LCOV - code coverage report
Current view: top level - isomedia - box_code_base.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 4996 6031 82.8 %
Date: 2021-04-29 23:48:07 Functions: 804 819 98.2 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / ISO Media File Format 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/isomedia_dev.h>
      27             : 
      28             : 
      29             : 
      30             : #ifndef GPAC_DISABLE_ISOM
      31             : 
      32           4 : void co64_box_del(GF_Box *s)
      33             : {
      34             :         GF_ChunkLargeOffsetBox *ptr;
      35             :         ptr = (GF_ChunkLargeOffsetBox *) s;
      36           4 :         if (ptr == NULL) return;
      37           4 :         if (ptr->offsets) gf_free(ptr->offsets);
      38           4 :         gf_free(ptr);
      39             : }
      40             : 
      41           1 : GF_Err co64_box_read(GF_Box *s,GF_BitStream *bs)
      42             : {
      43             :         u32 entries;
      44             :         GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
      45           1 :         ptr->nb_entries = gf_bs_read_u32(bs);
      46             : 
      47           1 :         ISOM_DECREASE_SIZE(ptr, 4)
      48             : 
      49           1 :         if (ptr->nb_entries > ptr->size / 8) {
      50           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in co64\n", ptr->nb_entries));
      51             :                 return GF_ISOM_INVALID_FILE;
      52             :         }
      53             : 
      54           1 :         ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) );
      55           1 :         if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
      56           1 :         ptr->alloc_size = ptr->nb_entries;
      57           1 :         for (entries = 0; entries < ptr->nb_entries; entries++) {
      58           0 :                 ptr->offsets[entries] = gf_bs_read_u64(bs);
      59             :         }
      60             :         return GF_OK;
      61             : }
      62             : 
      63           4 : GF_Box *co64_box_new()
      64             : {
      65           8 :         ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);
      66           4 :         return (GF_Box *)tmp;
      67             : }
      68             : 
      69             : 
      70             : #ifndef GPAC_DISABLE_ISOM_WRITE
      71             : 
      72           2 : GF_Err co64_box_write(GF_Box *s, GF_BitStream *bs)
      73             : {
      74             :         GF_Err e;
      75             :         u32 i;
      76             :         GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
      77             : 
      78           2 :         e = gf_isom_full_box_write(s, bs);
      79           2 :         if (e) return e;
      80           2 :         gf_bs_write_u32(bs, ptr->nb_entries);
      81          17 :         for (i = 0; i < ptr->nb_entries; i++ ) {
      82          15 :                 gf_bs_write_u64(bs, ptr->offsets[i]);
      83             :         }
      84             :         return GF_OK;
      85             : }
      86             : 
      87           4 : GF_Err co64_box_size(GF_Box *s)
      88             : {
      89             :         GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
      90             : 
      91           4 :         ptr->size += 4 + (8 * ptr->nb_entries);
      92           4 :         return GF_OK;
      93             : }
      94             : 
      95             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
      96             : 
      97           7 : void cprt_box_del(GF_Box *s)
      98             : {
      99             :         GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
     100           7 :         if (ptr == NULL) return;
     101           7 :         if (ptr->notice)
     102           2 :                 gf_free(ptr->notice);
     103           7 :         gf_free(ptr);
     104             : }
     105             : 
     106             : 
     107           9 : GF_Box *chpl_box_new()
     108             : {
     109          18 :         ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
     110           9 :         tmp->list = gf_list_new();
     111           9 :         tmp->version = 1;
     112           9 :         return (GF_Box *)tmp;
     113             : }
     114             : 
     115           9 : void chpl_box_del(GF_Box *s)
     116             : {
     117             :         GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
     118           9 :         if (ptr == NULL) return;
     119          37 :         while (gf_list_count(ptr->list)) {
     120          28 :                 GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0);
     121          28 :                 if (ce->name) gf_free(ce->name);
     122          28 :                 gf_free(ce);
     123          28 :                 gf_list_rem(ptr->list, 0);
     124             :         }
     125           9 :         gf_list_del(ptr->list);
     126           9 :         gf_free(ptr);
     127             : }
     128             : 
     129             : /*this is using chpl format according to some NeroRecode samples*/
     130           5 : GF_Err chpl_box_read(GF_Box *s,GF_BitStream *bs)
     131             : {
     132             :         GF_ChapterEntry *ce;
     133             :         u32 nb_chaps, len, i, count;
     134             :         GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
     135             : 
     136           5 :         ISOM_DECREASE_SIZE(ptr, 5)
     137             :         /*reserved or ???*/
     138           5 :         gf_bs_read_u32(bs);
     139           5 :         nb_chaps = gf_bs_read_u8(bs);
     140             : 
     141             :         count = 0;
     142          29 :         while (nb_chaps) {
     143          19 :                 GF_SAFEALLOC(ce, GF_ChapterEntry);
     144          19 :                 if (!ce) return GF_OUT_OF_MEM;
     145          19 :                 ISOM_DECREASE_SIZE(ptr, 9)
     146          19 :                 ce->start_time = gf_bs_read_u64(bs);
     147          19 :                 len = gf_bs_read_u8(bs);
     148          19 :                 if (ptr->size<len) return GF_ISOM_INVALID_FILE;
     149          19 :                 if (len) {
     150          19 :                         ce->name = (char *)gf_malloc(sizeof(char)*(len+1));
     151          19 :                         if (!ce->name) return GF_OUT_OF_MEM;
     152          19 :                         ISOM_DECREASE_SIZE(ptr, len)
     153          19 :                         gf_bs_read_data(bs, ce->name, len);
     154          19 :                         ce->name[len] = 0;
     155             :                 } else {
     156           0 :                         ce->name = gf_strdup("");
     157             :                 }
     158             : 
     159          36 :                 for (i=0; i<count; i++) {
     160          36 :                         GF_ChapterEntry *ace = (GF_ChapterEntry *) gf_list_get(ptr->list, i);
     161          36 :                         if (ace->start_time >= ce->start_time) {
     162           0 :                                 gf_list_insert(ptr->list, ce, i);
     163             :                                 ce = NULL;
     164             :                                 break;
     165             :                         }
     166             :                 }
     167          19 :                 if (ce) gf_list_add(ptr->list, ce);
     168          19 :                 count++;
     169          19 :                 nb_chaps--;
     170             :         }
     171             :         return GF_OK;
     172             : }
     173             : 
     174             : #ifndef GPAC_DISABLE_ISOM_WRITE
     175             : 
     176           3 : GF_Err chpl_box_write(GF_Box *s, GF_BitStream *bs)
     177             : {
     178             :         GF_Err e;
     179             :         u32 count, i;
     180             :         GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
     181           3 :         e = gf_isom_full_box_write(s, bs);
     182           3 :         if (e) return e;
     183             : 
     184           3 :         count = gf_list_count(ptr->list);
     185           3 :         gf_bs_write_u32(bs, 0);
     186           3 :         gf_bs_write_u8(bs, count);
     187          12 :         for (i=0; i<count; i++) {
     188             :                 u32 len;
     189           9 :                 GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
     190           9 :                 gf_bs_write_u64(bs, ce->start_time);
     191           9 :                 if (ce->name) {
     192           9 :                         len = (u32) strlen(ce->name);
     193           9 :                         if (len>255) len = 255;
     194           9 :                         gf_bs_write_u8(bs, len);
     195           9 :                         gf_bs_write_data(bs, ce->name, len);
     196             :                 } else {
     197           0 :                         gf_bs_write_u8(bs, 0);
     198             :                 }
     199             :         }
     200             :         return GF_OK;
     201             : }
     202             : 
     203           7 : GF_Err chpl_box_size(GF_Box *s)
     204             : {
     205             :         u32 count, i;
     206             :         GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
     207             : 
     208           7 :         ptr->size += 5;
     209             : 
     210           7 :         count = gf_list_count(ptr->list);
     211          34 :         for (i=0; i<count; i++) {
     212          27 :                 GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
     213          27 :                 ptr->size += 9; /*64bit time stamp + 8bit str len*/
     214          27 :                 if (ce->name) ptr->size += strlen(ce->name);
     215             :         }
     216           7 :         return GF_OK;
     217             : }
     218             : 
     219             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     220             : 
     221             : 
     222           3 : GF_Err cprt_box_read(GF_Box *s,GF_BitStream *bs)
     223             : {
     224             :         GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
     225             : 
     226           3 :         ISOM_DECREASE_SIZE(ptr, 2);
     227           3 :         gf_bs_read_int(bs, 1);
     228             :         //the spec is unclear here, just says "the value 0 is interpreted as undetermined"
     229           3 :         ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5);
     230           3 :         ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5);
     231           3 :         ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5);
     232             : 
     233             :         //but before or after compaction ?? We assume before
     234           3 :         if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) {
     235           3 :                 ptr->packedLanguageCode[0] += 0x60;
     236           3 :                 ptr->packedLanguageCode[1] += 0x60;
     237           3 :                 ptr->packedLanguageCode[2] += 0x60;
     238             :         } else {
     239           0 :                 ptr->packedLanguageCode[0] = 'u';
     240           0 :                 ptr->packedLanguageCode[1] = 'n';
     241           0 :                 ptr->packedLanguageCode[2] = 'd';
     242             :         }
     243           3 :         if (ptr->size) {
     244           1 :                 u32 bytesToRead = (u32) ptr->size;
     245           1 :                 ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char));
     246           1 :                 if (ptr->notice == NULL) return GF_OUT_OF_MEM;
     247           1 :                 gf_bs_read_data(bs, ptr->notice, bytesToRead);
     248             :         }
     249             :         return GF_OK;
     250             : }
     251             : 
     252           7 : GF_Box *cprt_box_new()
     253             : {
     254          14 :         ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
     255           7 :         tmp->packedLanguageCode[0] = 'u';
     256           7 :         tmp->packedLanguageCode[1] = 'n';
     257           7 :         tmp->packedLanguageCode[2] = 'd';
     258             : 
     259           7 :         return (GF_Box *)tmp;
     260             : }
     261             : 
     262             : #ifndef GPAC_DISABLE_ISOM_WRITE
     263             : 
     264           3 : GF_Err cprt_box_write(GF_Box *s, GF_BitStream *bs)
     265             : {
     266             :         GF_Err e;
     267             :         GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
     268             : 
     269           3 :         e = gf_isom_full_box_write(s, bs);
     270           3 :         if (e) return e;
     271           3 :         gf_bs_write_int(bs, 0, 1);
     272           3 :         if (ptr->packedLanguageCode[0]) {
     273           3 :                 gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5);
     274           3 :                 gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5);
     275           3 :                 gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5);
     276             :         } else {
     277           0 :                 gf_bs_write_int(bs, 0, 15);
     278             :         }
     279           3 :         if (ptr->notice) {
     280           1 :                 gf_bs_write_data(bs, ptr->notice, (u32) (strlen(ptr->notice) + 1) );
     281             :         }
     282             :         return GF_OK;
     283             : }
     284             : 
     285           5 : GF_Err cprt_box_size(GF_Box *s)
     286             : {
     287             :         GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
     288             : 
     289           5 :         ptr->size += 2;
     290           5 :         if (ptr->notice)
     291           3 :                 ptr->size += strlen(ptr->notice) + 1;
     292           5 :         return GF_OK;
     293             : }
     294             : 
     295             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     296             : 
     297         145 : void kind_box_del(GF_Box *s)
     298             : {
     299             :         GF_KindBox *ptr = (GF_KindBox *) s;
     300         145 :         if (ptr == NULL) return;
     301         145 :         if (ptr->schemeURI) gf_free(ptr->schemeURI);
     302         145 :         if (ptr->value) gf_free(ptr->value);
     303         145 :         gf_free(ptr);
     304             : }
     305             : 
     306          87 : GF_Err kind_box_read(GF_Box *s,GF_BitStream *bs)
     307             : {
     308             :         GF_KindBox *ptr = (GF_KindBox *)s;
     309             : 
     310          87 :         if (ptr->size) {
     311          87 :                 u32 bytesToRead = (u32) ptr->size;
     312             :                 char *data;
     313             :                 u32 schemeURIlen;
     314          87 :                 data = (char*)gf_malloc(bytesToRead * sizeof(char));
     315          87 :                 if (!data) return GF_OUT_OF_MEM;
     316          87 :                 gf_bs_read_data(bs, data, bytesToRead);
     317             :                 /*safety check in case the string is not null-terminated*/
     318          87 :                 if (data[bytesToRead-1]) {
     319           0 :                         data = (char*)gf_realloc(data, sizeof(char)*(bytesToRead + 1));
     320           0 :                         if (!data) return GF_OUT_OF_MEM;
     321           0 :                         data[bytesToRead] = 0;
     322             :                         bytesToRead++;
     323             :                 }
     324          87 :                 ptr->schemeURI = gf_strdup(data);
     325          87 :                 if (!ptr->schemeURI) return GF_OUT_OF_MEM;
     326          87 :                 schemeURIlen = (u32) strlen(data);
     327          87 :                 if (bytesToRead > schemeURIlen+1) {
     328             :                         /* read the value */
     329          37 :                         char *data_value = data + schemeURIlen +1;
     330          37 :                         ptr->value = gf_strdup(data_value);
     331          37 :                         if (!ptr->value) return GF_OUT_OF_MEM;
     332             :                 }
     333          87 :                 gf_free(data);
     334             :         }
     335             :         return GF_OK;
     336             : }
     337             : 
     338         145 : GF_Box *kind_box_new()
     339             : {
     340         290 :         ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND);
     341         145 :         return (GF_Box *)tmp;
     342             : }
     343             : 
     344             : #ifndef GPAC_DISABLE_ISOM_WRITE
     345             : 
     346         105 : GF_Err kind_box_write(GF_Box *s, GF_BitStream *bs)
     347             : {
     348             :         GF_Err e;
     349             :         GF_KindBox *ptr = (GF_KindBox *) s;
     350             : 
     351         105 :         e = gf_isom_full_box_write(s, bs);
     352         105 :         if (e) return e;
     353         105 :     if (ptr->schemeURI)
     354         104 :         gf_bs_write_data(bs, ptr->schemeURI, (u32) (strlen(ptr->schemeURI) + 1 ));
     355             :     else
     356           1 :         gf_bs_write_u8(bs, 0);
     357             : 
     358         105 :     if (ptr->value) {
     359          51 :                 gf_bs_write_data(bs, ptr->value, (u32) (strlen(ptr->value) + 1) );
     360             :         }
     361             :         return GF_OK;
     362             : }
     363             : 
     364         273 : GF_Err kind_box_size(GF_Box *s)
     365             : {
     366             :         GF_KindBox *ptr = (GF_KindBox *)s;
     367             : 
     368         273 :     ptr->size += (ptr->schemeURI ? strlen(ptr->schemeURI) : 0) + 1;
     369         273 :         if (ptr->value) {
     370         137 :                 ptr->size += strlen(ptr->value) + 1;
     371             :         }
     372         273 :         return GF_OK;
     373             : }
     374             : 
     375             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     376             : 
     377       18028 : void ctts_box_del(GF_Box *s)
     378             : {
     379             :         GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
     380       18028 :         if (ptr->entries) gf_free(ptr->entries);
     381       18028 :         gf_free(ptr);
     382       18028 : }
     383             : 
     384             : 
     385             : 
     386         477 : GF_Err ctts_box_read(GF_Box *s, GF_BitStream *bs)
     387             : {
     388             :         u32 i;
     389             :         u32 sampleCount;
     390             :         GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
     391             : 
     392         477 :         ISOM_DECREASE_SIZE(ptr, 4);
     393         477 :         ptr->nb_entries = gf_bs_read_u32(bs);
     394             : 
     395         477 :         if (ptr->nb_entries > ptr->size / 8) {
     396           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", ptr->nb_entries));
     397             :                 return GF_ISOM_INVALID_FILE;
     398             :         }
     399             : 
     400         477 :         ptr->alloc_size = ptr->nb_entries;
     401         477 :         ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
     402         477 :         if (!ptr->entries) return GF_OUT_OF_MEM;
     403             :         sampleCount = 0;
     404      157101 :         for (i=0; i<ptr->nb_entries; i++) {
     405      157101 :                 ISOM_DECREASE_SIZE(ptr, 8);
     406      157101 :                 ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
     407      157101 :                 if (ptr->version)
     408        5274 :                         ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
     409             :                 else
     410      151827 :                         ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs);
     411      157101 :                 sampleCount += ptr->entries[i].sampleCount;
     412             : 
     413      157101 :                 if (ptr->max_ts_delta < ABS(ptr->entries[i].decodingOffset))
     414        1256 :                         ptr->max_ts_delta = ABS(ptr->entries[i].decodingOffset);
     415             :         }
     416             : #ifndef GPAC_DISABLE_ISOM_WRITE
     417         477 :         ptr->w_LastSampleNumber = sampleCount;
     418             : #endif
     419         477 :         return GF_OK;
     420             : }
     421             : 
     422       18028 : GF_Box *ctts_box_new()
     423             : {
     424       36056 :         ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
     425       18028 :         return (GF_Box *) tmp;
     426             : }
     427             : 
     428             : 
     429             : 
     430             : #ifndef GPAC_DISABLE_ISOM_WRITE
     431             : 
     432         407 : GF_Err ctts_box_write(GF_Box *s, GF_BitStream *bs)
     433             : {
     434             :         GF_Err e;
     435             :         u32 i;
     436             :         GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
     437             : 
     438         407 :         e = gf_isom_full_box_write(s, bs);
     439         407 :         if (e) return e;
     440         407 :         gf_bs_write_u32(bs, ptr->nb_entries);
     441      141097 :         for (i=0; i<ptr->nb_entries; i++ ) {
     442      140690 :                 gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
     443      140690 :                 if (ptr->version) {
     444        1560 :                         gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
     445             :                 } else {
     446      139130 :                         gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset);
     447             :                 }
     448             :         }
     449             :         return GF_OK;
     450             : }
     451             : 
     452        1157 : GF_Err ctts_box_size(GF_Box *s)
     453             : {
     454             :         GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *) s;
     455             : 
     456        1157 :         ptr->size += 4 + (8 * ptr->nb_entries);
     457        1157 :         return GF_OK;
     458             : }
     459             : 
     460             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     461             : 
     462          18 : void cslg_box_del(GF_Box *s)
     463             : {
     464             :         GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
     465          18 :         if (ptr == NULL) return;
     466          18 :         gf_free(ptr);
     467          18 :         return;
     468             : }
     469             : 
     470          13 : GF_Err cslg_box_read(GF_Box *s, GF_BitStream *bs)
     471             : {
     472             :         GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
     473             : 
     474          13 :         ISOM_DECREASE_SIZE(ptr, 20);
     475          13 :         ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
     476          13 :         ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
     477          13 :         ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
     478          13 :         ptr->compositionStartTime = gf_bs_read_int(bs, 32);
     479          13 :         ptr->compositionEndTime = gf_bs_read_int(bs, 32);
     480          13 :         return GF_OK;
     481             : }
     482             : 
     483          18 : GF_Box *cslg_box_new()
     484             : {
     485          36 :         ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
     486          18 :         return (GF_Box *) tmp;
     487             : }
     488             : 
     489             : #ifndef GPAC_DISABLE_ISOM_WRITE
     490             : 
     491           9 : GF_Err cslg_box_write(GF_Box *s, GF_BitStream *bs)
     492             : {
     493             :         GF_Err e;
     494             :         GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
     495             : 
     496           9 :         e = gf_isom_full_box_write(s, bs);
     497           9 :         if (e) return e;
     498           9 :         gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
     499           9 :         gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
     500           9 :         gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
     501           9 :         gf_bs_write_int(bs, ptr->compositionStartTime, 32);
     502           9 :         gf_bs_write_int(bs, ptr->compositionEndTime, 32);
     503           9 :         return GF_OK;
     504             : }
     505             : 
     506          13 : GF_Err cslg_box_size(GF_Box *s)
     507             : {
     508             :         GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
     509             : 
     510          13 :         ptr->size += 20;
     511          13 :         return GF_OK;
     512             : }
     513             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     514             : 
     515           4 : void ccst_box_del(GF_Box *s)
     516             : {
     517             :         GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
     518           4 :         if (ptr) gf_free(ptr);
     519           4 :         return;
     520             : }
     521             : 
     522           1 : GF_Err ccst_box_read(GF_Box *s, GF_BitStream *bs)
     523             : {
     524             :         GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
     525             : 
     526           1 :         ISOM_DECREASE_SIZE(ptr, 4);
     527           1 :         ptr->all_ref_pics_intra = gf_bs_read_int(bs, 1);
     528           1 :         ptr->intra_pred_used = gf_bs_read_int(bs, 1);
     529           1 :         ptr->max_ref_per_pic = gf_bs_read_int(bs, 4);
     530           1 :         ptr->reserved = gf_bs_read_int(bs, 26);
     531           1 :         return GF_OK;
     532             : }
     533             : 
     534           4 : GF_Box *ccst_box_new()
     535             : {
     536           8 :         ISOM_DECL_BOX_ALLOC(GF_CodingConstraintsBox, GF_ISOM_BOX_TYPE_CCST);
     537           4 :         return (GF_Box *) tmp;
     538             : }
     539             : 
     540             : #ifndef GPAC_DISABLE_ISOM_WRITE
     541             : 
     542           2 : GF_Err ccst_box_write(GF_Box *s, GF_BitStream *bs)
     543             : {
     544             :         GF_Err e;
     545             :         GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
     546             : 
     547           2 :         e = gf_isom_full_box_write(s, bs);
     548           2 :         if (e) return e;
     549           2 :         gf_bs_write_int(bs, ptr->all_ref_pics_intra, 1);
     550           2 :         gf_bs_write_int(bs, ptr->intra_pred_used, 1);
     551           2 :         gf_bs_write_int(bs, ptr->max_ref_per_pic, 4);
     552           2 :         gf_bs_write_int(bs, 0, 26);
     553           2 :         return GF_OK;
     554             : }
     555             : 
     556           4 : GF_Err ccst_box_size(GF_Box *s)
     557             : {
     558             :         GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
     559           4 :         ptr->size += 4;
     560           4 :         return GF_OK;
     561             : }
     562             : 
     563             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     564             : 
     565        4209 : void url_box_del(GF_Box *s)
     566             : {
     567             :         GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
     568        4209 :         if (ptr == NULL) return;
     569        4209 :         if (ptr->location) gf_free(ptr->location);
     570        4209 :         gf_free(ptr);
     571        4209 :         return;
     572             : }
     573             : 
     574             : 
     575        2474 : GF_Err url_box_read(GF_Box *s, GF_BitStream *bs)
     576             : {
     577             :         GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
     578             : 
     579        2474 :         if (ptr->size) {
     580           0 :                 ptr->location = (char*)gf_malloc((u32) ptr->size);
     581           0 :                 if (! ptr->location) return GF_OUT_OF_MEM;
     582           0 :                 gf_bs_read_data(bs, ptr->location, (u32)ptr->size);
     583           0 :                 if (ptr->location[ptr->size-1]) {
     584           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] url box location is not 0-terminated\n" ));
     585             :                         return GF_ISOM_INVALID_FILE;
     586             :                 }
     587             :         }
     588             :         return GF_OK;
     589             : }
     590             : 
     591        4209 : GF_Box *url_box_new()
     592             : {
     593        8418 :         ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
     594        4209 :         return (GF_Box *)tmp;
     595             : }
     596             : 
     597             : #ifndef GPAC_DISABLE_ISOM_WRITE
     598             : 
     599        2038 : GF_Err url_box_write(GF_Box *s, GF_BitStream *bs)
     600             : {
     601             :         GF_Err e;
     602             :         GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
     603             : 
     604        2038 :         e = gf_isom_full_box_write(s, bs);
     605        2038 :         if (e) return e;
     606             :         //the flag set indicates we have a string (WE HAVE TO for URLs)
     607        2038 :         if ( !(ptr->flags & 1)) {
     608           4 :                 if (ptr->location) {
     609           3 :                         gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
     610             :                 }
     611             :         }
     612             :         return GF_OK;
     613             : }
     614             : 
     615        4987 : GF_Err url_box_size(GF_Box *s)
     616             : {
     617             :         GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
     618             : 
     619        4987 :         if ( !(ptr->flags & 1)) {
     620          10 :                 if (ptr->location) ptr->size += 1 + strlen(ptr->location);
     621             :         }
     622        4987 :         return GF_OK;
     623             : }
     624             : 
     625             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     626             : 
     627           3 : void urn_box_del(GF_Box *s)
     628             : {
     629             :         GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
     630           3 :         if (ptr == NULL) return;
     631           3 :         if (ptr->location) gf_free(ptr->location);
     632           3 :         if (ptr->nameURN) gf_free(ptr->nameURN);
     633           3 :         gf_free(ptr);
     634             : }
     635             : 
     636             : 
     637           1 : GF_Err urn_box_read(GF_Box *s, GF_BitStream *bs)
     638             : {
     639             :         u32 i, to_read;
     640             :         char *tmpName;
     641             :         GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
     642           1 :         if (! ptr->size ) return GF_OK;
     643             : 
     644             :         //here we have to handle that in a clever way
     645           0 :         to_read = (u32) ptr->size;
     646           0 :         tmpName = (char*)gf_malloc(sizeof(char) * to_read);
     647           0 :         if (!tmpName) return GF_OUT_OF_MEM;
     648             :         //get the data
     649           0 :         gf_bs_read_data(bs, tmpName, to_read);
     650             : 
     651             :         //then get the break
     652             :         i = 0;
     653           0 :         while ( (i < to_read) && (tmpName[i] != 0) ) {
     654           0 :                 i++;
     655             :         }
     656             :         //check the data is consistent
     657           0 :         if (i == to_read) {
     658           0 :                 gf_free(tmpName);
     659           0 :                 return GF_ISOM_INVALID_FILE;
     660             :         }
     661             :         //no NULL char, URL is not specified
     662           0 :         if (i == to_read - 1) {
     663           0 :                 ptr->nameURN = tmpName;
     664           0 :                 ptr->location = NULL;
     665           0 :                 return GF_OK;
     666             :         }
     667             :         //OK, this has both URN and URL
     668           0 :         ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1));
     669           0 :         if (!ptr->nameURN) {
     670           0 :                 gf_free(tmpName);
     671           0 :                 return GF_OUT_OF_MEM;
     672             :         }
     673             :         memcpy(ptr->nameURN, tmpName, i + 1);
     674             : 
     675           0 :         if (tmpName[to_read - 1] != 0) {
     676           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] urn box contains invalid location field\n" ));
     677             :         }
     678             :         else {
     679           0 :                 ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1));
     680           0 :                 if (!ptr->location) {
     681           0 :                         gf_free(tmpName);
     682           0 :                         gf_free(ptr->nameURN);
     683           0 :                         ptr->nameURN = NULL;
     684           0 :                         return GF_OUT_OF_MEM;
     685             :                 }
     686           0 :                 memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1));
     687             :         }
     688             : 
     689           0 :         gf_free(tmpName);
     690           0 :         return GF_OK;
     691             : }
     692             : 
     693           3 : GF_Box *urn_box_new()
     694             : {
     695           6 :         ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
     696           3 :         return (GF_Box *)tmp;
     697             : }
     698             : 
     699             : #ifndef GPAC_DISABLE_ISOM_WRITE
     700             : 
     701             : 
     702           1 : GF_Err urn_box_write(GF_Box *s, GF_BitStream *bs)
     703             : {
     704             :         GF_Err e;
     705             :         GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
     706             : 
     707           1 :         e = gf_isom_full_box_write(s, bs);
     708           1 :         if (e) return e;
     709             :         //the flag set indicates we have a string (WE HAVE TO for URLs)
     710           1 :         if ( !(ptr->flags & 1)) {
     711             :                 //to check, the spec says: First name, then location
     712           1 :                 if (ptr->nameURN) {
     713           0 :                         gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1);
     714             :                 }
     715           1 :                 if (ptr->location) {
     716           0 :                         gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
     717             :                 }
     718             :         }
     719             :         return GF_OK;
     720             : }
     721             : 
     722           1 : GF_Err urn_box_size(GF_Box *s)
     723             : {
     724             :         GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
     725             : 
     726           1 :         if ( !(ptr->flags & 1)) {
     727           1 :                 if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN);
     728           1 :                 if (ptr->location) ptr->size += 1 + strlen(ptr->location);
     729             :         }
     730           1 :         return GF_OK;
     731             : }
     732             : 
     733             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     734             : 
     735        1388 : void unkn_box_del(GF_Box *s)
     736             : {
     737             :         GF_UnknownBox *ptr = (GF_UnknownBox *) s;
     738        1388 :         if (!s) return;
     739        1388 :         if (ptr->data) gf_free(ptr->data);
     740        1388 :         gf_free(ptr);
     741             : }
     742             : 
     743             : 
     744        1362 : GF_Err unkn_box_read(GF_Box *s, GF_BitStream *bs)
     745             : {
     746             :         GF_Err e;
     747             :         u32 bytesToRead, sub_size, sub_a;
     748             :         GF_BitStream *sub_bs;
     749             :         GF_UnknownBox *ptr = (GF_UnknownBox *)s;
     750        1362 :         if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
     751        1362 :         bytesToRead = (u32) (ptr->size);
     752             : 
     753        1362 :         if (!bytesToRead) return GF_OK;
     754        1233 :         if (bytesToRead>1000000) {
     755           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unknown box %s (0x%08X) with payload larger than 1 MBytes, ignoring\n", gf_4cc_to_str(ptr->type), ptr->type ));
     756           0 :                 gf_bs_skip_bytes(bs, ptr->dataSize);
     757           0 :                 return GF_OK;
     758             :         }
     759             : 
     760        1233 :         ptr->data = (char*)gf_malloc(bytesToRead);
     761        1233 :         if (ptr->data == NULL ) return GF_OUT_OF_MEM;
     762        1233 :         ptr->dataSize = bytesToRead;
     763        1233 :         gf_bs_read_data(bs, ptr->data, ptr->dataSize);
     764             : 
     765             :         //try to parse container boxes, check if next 8 bytes match a subbox
     766        1233 :         sub_bs = gf_bs_new(ptr->data, ptr->dataSize, GF_BITSTREAM_READ);
     767        1233 :         sub_size = gf_bs_read_u32(sub_bs);
     768        1233 :         sub_a = gf_bs_read_u8(sub_bs);
     769        1233 :         e = (sub_size && (sub_size <= ptr->dataSize)) ? GF_OK : GF_NOT_SUPPORTED;
     770        1233 :         if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
     771        1233 :         sub_a = gf_bs_read_u8(sub_bs);
     772        1233 :         if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
     773        1233 :         sub_a = gf_bs_read_u8(sub_bs);
     774        1233 :         if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
     775        1233 :         sub_a = gf_bs_read_u8(sub_bs);
     776        1233 :         if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
     777             : 
     778         992 :         if (e == GF_OK) {
     779         968 :                 gf_bs_seek(sub_bs, 0);
     780         968 :                 gf_bs_set_cookie(sub_bs, GF_ISOM_BS_COOKIE_NO_LOGS);
     781         968 :                 e = gf_isom_box_array_read(s, sub_bs);
     782             :         }
     783        1233 :         gf_bs_del(sub_bs);
     784        1233 :         if (e==GF_OK) {
     785         968 :                 gf_free(ptr->data);
     786         968 :                 ptr->data = NULL;
     787         968 :                 ptr->dataSize = 0;
     788         265 :         } else if (s->child_boxes) {
     789           0 :                 gf_isom_box_array_del(s->child_boxes);
     790           0 :                 s->child_boxes=NULL;
     791             :         }
     792             : 
     793             :         return GF_OK;
     794             : }
     795             : 
     796        1388 : GF_Box *unkn_box_new()
     797             : {
     798        2776 :         ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN);
     799        1388 :         return (GF_Box *) tmp;
     800             : }
     801             : 
     802             : #ifndef GPAC_DISABLE_ISOM_WRITE
     803             : 
     804         956 : GF_Err unkn_box_write(GF_Box *s, GF_BitStream *bs)
     805             : {
     806             :         GF_Err e;
     807             :         u32 type;
     808             :         GF_UnknownBox *ptr = (GF_UnknownBox *)s;
     809         956 :         if (!s) return GF_BAD_PARAM;
     810         956 :         type = s->type;
     811         956 :         ptr->type = ptr->original_4cc;
     812         956 :         e = gf_isom_box_write_header(s, bs);
     813         956 :         ptr->type = type;
     814         956 :         if (e) return e;
     815             : 
     816         956 :         if (ptr->dataSize && ptr->data) {
     817         184 :                 gf_bs_write_data(bs, ptr->data, ptr->dataSize);
     818             :         }
     819             :         return GF_OK;
     820             : }
     821             : 
     822        1688 : GF_Err unkn_box_size(GF_Box *s)
     823             : {
     824             :         GF_UnknownBox *ptr = (GF_UnknownBox *)s;
     825             : 
     826        1688 :         if (ptr->dataSize && ptr->data) {
     827         334 :                 ptr->size += ptr->dataSize;
     828             :         }
     829        1688 :         return GF_OK;
     830             : }
     831             : 
     832             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     833             : 
     834             : 
     835         176 : void def_parent_box_del(GF_Box *s)
     836             : {
     837         176 :         if (s) gf_free(s);
     838         176 : }
     839             : 
     840             : 
     841         150 : GF_Err def_parent_box_read(GF_Box *s, GF_BitStream *bs)
     842             : {
     843         150 :         return gf_isom_box_array_read(s, bs);
     844             : }
     845             : 
     846         176 : GF_Box *def_parent_box_new()
     847             : {
     848         352 :         ISOM_DECL_BOX_ALLOC(GF_Box, 0);
     849         176 :         return (GF_Box *) tmp;
     850             : }
     851             : 
     852             : #ifndef GPAC_DISABLE_ISOM_WRITEHintSa
     853             : 
     854         116 : GF_Err def_parent_box_write(GF_Box *s, GF_BitStream *bs)
     855             : {
     856         116 :         return gf_isom_box_write_header(s, bs);
     857             : }
     858             : 
     859         206 : GF_Err def_parent_box_size(GF_Box *s)
     860             : {
     861         206 :         return GF_OK;
     862             : }
     863             : 
     864             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     865             : 
     866             : 
     867           3 : void def_parent_full_box_del(GF_Box *s)
     868             : {
     869           3 :         if (s) gf_free(s);
     870           3 : }
     871             : 
     872             : 
     873           1 : GF_Err def_parent_full_box_read(GF_Box *s, GF_BitStream *bs)
     874             : {
     875           1 :         return gf_isom_box_array_read(s, bs);
     876             : }
     877             : 
     878           3 : GF_Box *def_parent_full_box_new()
     879             : {
     880           6 :         ISOM_DECL_BOX_ALLOC(GF_Box, 0);
     881           3 :         return (GF_Box *) tmp;
     882             : }
     883             : 
     884             : #ifndef GPAC_DISABLE_ISOM_WRITEHintSa
     885             : 
     886           1 : GF_Err def_parent_full_box_write(GF_Box *s, GF_BitStream *bs)
     887             : {
     888           1 :         return gf_isom_full_box_write(s, bs);
     889             : }
     890             : 
     891           1 : GF_Err def_parent_full_box_size(GF_Box *s)
     892             : {
     893           1 :         return GF_OK;
     894             : }
     895             : 
     896             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     897             : 
     898          21 : void uuid_box_del(GF_Box *s)
     899             : {
     900             :         GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s;
     901          21 :         if (!s) return;
     902          21 :         if (ptr->data) gf_free(ptr->data);
     903          21 :         gf_free(ptr);
     904             : }
     905             : 
     906             : 
     907          13 : GF_Err uuid_box_read(GF_Box *s, GF_BitStream *bs)
     908             : {
     909             :         u32 bytesToRead;
     910             :         GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
     911          13 :         if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
     912          13 :         bytesToRead = (u32) (ptr->size);
     913             : 
     914          13 :         if (bytesToRead) {
     915          11 :                 ptr->data = (char*)gf_malloc(bytesToRead);
     916          11 :                 if (ptr->data == NULL ) return GF_OUT_OF_MEM;
     917          11 :                 ptr->dataSize = bytesToRead;
     918          11 :                 gf_bs_read_data(bs, ptr->data, ptr->dataSize);
     919             :         }
     920             :         return GF_OK;
     921             : }
     922             : 
     923          21 : GF_Box *uuid_box_new()
     924             : {
     925          42 :         ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
     926          21 :         return (GF_Box *) tmp;
     927             : }
     928             : 
     929             : #ifndef GPAC_DISABLE_ISOM_WRITE
     930             : 
     931          10 : GF_Err uuid_box_write(GF_Box *s, GF_BitStream *bs)
     932             : {
     933             :         GF_Err e;
     934             :         GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s;
     935          10 :         if (!s) return GF_BAD_PARAM;
     936             : 
     937          10 :         e = gf_isom_box_write_header(s, bs);
     938          10 :         if (e) return e;
     939          10 :         if (ptr->data) {
     940           8 :                 gf_bs_write_data(bs, ptr->data, ptr->dataSize);
     941             :         }
     942             :         return GF_OK;
     943             : }
     944             : 
     945          22 : GF_Err uuid_box_size(GF_Box *s)
     946             : {
     947             :         GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s;
     948          22 :         ptr->size += ptr->dataSize;
     949          22 :         return GF_OK;
     950             : }
     951             : 
     952             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     953             : 
     954             : 
     955        4120 : void dinf_box_del(GF_Box *s)
     956             : {
     957        4120 :         gf_free(s);
     958        4120 : }
     959             : 
     960             : 
     961        3495 : GF_Err dinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
     962             : {
     963             :         GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
     964        3495 :         switch(a->type) {
     965        3495 :         case GF_ISOM_BOX_TYPE_DREF:
     966        3495 :                 BOX_FIELD_ASSIGN(dref, GF_DataReferenceBox)
     967        3495 :                 return GF_OK;
     968             :         }
     969             :         return GF_OK;
     970             : }
     971             : 
     972        3100 : GF_Err dinf_box_read(GF_Box *s, GF_BitStream *bs)
     973             : {
     974             :         GF_DataInformationBox *dinf;
     975        3100 :         GF_Err e = gf_isom_box_array_read(s, bs);
     976        3100 :         if (e) {
     977             :                 return e;
     978             :         }
     979             :         dinf = (GF_DataInformationBox *)s;
     980        3100 :         if (!dinf->dref) {
     981         616 :                 if (! (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_NO_LOGS) ) {
     982           1 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing dref box in dinf\n"));
     983             :                 }
     984         616 :                 dinf->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&dinf->child_boxes, GF_ISOM_BOX_TYPE_DREF);
     985             :         }
     986             :         return GF_OK;
     987             : }
     988             : 
     989        4120 : GF_Box *dinf_box_new()
     990             : {
     991        8240 :         ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
     992        4120 :         return (GF_Box *)tmp;
     993             : }
     994             : 
     995             : #ifndef GPAC_DISABLE_ISOM_WRITE
     996             : 
     997        3171 : GF_Err dinf_box_write(GF_Box *s, GF_BitStream *bs)
     998             : {
     999        3171 :         return gf_isom_box_write_header(s, bs);
    1000             : }
    1001             : 
    1002        6120 : GF_Err dinf_box_size(GF_Box *s)
    1003             : {
    1004        6120 :         return GF_OK;
    1005             : }
    1006             : 
    1007             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1008             : 
    1009        4121 : void dref_box_del(GF_Box *s)
    1010             : {
    1011             :         GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s;
    1012        4121 :         if (ptr == NULL) return;
    1013        4121 :         gf_free(ptr);
    1014             : }
    1015             : 
    1016             : 
    1017        2485 : GF_Err dref_box_read(GF_Box *s, GF_BitStream *bs)
    1018             : {
    1019             :         GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
    1020        2485 :         ISOM_DECREASE_SIZE(ptr, 4);
    1021        2485 :         gf_bs_read_u32(bs);
    1022        2485 :         return gf_isom_box_array_read(s, bs);
    1023             : }
    1024             : 
    1025        4121 : GF_Box *dref_box_new()
    1026             : {
    1027        8242 :         ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
    1028        4121 :         return (GF_Box *)tmp;
    1029             : }
    1030             : 
    1031             : 
    1032             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1033             : 
    1034        2038 : GF_Err dref_box_write(GF_Box *s, GF_BitStream *bs)
    1035             : {
    1036             :         GF_Err e;
    1037             :         u32 count;
    1038             :         GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
    1039        2038 :         if (!s) return GF_BAD_PARAM;
    1040             : 
    1041        2038 :         e = gf_isom_full_box_write(s, bs);
    1042        2038 :         if (e) return e;
    1043        2038 :         count = ptr->child_boxes ? gf_list_count(ptr->child_boxes) : 0;
    1044        2038 :         gf_bs_write_u32(bs, count);
    1045        2038 :         return GF_OK;
    1046             : }
    1047             : 
    1048        4987 : GF_Err dref_box_size(GF_Box *s)
    1049             : {
    1050             :         GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
    1051        4987 :         if (!s) return GF_BAD_PARAM;
    1052             : 
    1053        4987 :         ptr->size += 4;
    1054        4987 :         return GF_OK;
    1055             : }
    1056             : 
    1057             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1058             : 
    1059        1237 : void edts_box_del(GF_Box *s)
    1060             : {
    1061        1237 :         gf_free(s);
    1062        1237 : }
    1063             : 
    1064             : 
    1065        1235 : GF_Err edts_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    1066             : {
    1067             :         GF_EditBox *ptr = (GF_EditBox *)s;
    1068        1235 :         if (a->type == GF_ISOM_BOX_TYPE_ELST) {
    1069        1235 :                 BOX_FIELD_ASSIGN(editList, GF_EditListBox)
    1070        1235 :                 return GF_OK;
    1071             :         } else {
    1072             :                 return GF_OK;
    1073             :         }
    1074             :         return GF_OK;
    1075             : }
    1076             : 
    1077             : 
    1078         762 : GF_Err edts_box_read(GF_Box *s, GF_BitStream *bs)
    1079             : {
    1080         762 :         return gf_isom_box_array_read(s, bs);
    1081             : }
    1082             : 
    1083        1237 : GF_Box *edts_box_new()
    1084             : {
    1085        2474 :         ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
    1086        1237 :         return (GF_Box *) tmp;
    1087             : }
    1088             : 
    1089             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1090             : 
    1091         783 : GF_Err edts_box_write(GF_Box *s, GF_BitStream *bs)
    1092             : {
    1093             :         GF_EditBox *ptr = (GF_EditBox *)s;
    1094             : 
    1095             :         //here we have a trick: if editList is empty, skip the box
    1096         783 :         if (ptr->editList && gf_list_count(ptr->editList->entryList)) {
    1097         783 :                 return gf_isom_box_write_header(s, bs);
    1098             :         } else {
    1099           0 :                 s->size = 0;
    1100             :         }
    1101           0 :         return GF_OK;
    1102             : }
    1103             : 
    1104        1580 : GF_Err edts_box_size(GF_Box *s)
    1105             : {
    1106             :         GF_EditBox *ptr = (GF_EditBox *)s;
    1107             : 
    1108             :         //here we have a trick: if editList is empty, skip the box
    1109        1580 :         if (!ptr->editList || ! gf_list_count(ptr->editList->entryList)) {
    1110           1 :                 ptr->size = 0;
    1111             :         }
    1112        1580 :         return GF_OK;
    1113             : }
    1114             : 
    1115             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1116             : 
    1117        1239 : void elst_box_del(GF_Box *s)
    1118             : {
    1119             :         GF_EditListBox *ptr;
    1120             :         u32 nb_entries;
    1121             :         u32 i;
    1122             : 
    1123             :         ptr = (GF_EditListBox *)s;
    1124        1239 :         if (ptr == NULL) return;
    1125        1239 :         nb_entries = gf_list_count(ptr->entryList);
    1126        2265 :         for (i = 0; i < nb_entries; i++) {
    1127        1026 :                 GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
    1128        1026 :                 if (p) gf_free(p);
    1129             :         }
    1130        1239 :         gf_list_del(ptr->entryList);
    1131        1239 :         gf_free(ptr);
    1132             : }
    1133             : 
    1134         763 : GF_Err elst_box_read(GF_Box *s, GF_BitStream *bs)
    1135             : {
    1136             :         u32 entries;
    1137             :         s32 tr;
    1138             :         u32 nb_entries;
    1139             :         GF_EditListBox *ptr = (GF_EditListBox *)s;
    1140             : 
    1141         763 :         ISOM_DECREASE_SIZE(ptr, 4);
    1142         763 :         nb_entries = gf_bs_read_u32(bs);
    1143             : 
    1144         763 :         if (ptr->version == 1) {
    1145           0 :                 if (nb_entries > ptr->size / 20) {
    1146           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
    1147             :                         return GF_ISOM_INVALID_FILE;
    1148             :                 }
    1149             :         } else {
    1150         763 :                 if (nb_entries > ptr->size / 12) {
    1151           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
    1152             :                         return GF_ISOM_INVALID_FILE;
    1153             :                 }
    1154             :         }
    1155             : 
    1156             : 
    1157         763 :         for (entries = 0; entries < nb_entries; entries++) {
    1158             :                 GF_EdtsEntry *p;
    1159         763 :                 GF_SAFEALLOC(p, GF_EdtsEntry);
    1160         763 :                 if (!p) return GF_OUT_OF_MEM;
    1161         763 :                 if (ptr->version == 1) {
    1162           0 :                         ISOM_DECREASE_SIZE(ptr, 16);
    1163           0 :                         p->segmentDuration = gf_bs_read_u64(bs);
    1164           0 :                         p->mediaTime = (s64) gf_bs_read_u64(bs);
    1165             :                 } else {
    1166         763 :                         ISOM_DECREASE_SIZE(ptr, 8);
    1167         763 :                         p->segmentDuration = gf_bs_read_u32(bs);
    1168         763 :                         tr = gf_bs_read_u32(bs);
    1169         763 :                         p->mediaTime = (s64) tr;
    1170             :                 }
    1171         763 :                 ISOM_DECREASE_SIZE(ptr, 4);
    1172         763 :                 p->mediaRate = gf_bs_read_u32(bs);
    1173         763 :                 gf_list_add(ptr->entryList, p);
    1174             :         }
    1175             :         return GF_OK;
    1176             : }
    1177             : 
    1178        1239 : GF_Box *elst_box_new()
    1179             : {
    1180        2478 :         ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
    1181        1239 :         tmp->entryList = gf_list_new();
    1182        1239 :         if (!tmp->entryList) {
    1183           0 :                 gf_free(tmp);
    1184           0 :                 return NULL;
    1185             :         }
    1186             :         return (GF_Box *)tmp;
    1187             : }
    1188             : 
    1189             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1190             : 
    1191         784 : GF_Err elst_box_write(GF_Box *s, GF_BitStream *bs)
    1192             : {
    1193             :         GF_Err e;
    1194             :         u32 i;
    1195             :         u32 nb_entries;
    1196             :         GF_EditListBox *ptr = (GF_EditListBox *)s;
    1197         784 :         if (!ptr) return GF_BAD_PARAM;
    1198             : 
    1199         784 :         nb_entries = gf_list_count(ptr->entryList);
    1200         784 :         e = gf_isom_full_box_write(s, bs);
    1201         784 :         if (e) return e;
    1202         784 :         gf_bs_write_u32(bs, nb_entries);
    1203        1621 :         for (i = 0; i < nb_entries; i++ ) {
    1204         837 :                 GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
    1205         837 :                 if (ptr->version == 1) {
    1206           0 :                         gf_bs_write_u64(bs, p->segmentDuration);
    1207           0 :                         gf_bs_write_u64(bs, p->mediaTime);
    1208             :                 } else {
    1209         837 :                         gf_bs_write_u32(bs, (u32) p->segmentDuration);
    1210         837 :                         gf_bs_write_u32(bs, (s32) p->mediaTime);
    1211             :                 }
    1212         837 :                 gf_bs_write_u32(bs, p->mediaRate);
    1213             :         }
    1214             :         return GF_OK;
    1215             : }
    1216             : 
    1217        1580 : GF_Err elst_box_size(GF_Box *s)
    1218             : {
    1219             :         u32 durtimebytes;
    1220             :         u32 i, nb_entries;
    1221             :         GF_EditListBox *ptr = (GF_EditListBox *)s;
    1222             : 
    1223             :         //entry count
    1224        1580 :         ptr->size += 4;
    1225        1580 :         nb_entries = gf_list_count(ptr->entryList);
    1226        1580 :         ptr->version = 0;
    1227        3309 :         for (i=0; i<nb_entries; i++) {
    1228        1729 :                 GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
    1229        1729 :                 if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) {
    1230           0 :                         ptr->version = 1;
    1231           0 :                         break;
    1232             :                 }
    1233             :         }
    1234        1580 :         durtimebytes = (ptr->version == 1 ? 16 : 8) + 4;
    1235        1580 :         ptr->size += (nb_entries * durtimebytes);
    1236        1580 :         return GF_OK;
    1237             : }
    1238             : 
    1239             : 
    1240             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1241             : 
    1242        1542 : void esds_box_del(GF_Box *s)
    1243             : {
    1244             :         GF_ESDBox *ptr = (GF_ESDBox *)s;
    1245        1542 :         if (ptr == NULL)        return;
    1246        1542 :         if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc);
    1247        1542 :         gf_free(ptr);
    1248             : }
    1249             : 
    1250             : 
    1251        1049 : GF_Err esds_box_read(GF_Box *s, GF_BitStream *bs)
    1252             : {
    1253             :         GF_Err e=GF_OK;
    1254             :         u32 descSize;
    1255             :         GF_ESDBox *ptr = (GF_ESDBox *)s;
    1256             : 
    1257        1049 :         descSize = (u32) (ptr->size);
    1258             : 
    1259        1049 :         if (descSize) {
    1260        1049 :                 char *enc_desc = (char*)gf_malloc(sizeof(char) * descSize);
    1261        1049 :                 if (!enc_desc) return GF_OUT_OF_MEM;
    1262             :                 //get the payload
    1263        1049 :                 gf_bs_read_data(bs, enc_desc, descSize);
    1264             :                 //send it to the OD Codec
    1265        1049 :                 e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc);
    1266             :                 //OK, free our desc
    1267        1049 :                 gf_free(enc_desc);
    1268             : 
    1269        1049 :                 if (ptr->desc && (ptr->desc->tag!=GF_ODF_ESD_TAG) ) {
    1270           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor tag 0x%x in esds\n", ptr->desc->tag));
    1271           0 :                         gf_odf_desc_del((GF_Descriptor*)ptr->desc);
    1272           0 :                         ptr->desc=NULL;
    1273           0 :                         return GF_ISOM_INVALID_FILE;
    1274             :                 }
    1275             : 
    1276        1049 :                 if (e) {
    1277           0 :                         ptr->desc = NULL;
    1278             :                 } else {
    1279             :                         /*fix broken files*/
    1280        1049 :                         if (ptr->desc && !ptr->desc->URLString) {
    1281        1049 :                                 if (!ptr->desc->slConfig) {
    1282           0 :                                         ptr->desc->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
    1283           0 :                                         ptr->desc->slConfig->predefined = SLPredef_MP4;
    1284        1049 :                                 } else if (ptr->desc->slConfig->predefined != SLPredef_MP4) {
    1285           0 :                                         ptr->desc->slConfig->predefined = SLPredef_MP4;
    1286           0 :                                         gf_odf_slc_set_pref(ptr->desc->slConfig);
    1287             :                                 }
    1288             :                         }
    1289             :                 }
    1290             :         }
    1291             :         return e;
    1292             : }
    1293             : 
    1294        1542 : GF_Box *esds_box_new()
    1295             : {
    1296        3084 :         ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
    1297        1542 :         return (GF_Box *)tmp;
    1298             : }
    1299             : 
    1300             : 
    1301             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1302             : 
    1303         913 : GF_Err esds_box_write(GF_Box *s, GF_BitStream *bs)
    1304             : {
    1305             :         GF_Err e;
    1306             :         u8 *enc_desc;
    1307         913 :         u32 descSize = 0;
    1308             :         GF_ESDBox *ptr = (GF_ESDBox *)s;
    1309             :         //make sure we write with no ESID and no OCRESID
    1310         913 :     if (ptr->desc) {
    1311         912 :         ptr->desc->ESID = 0;
    1312         912 :         ptr->desc->OCRESID = 0;
    1313             :     }
    1314         913 :         e = gf_isom_full_box_write(s, bs);
    1315         913 :         if (e) return e;
    1316         913 :         e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize);
    1317         913 :         if (e) return e;
    1318         912 :         gf_bs_write_data(bs, enc_desc, descSize);
    1319             :         //free our buffer
    1320         912 :         gf_free(enc_desc);
    1321         912 :         return GF_OK;
    1322             : }
    1323             : 
    1324        1938 : GF_Err esds_box_size(GF_Box *s)
    1325             : {
    1326             :         u32 descSize = 0;
    1327             :         GF_ESDBox *ptr = (GF_ESDBox *)s;
    1328             :         //make sure we write with no ESID and no OCRESID
    1329        1938 :     if (ptr->desc) {
    1330        1937 :         ptr->desc->ESID = 0;
    1331        1937 :         ptr->desc->OCRESID = 0;
    1332             :     }
    1333        1938 :         descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc);
    1334        1938 :         ptr->size += descSize;
    1335        1938 :         return GF_OK;
    1336             : }
    1337             : 
    1338             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1339             : 
    1340        3045 : void free_box_del(GF_Box *s)
    1341             : {
    1342             :         GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
    1343        3045 :         if (ptr->data) gf_free(ptr->data);
    1344        3045 :         gf_free(ptr);
    1345        3045 : }
    1346             : 
    1347             : 
    1348        1791 : GF_Err free_box_read(GF_Box *s, GF_BitStream *bs)
    1349             : {
    1350             :         u32 bytesToRead;
    1351             :         GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
    1352             : 
    1353        1791 :         if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR;
    1354             : 
    1355        1791 :         bytesToRead = (u32) (ptr->size);
    1356             : 
    1357        1791 :         if (bytesToRead) {
    1358        1717 :                 ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char));
    1359        1717 :                 if (!ptr->data) return GF_OUT_OF_MEM;
    1360        1717 :                 gf_bs_read_data(bs, ptr->data, bytesToRead);
    1361        1717 :                 ptr->dataSize = bytesToRead;
    1362             :         }
    1363             :         return GF_OK;
    1364             : }
    1365             : 
    1366        3045 : GF_Box *free_box_new()
    1367             : {
    1368        6090 :         ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
    1369        3045 :         return (GF_Box *)tmp;
    1370             : }
    1371             : 
    1372             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1373             : 
    1374        1418 : GF_Err free_box_write(GF_Box *s, GF_BitStream *bs)
    1375             : {
    1376             :         GF_Err e;
    1377             :         GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
    1378        1418 :         if (ptr->original_4cc) {
    1379           0 :                 u32 t = s->type;
    1380           0 :                 s->type=ptr->original_4cc;
    1381           0 :                 e = gf_isom_box_write_header(s, bs);
    1382           0 :                 s->type=t;
    1383             :         } else {
    1384        1418 :                 e = gf_isom_box_write_header(s, bs);
    1385             :         }
    1386        1418 :         if (e) return e;
    1387        1418 :         if (ptr->dataSize)   {
    1388        1403 :                 if (ptr->data) {
    1389        1403 :                         gf_bs_write_data(bs, ptr->data, ptr->dataSize);
    1390             :                 } else {
    1391             :                         u32 i = 0;
    1392           0 :                         while (i<ptr->dataSize) {
    1393           0 :                                 gf_bs_write_u8(bs, 0);
    1394           0 :                                 i++;
    1395             :                         }
    1396             :                 }
    1397             :         }
    1398             :         return GF_OK;
    1399             : }
    1400             : 
    1401        1425 : GF_Err free_box_size(GF_Box *s)
    1402             : {
    1403             :         GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
    1404        1425 :         ptr->size += ptr->dataSize;
    1405        1425 :         return GF_OK;
    1406             : }
    1407             : 
    1408             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1409             : 
    1410        5720 : void ftyp_box_del(GF_Box *s)
    1411             : {
    1412             :         GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
    1413        5720 :         if (ptr->altBrand) gf_free(ptr->altBrand);
    1414        5720 :         gf_free(ptr);
    1415        5720 : }
    1416             : 
    1417        5720 : GF_Box *ftyp_box_new()
    1418             : {
    1419       11440 :         ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
    1420        5720 :         return (GF_Box *)tmp;
    1421             : }
    1422             : 
    1423        4419 : GF_Err ftyp_box_read(GF_Box *s,GF_BitStream *bs)
    1424             : {
    1425             :         u32 i;
    1426             :         GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
    1427             : 
    1428        4419 :         ISOM_DECREASE_SIZE(ptr, 8);
    1429        4419 :         ptr->majorBrand = gf_bs_read_u32(bs);
    1430        4419 :         ptr->minorVersion = gf_bs_read_u32(bs);
    1431             : 
    1432        4419 :         if (ptr->size % 4) return GF_ISOM_INVALID_FILE;
    1433        4419 :         ptr->altCount = ( (u32) (ptr->size)) / 4;
    1434        4419 :         if (!ptr->altCount) return GF_OK;
    1435             : 
    1436        4417 :         ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount);
    1437        4417 :         if (!ptr->altBrand) return GF_OUT_OF_MEM;
    1438             : 
    1439        8585 :         for (i = 0; i<ptr->altCount; i++) {
    1440        8585 :                 ptr->altBrand[i] = gf_bs_read_u32(bs);
    1441             :         }
    1442             :         return GF_OK;
    1443             : }
    1444             : 
    1445             : 
    1446             : 
    1447             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1448             : 
    1449        4036 : GF_Err ftyp_box_write(GF_Box *s, GF_BitStream *bs)
    1450             : {
    1451             :         GF_Err e;
    1452             :         u32 i;
    1453             :         GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
    1454             : 
    1455        4036 :         e = gf_isom_box_write_header(s, bs);
    1456        4036 :         if (e) return e;
    1457        4036 :         gf_bs_write_u32(bs, ptr->majorBrand);
    1458        4036 :         gf_bs_write_u32(bs, ptr->minorVersion);
    1459       12012 :         for (i=0; i<ptr->altCount; i++) {
    1460        7976 :                 gf_bs_write_u32(bs, ptr->altBrand[i]);
    1461             :         }
    1462             :         return GF_OK;
    1463             : }
    1464             : 
    1465        4055 : GF_Err ftyp_box_size(GF_Box *s)
    1466             : {
    1467             :         GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
    1468             : 
    1469        4055 :         ptr->size += 8 + ptr->altCount * 4;
    1470        4055 :         return GF_OK;
    1471             : }
    1472             : 
    1473             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1474             : 
    1475             : 
    1476             : 
    1477           8 : void gnrm_box_del(GF_Box *s)
    1478             : {
    1479             :         GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
    1480           8 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
    1481           8 :         if (ptr->data) gf_free(ptr->data);
    1482           8 :         gf_free(ptr);
    1483           8 : }
    1484             : 
    1485           8 : GF_Box *gnrm_box_new()
    1486             : {
    1487          16 :         ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);
    1488             : 
    1489           8 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    1490           8 :         return (GF_Box *)tmp;
    1491             : }
    1492             : 
    1493             : //dummy
    1494           0 : GF_Err gnrm_box_read(GF_Box *s, GF_BitStream *bs)
    1495             : {
    1496           0 :         return GF_OK;
    1497             : }
    1498             : 
    1499             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1500             : 
    1501           1 : GF_Err gnrm_box_write(GF_Box *s, GF_BitStream *bs)
    1502             : {
    1503             :         GF_Err e;
    1504             :         GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
    1505             : 
    1506             :         //careful we are not writing the box type but the entry type so switch for write
    1507           1 :         ptr->type = ptr->EntryType;
    1508           1 :         e = gf_isom_box_write_header(s, bs);
    1509           1 :         if (e) return e;
    1510           1 :         ptr->type = GF_ISOM_BOX_TYPE_GNRM;
    1511           1 :         gf_bs_write_data(bs, ptr->reserved, 6);
    1512           1 :         gf_bs_write_u16(bs, ptr->dataReferenceIndex);
    1513           1 :         gf_bs_write_data(bs,  ptr->data, ptr->data_size);
    1514           1 :         return GF_OK;
    1515             : }
    1516             : 
    1517           1 : GF_Err gnrm_box_size(GF_Box *s)
    1518             : {
    1519             :         GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
    1520           1 :         s->type = GF_ISOM_BOX_TYPE_GNRM;
    1521           1 :         ptr->size += 8+ptr->data_size;
    1522           1 :         return GF_OK;
    1523             : }
    1524             : 
    1525             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1526             : 
    1527             : 
    1528          22 : void gnrv_box_del(GF_Box *s)
    1529             : {
    1530             :         GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
    1531          22 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
    1532          22 :         if (ptr->data) gf_free(ptr->data);
    1533          22 :         gf_free(ptr);
    1534          22 : }
    1535             : 
    1536          22 : GF_Box *gnrv_box_new()
    1537             : {
    1538          44 :         ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
    1539          22 :         gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp);
    1540          22 :         return (GF_Box *)tmp;
    1541             : }
    1542             : //dummy
    1543           0 : GF_Err gnrv_box_read(GF_Box *s, GF_BitStream *bs)
    1544             : {
    1545           0 :         return GF_OK;
    1546             : }
    1547             : 
    1548             : 
    1549             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1550             : 
    1551          20 : GF_Err gnrv_box_write(GF_Box *s, GF_BitStream *bs)
    1552             : {
    1553             :         GF_Err e;
    1554             :         GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
    1555             : 
    1556             :         //careful we are not writing the box type but the entry type so switch for write
    1557          20 :         ptr->type = ptr->EntryType;
    1558          20 :         e = gf_isom_box_write_header(s, bs);
    1559          20 :         if (e) return e;
    1560          20 :         ptr->type = GF_ISOM_BOX_TYPE_GNRV;
    1561             : 
    1562          20 :         gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs);
    1563          20 :         gf_bs_write_data(bs,  ptr->data, ptr->data_size);
    1564          20 :         return GF_OK;
    1565             : }
    1566             : 
    1567          58 : GF_Err gnrv_box_size(GF_Box *s)
    1568             : {
    1569             :         GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
    1570          58 :         s->type = GF_ISOM_BOX_TYPE_GNRV;
    1571          58 :         gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
    1572          58 :         ptr->size += ptr->data_size;
    1573          58 :         return GF_OK;
    1574             : }
    1575             : 
    1576             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1577             : 
    1578             : 
    1579             : 
    1580          70 : void gnra_box_del(GF_Box *s)
    1581             : {
    1582             :         GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
    1583          70 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
    1584          70 :         if (ptr->data) gf_free(ptr->data);
    1585          70 :         gf_free(ptr);
    1586          70 : }
    1587             : 
    1588          70 : GF_Box *gnra_box_new()
    1589             : {
    1590         140 :         ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
    1591          70 :         gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp);
    1592          70 :         return (GF_Box *)tmp;
    1593             : }
    1594             : //dummy
    1595           0 : GF_Err gnra_box_read(GF_Box *s, GF_BitStream *bs)
    1596             : {
    1597           0 :         return GF_OK;
    1598             : }
    1599             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1600             : 
    1601             : 
    1602          69 : GF_Err gnra_box_write(GF_Box *s, GF_BitStream *bs)
    1603             : {
    1604             :         GF_Err e;
    1605             :         GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
    1606             : 
    1607             :         //careful we are not writing the box type but the entry type so switch for write
    1608          69 :         ptr->type = ptr->EntryType;
    1609          69 :         e = gf_isom_box_write_header(s, bs);
    1610          69 :         if (e) return e;
    1611          69 :         ptr->type = GF_ISOM_BOX_TYPE_GNRA;
    1612             : 
    1613          69 :         gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs);
    1614          69 :         if (ptr->data) {
    1615           5 :                 gf_bs_write_data(bs,  ptr->data, ptr->data_size);
    1616             :         }
    1617             :         return GF_OK;
    1618             : }
    1619             : 
    1620         195 : GF_Err gnra_box_size(GF_Box *s)
    1621             : {
    1622             :         GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
    1623         195 :         s->type = GF_ISOM_BOX_TYPE_GNRA;
    1624         195 :         gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s);
    1625         195 :         ptr->size += ptr->data_size;
    1626         195 :         return GF_OK;
    1627             : }
    1628             : 
    1629             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1630             : 
    1631        4536 : void hdlr_box_del(GF_Box *s)
    1632             : {
    1633             :         GF_HandlerBox *ptr = (GF_HandlerBox *)s;
    1634        4536 :         if (ptr == NULL) return;
    1635        4536 :         if (ptr->nameUTF8) gf_free(ptr->nameUTF8);
    1636        4536 :         gf_free(ptr);
    1637             : }
    1638             : 
    1639             : 
    1640        3426 : GF_Err hdlr_box_read(GF_Box *s, GF_BitStream *bs)
    1641             : {
    1642             :         u64 cookie;
    1643             :         GF_HandlerBox *ptr = (GF_HandlerBox *)s;
    1644             : 
    1645        3426 :         ISOM_DECREASE_SIZE(ptr, 20);
    1646        3426 :         ptr->reserved1 = gf_bs_read_u32(bs);
    1647        3426 :         ptr->handlerType = gf_bs_read_u32(bs);
    1648        3426 :         gf_bs_read_data(bs, (char*)ptr->reserved2, 12);
    1649             : 
    1650        3426 :         cookie = gf_bs_get_cookie(bs);
    1651        3426 :         if (ptr->handlerType==GF_ISOM_MEDIA_VISUAL)
    1652        1814 :                 cookie |= GF_ISOM_BS_COOKIE_VISUAL_TRACK;
    1653             :         else
    1654        1612 :                 cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
    1655        3426 :         gf_bs_set_cookie(bs, cookie);
    1656             : 
    1657        3426 :         if (ptr->size) {
    1658        3426 :                 ptr->nameUTF8 = (char*)gf_malloc((u32) ptr->size);
    1659        3426 :                 if (!ptr->nameUTF8) return GF_OUT_OF_MEM;
    1660        3426 :                 gf_bs_read_data(bs, ptr->nameUTF8, (u32) ptr->size);
    1661             : 
    1662             :                 //patch for old QT files - we cannot rely on checking if str[0]==len(str+1) since we may have
    1663             :                 //cases where the first character of the string decimal value is indeed the same as the string length!!
    1664             :                 //we had this issue with encryption_import test
    1665             :                 //we therefore only check if last char is null, and if not so assume old QT style
    1666        3426 :                 if (ptr->nameUTF8[ptr->size-1]) {
    1667         266 :                         memmove(ptr->nameUTF8, ptr->nameUTF8+1, sizeof(char) * (u32) (ptr->size-1) );
    1668         266 :                         ptr->nameUTF8[ptr->size-1] = 0;
    1669         266 :                         ptr->store_counted_string = GF_TRUE;
    1670             :                 }
    1671             :         }
    1672             :         return GF_OK;
    1673             : }
    1674             : 
    1675        4536 : GF_Box *hdlr_box_new()
    1676             : {
    1677        9072 :         ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
    1678        4536 :         return (GF_Box *)tmp;
    1679             : }
    1680             : 
    1681             : 
    1682             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1683             : 
    1684        3453 : GF_Err hdlr_box_write(GF_Box *s, GF_BitStream *bs)
    1685             : {
    1686             :         GF_Err e;
    1687             :         GF_HandlerBox *ptr = (GF_HandlerBox *)s;
    1688        3453 :         e = gf_isom_full_box_write(s, bs);
    1689        3453 :         if (e) return e;
    1690        3453 :         gf_bs_write_u32(bs, ptr->reserved1);
    1691        3453 :         gf_bs_write_u32(bs, ptr->handlerType);
    1692        3453 :         gf_bs_write_data(bs, (char*)ptr->reserved2, 12);
    1693             : 
    1694        3453 :         if (ptr->nameUTF8) {
    1695        3446 :                 u32 len = (u32)strlen(ptr->nameUTF8);
    1696        3446 :                 if (ptr->store_counted_string) {
    1697         178 :                         gf_bs_write_u8(bs, len);
    1698         178 :                         gf_bs_write_data(bs, ptr->nameUTF8, len);
    1699             :                 } else {
    1700        3268 :                         gf_bs_write_data(bs, ptr->nameUTF8, len);
    1701        3268 :                         gf_bs_write_u8(bs, 0);
    1702             :                 }
    1703             :         } else {
    1704           7 :                 gf_bs_write_u8(bs, 0);
    1705             :         }
    1706             :         return GF_OK;
    1707             : }
    1708             : 
    1709        6728 : GF_Err hdlr_box_size(GF_Box *s)
    1710             : {
    1711             :         GF_HandlerBox *ptr = (GF_HandlerBox *)s;
    1712        6728 :         ptr->size += 20 + 1; //null term or counted string
    1713        6728 :         if (ptr->nameUTF8) {
    1714        6719 :                 ptr->size += strlen(ptr->nameUTF8);
    1715             :         }
    1716        6728 :         return GF_OK;
    1717             : }
    1718             : 
    1719             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1720             : 
    1721             : 
    1722           3 : void hinf_box_del(GF_Box *s)
    1723             : {
    1724             :         GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
    1725           3 :         gf_free(hinf);
    1726           3 : }
    1727             : 
    1728           3 : GF_Box *hinf_box_new()
    1729             : {
    1730           6 :         ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);
    1731             : 
    1732           3 :         tmp->child_boxes = gf_list_new();
    1733           3 :         return (GF_Box *)tmp;
    1734             : }
    1735             : 
    1736           0 : GF_Err hinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    1737             : {
    1738             :         GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
    1739           0 :         switch (a->type) {
    1740           0 :         case GF_ISOM_BOX_TYPE_MAXR:
    1741           0 :                 if (!is_rem) {
    1742           0 :                         u32 i=0;
    1743             :                         GF_MAXRBox *maxR;
    1744           0 :                         while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->child_boxes, &i))) {
    1745           0 :                                 if ((maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity))
    1746           0 :                                         ERROR_ON_DUPLICATED_BOX(a, s)
    1747             :                         }
    1748             :                 }
    1749             :                 break;
    1750             :         }
    1751             :         return GF_OK;
    1752             : }
    1753             : 
    1754             : 
    1755           1 : GF_Err hinf_box_read(GF_Box *s, GF_BitStream *bs)
    1756             : {
    1757           1 :         return gf_isom_box_array_read(s, bs);
    1758             : }
    1759             : 
    1760             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1761             : 
    1762           1 : GF_Err hinf_box_write(GF_Box *s, GF_BitStream *bs)
    1763             : {
    1764             : //      GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
    1765           1 :         if (!s) return GF_BAD_PARAM;
    1766           1 :         return gf_isom_box_write_header(s, bs);
    1767             : }
    1768             : 
    1769           1 : GF_Err hinf_box_size(GF_Box *s)
    1770             : {
    1771           1 :         return GF_OK;
    1772             : }
    1773             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1774             : 
    1775         121 : void hmhd_box_del(GF_Box *s)
    1776             : {
    1777             :         GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
    1778         121 :         if (ptr == NULL) return;
    1779         121 :         gf_free(ptr);
    1780             : }
    1781             : 
    1782             : 
    1783          46 : GF_Err hmhd_box_read(GF_Box *s,GF_BitStream *bs)
    1784             : {
    1785             :         GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
    1786             : 
    1787          46 :         ISOM_DECREASE_SIZE(ptr, 16);
    1788          46 :         ptr->maxPDUSize = gf_bs_read_u16(bs);
    1789          46 :         ptr->avgPDUSize = gf_bs_read_u16(bs);
    1790          46 :         ptr->maxBitrate = gf_bs_read_u32(bs);
    1791          46 :         ptr->avgBitrate = gf_bs_read_u32(bs);
    1792          46 :         ptr->slidingAverageBitrate = gf_bs_read_u32(bs);
    1793          46 :         return GF_OK;
    1794             : }
    1795             : 
    1796         121 : GF_Box *hmhd_box_new()
    1797             : {
    1798         242 :         ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
    1799         121 :         return (GF_Box *)tmp;
    1800             : }
    1801             : 
    1802             : 
    1803             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1804             : 
    1805          74 : GF_Err hmhd_box_write(GF_Box *s, GF_BitStream *bs)
    1806             : {
    1807             :         GF_Err e;
    1808             :         GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
    1809             : 
    1810          74 :         e = gf_isom_full_box_write(s, bs);
    1811          74 :         if (e) return e;
    1812          74 :         gf_bs_write_u16(bs, ptr->maxPDUSize);
    1813          74 :         gf_bs_write_u16(bs, ptr->avgPDUSize);
    1814          74 :         gf_bs_write_u32(bs, ptr->maxBitrate);
    1815          74 :         gf_bs_write_u32(bs, ptr->avgBitrate);
    1816          74 :         gf_bs_write_u32(bs, ptr->slidingAverageBitrate);
    1817          74 :         return GF_OK;
    1818             : }
    1819             : 
    1820         220 : GF_Err hmhd_box_size(GF_Box *s)
    1821             : {
    1822             :         GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
    1823         220 :         ptr->size += 16;
    1824         220 :         return GF_OK;
    1825             : }
    1826             : 
    1827             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1828             : 
    1829         219 : GF_Box *hnti_box_new()
    1830             : {
    1831         438 :         ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
    1832         219 :         return (GF_Box *)tmp;
    1833             : }
    1834             : 
    1835         219 : void hnti_box_del(GF_Box *a)
    1836             : {
    1837         219 :         gf_free(a);
    1838         219 : }
    1839             : 
    1840         216 : GF_Err hnti_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    1841             : {
    1842             :         GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
    1843         216 :         if (!ptr || !a) return GF_BAD_PARAM;
    1844             : 
    1845         216 :         switch (a->type) {
    1846             :         //this is the value for GF_RTPBox - same as HintSampleEntry for RTP !!!
    1847         216 :         case GF_ISOM_BOX_TYPE_RTP:
    1848             :         case GF_ISOM_BOX_TYPE_SDP:
    1849         216 :                 BOX_FIELD_ASSIGN(SDP, GF_Box)
    1850         216 :                 break;
    1851             :         default:
    1852             :                 break;
    1853             :         }
    1854             :         return GF_OK;
    1855             : }
    1856             : 
    1857          89 : GF_Err hnti_box_read(GF_Box *s, GF_BitStream *bs)
    1858             : {
    1859          89 :         return gf_isom_box_array_read_ex(s, bs, s->type);
    1860             : }
    1861             : 
    1862             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1863         129 : GF_Err hnti_box_write(GF_Box *s, GF_BitStream *bs)
    1864             : {
    1865         129 :         return gf_isom_box_write_header(s, bs);
    1866             : }
    1867             : 
    1868             : 
    1869         385 : GF_Err hnti_box_size(GF_Box *s)
    1870             : {
    1871         385 :         return GF_OK;
    1872             : }
    1873             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1874             : 
    1875             : /**********************************************************
    1876             :                 GF_SDPBox
    1877             : **********************************************************/
    1878             : 
    1879         121 : void sdp_box_del(GF_Box *s)
    1880             : {
    1881             :         GF_SDPBox *ptr = (GF_SDPBox *)s;
    1882         121 :         if (ptr->sdpText) gf_free(ptr->sdpText);
    1883         121 :         gf_free(ptr);
    1884             : 
    1885         121 : }
    1886          46 : GF_Err sdp_box_read(GF_Box *s, GF_BitStream *bs)
    1887             : {
    1888             :         u32 length;
    1889             :         GF_SDPBox *ptr = (GF_SDPBox *)s;
    1890          46 :         if (ptr == NULL) return GF_BAD_PARAM;
    1891             : 
    1892          46 :         length = (u32) (ptr->size);
    1893             :         //sdp text has no delimiter !!!
    1894          46 :         ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
    1895          46 :         if (!ptr->sdpText) return GF_OUT_OF_MEM;
    1896             : 
    1897          46 :         gf_bs_read_data(bs, ptr->sdpText, length);
    1898          46 :         ptr->sdpText[length] = 0;
    1899          46 :         return GF_OK;
    1900             : }
    1901         121 : GF_Box *sdp_box_new()
    1902             : {
    1903         242 :         ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
    1904         121 :         return (GF_Box *)tmp;
    1905             : }
    1906             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1907          74 : GF_Err sdp_box_write(GF_Box *s, GF_BitStream *bs)
    1908             : {
    1909             :         GF_Err e;
    1910             :         GF_SDPBox *ptr = (GF_SDPBox *)s;
    1911          74 :         if (ptr == NULL) return GF_BAD_PARAM;
    1912          74 :         e = gf_isom_box_write_header(s, bs);
    1913          74 :         if (e) return e;
    1914             :         //don't write the NULL char!!!
    1915          74 :         if (ptr->sdpText)
    1916          73 :                 gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
    1917             :         return GF_OK;
    1918             : }
    1919         220 : GF_Err sdp_box_size(GF_Box *s)
    1920             : {
    1921             :         GF_SDPBox *ptr = (GF_SDPBox *)s;
    1922             :         //don't count the NULL char!!!
    1923         220 :         if (ptr->sdpText)
    1924         219 :                 ptr->size += strlen(ptr->sdpText);
    1925         220 :         return GF_OK;
    1926             : }
    1927             : 
    1928             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1929             : 
    1930             : 
    1931             : 
    1932             : 
    1933          99 : void rtp_hnti_box_del(GF_Box *s)
    1934             : {
    1935             :         GF_RTPBox *ptr = (GF_RTPBox *)s;
    1936          99 :         if (ptr->sdpText) gf_free(ptr->sdpText);
    1937          99 :         gf_free(ptr);
    1938             : 
    1939          99 : }
    1940          43 : GF_Err rtp_hnti_box_read(GF_Box *s, GF_BitStream *bs)
    1941             : {
    1942             :         u32 length;
    1943             :         GF_RTPBox *ptr = (GF_RTPBox *)s;
    1944          43 :         if (ptr == NULL) return GF_BAD_PARAM;
    1945             : 
    1946          43 :         ISOM_DECREASE_SIZE(ptr, 4)
    1947          43 :         ptr->subType = gf_bs_read_u32(bs);
    1948             : 
    1949          43 :         length = (u32) (ptr->size);
    1950             :         //sdp text has no delimiter !!!
    1951          43 :         ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
    1952          43 :         if (!ptr->sdpText) return GF_OUT_OF_MEM;
    1953             : 
    1954          43 :         gf_bs_read_data(bs, ptr->sdpText, length);
    1955          43 :         ptr->sdpText[length] = 0;
    1956          43 :         return GF_OK;
    1957             : }
    1958             : 
    1959          99 : GF_Box *rtp_hnti_box_new()
    1960             : {
    1961         198 :         ISOM_DECL_BOX_ALLOC(GF_RTPBox, GF_ISOM_BOX_TYPE_RTP);
    1962          99 :         tmp->subType = GF_ISOM_BOX_TYPE_SDP;
    1963          99 :         return (GF_Box *)tmp;
    1964             : }
    1965             : #ifndef GPAC_DISABLE_ISOM_WRITE
    1966          55 : GF_Err rtp_hnti_box_write(GF_Box *s, GF_BitStream *bs)
    1967             : {
    1968             :         GF_Err e;
    1969             :         GF_RTPBox *ptr = (GF_RTPBox *)s;
    1970          55 :         if (ptr == NULL) return GF_BAD_PARAM;
    1971          55 :         e = gf_isom_box_write_header(s, bs);
    1972          55 :         if (e) return e;
    1973          55 :         gf_bs_write_u32(bs, ptr->subType);
    1974             :         //don't write the NULL char!!!
    1975          55 :         gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
    1976          55 :         return GF_OK;
    1977             : }
    1978             : 
    1979         165 : GF_Err rtp_hnti_box_size(GF_Box *s)
    1980             : {
    1981             :         GF_RTPBox *ptr = (GF_RTPBox *)s;
    1982         165 :         ptr->size += 4 + strlen(ptr->sdpText);
    1983         165 :         return GF_OK;
    1984             : }
    1985             : 
    1986             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    1987             : 
    1988             : 
    1989             : /**********************************************************
    1990             :                 TRPY GF_Box
    1991             : **********************************************************/
    1992             : 
    1993           3 : void trpy_box_del(GF_Box *s)
    1994             : {
    1995           3 :         gf_free((GF_TRPYBox *)s);
    1996           3 : }
    1997           1 : GF_Err trpy_box_read(GF_Box *s, GF_BitStream *bs)
    1998             : {
    1999             :         GF_TRPYBox *ptr = (GF_TRPYBox *)s;
    2000           1 :         ISOM_DECREASE_SIZE(ptr, 8);
    2001           1 :         ptr->nbBytes = gf_bs_read_u64(bs);
    2002           1 :         return GF_OK;
    2003             : }
    2004           3 : GF_Box *trpy_box_new()
    2005             : {
    2006           6 :         ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
    2007           3 :         return (GF_Box *)tmp;
    2008             : }
    2009             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2010             : 
    2011           1 : GF_Err trpy_box_write(GF_Box *s, GF_BitStream *bs)
    2012             : {
    2013             :         GF_Err e;
    2014             :         GF_TRPYBox *ptr = (GF_TRPYBox *)s;
    2015           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2016             : 
    2017           1 :         e = gf_isom_box_write_header(s, bs);
    2018           1 :         if (e) return e;
    2019           1 :         gf_bs_write_u64(bs, ptr->nbBytes);
    2020           1 :         return GF_OK;
    2021             : }
    2022           1 : GF_Err trpy_box_size(GF_Box *s)
    2023             : {
    2024           1 :         s->size += 8;
    2025           1 :         return GF_OK;
    2026             : }
    2027             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2028             : 
    2029             : /**********************************************************
    2030             :                 TOTL GF_Box
    2031             : **********************************************************/
    2032             : 
    2033           3 : void totl_box_del(GF_Box *s)
    2034             : {
    2035           3 :         gf_free((GF_TRPYBox *)s);
    2036           3 : }
    2037           1 : GF_Err totl_box_read(GF_Box *s, GF_BitStream *bs)
    2038             : {
    2039             :         GF_TOTLBox *ptr = (GF_TOTLBox *)s;
    2040           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    2041           1 :         ptr->nbBytes = gf_bs_read_u32(bs);
    2042           1 :         return GF_OK;
    2043             : }
    2044           3 : GF_Box *totl_box_new()
    2045             : {
    2046           6 :         ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
    2047           3 :         return (GF_Box *)tmp;
    2048             : }
    2049             : 
    2050             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2051             : 
    2052           1 : GF_Err totl_box_write(GF_Box *s, GF_BitStream *bs)
    2053             : {
    2054             :         GF_Err e;
    2055             :         GF_TOTLBox *ptr = (GF_TOTLBox *)s;
    2056           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2057           1 :         e = gf_isom_box_write_header(s, bs);
    2058           1 :         if (e) return e;
    2059           1 :         gf_bs_write_u32(bs, ptr->nbBytes);
    2060           1 :         return GF_OK;
    2061             : }
    2062           1 : GF_Err totl_box_size(GF_Box *s)
    2063             : {
    2064           1 :         s->size += 4;
    2065           1 :         return GF_OK;
    2066             : }
    2067             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2068             : 
    2069             : 
    2070             : /**********************************************************
    2071             :                 NUMP GF_Box
    2072             : **********************************************************/
    2073             : 
    2074           3 : void nump_box_del(GF_Box *s)
    2075             : {
    2076           3 :         gf_free((GF_NUMPBox *)s);
    2077           3 : }
    2078           1 : GF_Err nump_box_read(GF_Box *s, GF_BitStream *bs)
    2079             : {
    2080             :         GF_NUMPBox *ptr = (GF_NUMPBox *)s;
    2081           1 :         ISOM_DECREASE_SIZE(ptr, 8);
    2082           1 :         ptr->nbPackets = gf_bs_read_u64(bs);
    2083           1 :         return GF_OK;
    2084             : }
    2085           3 : GF_Box *nump_box_new()
    2086             : {
    2087           6 :         ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
    2088           3 :         return (GF_Box *)tmp;
    2089             : }
    2090             : 
    2091             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2092           1 : GF_Err nump_box_write(GF_Box *s, GF_BitStream *bs)
    2093             : {
    2094             :         GF_Err e;
    2095             :         GF_NUMPBox *ptr = (GF_NUMPBox *)s;
    2096           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2097           1 :         e = gf_isom_box_write_header(s, bs);
    2098           1 :         if (e) return e;
    2099           1 :         gf_bs_write_u64(bs, ptr->nbPackets);
    2100           1 :         return GF_OK;
    2101             : }
    2102           1 : GF_Err nump_box_size(GF_Box *s)
    2103             : {
    2104           1 :         s->size += 8;
    2105           1 :         return GF_OK;
    2106             : }
    2107             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2108             : 
    2109             : 
    2110             : /**********************************************************
    2111             :                 NPCK GF_Box
    2112             : **********************************************************/
    2113             : 
    2114           3 : void npck_box_del(GF_Box *s)
    2115             : {
    2116           3 :         gf_free((GF_NPCKBox *)s);
    2117           3 : }
    2118           1 : GF_Err npck_box_read(GF_Box *s, GF_BitStream *bs)
    2119             : {
    2120             :         GF_NPCKBox *ptr = (GF_NPCKBox *)s;
    2121           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    2122           1 :         ptr->nbPackets = gf_bs_read_u32(bs);
    2123           1 :         return GF_OK;
    2124             : }
    2125           3 : GF_Box *npck_box_new()
    2126             : {
    2127           6 :         ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
    2128           3 :         return (GF_Box *)tmp;
    2129             : }
    2130             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2131           1 : GF_Err npck_box_write(GF_Box *s, GF_BitStream *bs)
    2132             : {
    2133             :         GF_Err e;
    2134             :         GF_NPCKBox *ptr = (GF_NPCKBox *)s;
    2135           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2136           1 :         e = gf_isom_box_write_header(s, bs);
    2137           1 :         if (e) return e;
    2138           1 :         gf_bs_write_u32(bs, ptr->nbPackets);
    2139           1 :         return GF_OK;
    2140             : }
    2141           1 : GF_Err npck_box_size(GF_Box *s)
    2142             : {
    2143           1 :         s->size += 4;
    2144           1 :         return GF_OK;
    2145             : }
    2146             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2147             : 
    2148             : 
    2149             : /**********************************************************
    2150             :                 TPYL GF_Box
    2151             : **********************************************************/
    2152             : 
    2153           3 : void tpyl_box_del(GF_Box *s)
    2154             : {
    2155           3 :         gf_free((GF_NTYLBox *)s);
    2156           3 : }
    2157           1 : GF_Err tpyl_box_read(GF_Box *s, GF_BitStream *bs)
    2158             : {
    2159             :         GF_NTYLBox *ptr = (GF_NTYLBox *)s;
    2160           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2161           1 :         ISOM_DECREASE_SIZE(ptr, 8);
    2162           1 :         ptr->nbBytes = gf_bs_read_u64(bs);
    2163           1 :         return GF_OK;
    2164             : }
    2165           3 : GF_Box *tpyl_box_new()
    2166             : {
    2167           6 :         ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
    2168           3 :         return (GF_Box *)tmp;
    2169             : }
    2170             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2171           1 : GF_Err tpyl_box_write(GF_Box *s, GF_BitStream *bs)
    2172             : {
    2173             :         GF_Err e;
    2174             :         GF_NTYLBox *ptr = (GF_NTYLBox *)s;
    2175           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2176           1 :         e = gf_isom_box_write_header(s, bs);
    2177           1 :         if (e) return e;
    2178           1 :         gf_bs_write_u64(bs, ptr->nbBytes);
    2179           1 :         return GF_OK;
    2180             : }
    2181           1 : GF_Err tpyl_box_size(GF_Box *s)
    2182             : {
    2183           1 :         s->size += 8;
    2184           1 :         return GF_OK;
    2185             : }
    2186             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2187             : 
    2188             : /**********************************************************
    2189             :                 TPAY GF_Box
    2190             : **********************************************************/
    2191             : 
    2192           3 : void tpay_box_del(GF_Box *s)
    2193             : {
    2194           3 :         gf_free((GF_TPAYBox *)s);
    2195           3 : }
    2196           1 : GF_Err tpay_box_read(GF_Box *s, GF_BitStream *bs)
    2197             : {
    2198             :         GF_TPAYBox *ptr = (GF_TPAYBox *)s;
    2199           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    2200           1 :         ptr->nbBytes = gf_bs_read_u32(bs);
    2201           1 :         return GF_OK;
    2202             : }
    2203           3 : GF_Box *tpay_box_new()
    2204             : {
    2205           6 :         ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
    2206           3 :         return (GF_Box *)tmp;
    2207             : }
    2208             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2209           1 : GF_Err tpay_box_write(GF_Box *s, GF_BitStream *bs)
    2210             : {
    2211             :         GF_Err e;
    2212             :         GF_TPAYBox *ptr = (GF_TPAYBox *)s;
    2213           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2214           1 :         e = gf_isom_box_write_header(s, bs);
    2215           1 :         if (e) return e;
    2216           1 :         gf_bs_write_u32(bs, ptr->nbBytes);
    2217           1 :         return GF_OK;
    2218             : }
    2219           1 : GF_Err tpay_box_size(GF_Box *s)
    2220             : {
    2221           1 :         s->size += 4;
    2222           1 :         return GF_OK;
    2223             : }
    2224             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2225             : 
    2226             : 
    2227             : /**********************************************************
    2228             :                 MAXR GF_Box
    2229             : **********************************************************/
    2230             : 
    2231           3 : void maxr_box_del(GF_Box *s)
    2232             : {
    2233           3 :         gf_free((GF_MAXRBox *)s);
    2234           3 : }
    2235           1 : GF_Err maxr_box_read(GF_Box *s, GF_BitStream *bs)
    2236             : {
    2237             :         GF_MAXRBox *ptr = (GF_MAXRBox *)s;
    2238           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2239           1 :         ISOM_DECREASE_SIZE(ptr, 8);
    2240           1 :         ptr->granularity = gf_bs_read_u32(bs);
    2241           1 :         ptr->maxDataRate = gf_bs_read_u32(bs);
    2242           1 :         return GF_OK;
    2243             : }
    2244           3 : GF_Box *maxr_box_new()
    2245             : {
    2246           6 :         ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
    2247           3 :         return (GF_Box *)tmp;
    2248             : }
    2249             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2250           1 : GF_Err maxr_box_write(GF_Box *s, GF_BitStream *bs)
    2251             : {
    2252             :         GF_Err e;
    2253             :         GF_MAXRBox *ptr = (GF_MAXRBox *)s;
    2254           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2255           1 :         e = gf_isom_box_write_header(s, bs);
    2256           1 :         if (e) return e;
    2257           1 :         gf_bs_write_u32(bs, ptr->granularity);
    2258           1 :         gf_bs_write_u32(bs, ptr->maxDataRate);
    2259           1 :         return GF_OK;
    2260             : }
    2261           1 : GF_Err maxr_box_size(GF_Box *s)
    2262             : {
    2263           1 :         s->size += 8;
    2264           1 :         return GF_OK;
    2265             : }
    2266             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2267             : 
    2268             : 
    2269             : /**********************************************************
    2270             :                 DMED GF_Box
    2271             : **********************************************************/
    2272             : 
    2273           3 : void dmed_box_del(GF_Box *s)
    2274             : {
    2275           3 :         gf_free((GF_DMEDBox *)s);
    2276           3 : }
    2277           1 : GF_Err dmed_box_read(GF_Box *s, GF_BitStream *bs)
    2278             : {
    2279             :         GF_DMEDBox *ptr = (GF_DMEDBox *)s;
    2280           1 :         ISOM_DECREASE_SIZE(ptr, 8);
    2281           1 :         ptr->nbBytes = gf_bs_read_u64(bs);
    2282           1 :         return GF_OK;
    2283             : }
    2284           3 : GF_Box *dmed_box_new()
    2285             : {
    2286           6 :         ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
    2287           3 :         return (GF_Box *)tmp;
    2288             : }
    2289             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2290           1 : GF_Err dmed_box_write(GF_Box *s, GF_BitStream *bs)
    2291             : {
    2292             :         GF_Err e;
    2293             :         GF_DMEDBox *ptr = (GF_DMEDBox *)s;
    2294           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2295           1 :         e = gf_isom_box_write_header(s, bs);
    2296           1 :         if (e) return e;
    2297           1 :         gf_bs_write_u64(bs, ptr->nbBytes);
    2298           1 :         return GF_OK;
    2299             : }
    2300           1 : GF_Err dmed_box_size(GF_Box *s)
    2301             : {
    2302           1 :         s->size += 8;
    2303           1 :         return GF_OK;
    2304             : }
    2305             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2306             : 
    2307             : /**********************************************************
    2308             :                 DIMM GF_Box
    2309             : **********************************************************/
    2310             : 
    2311           3 : void dimm_box_del(GF_Box *s)
    2312             : {
    2313           3 :         gf_free((GF_DIMMBox *)s);
    2314           3 : }
    2315           1 : GF_Err dimm_box_read(GF_Box *s, GF_BitStream *bs)
    2316             : {
    2317             :         GF_DIMMBox *ptr = (GF_DIMMBox *)s;
    2318           1 :         ISOM_DECREASE_SIZE(ptr, 8)
    2319           1 :         ptr->nbBytes = gf_bs_read_u64(bs);
    2320           1 :         return GF_OK;
    2321             : }
    2322           3 : GF_Box *dimm_box_new()
    2323             : {
    2324           6 :         ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
    2325           3 :         return (GF_Box *)tmp;
    2326             : }
    2327             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2328           1 : GF_Err dimm_box_write(GF_Box *s, GF_BitStream *bs)
    2329             : {
    2330             :         GF_Err e;
    2331             :         GF_DIMMBox *ptr = (GF_DIMMBox *)s;
    2332           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2333           1 :         e = gf_isom_box_write_header(s, bs);
    2334           1 :         if (e) return e;
    2335           1 :         gf_bs_write_u64(bs, ptr->nbBytes);
    2336           1 :         return GF_OK;
    2337             : }
    2338           1 : GF_Err dimm_box_size(GF_Box *s)
    2339             : {
    2340           1 :         s->size += 8;
    2341           1 :         return GF_OK;
    2342             : }
    2343             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2344             : 
    2345             : /**********************************************************
    2346             :                 DREP GF_Box
    2347             : **********************************************************/
    2348             : 
    2349           3 : void drep_box_del(GF_Box *s)
    2350             : {
    2351           3 :         gf_free((GF_DREPBox *)s);
    2352           3 : }
    2353           1 : GF_Err drep_box_read(GF_Box *s, GF_BitStream *bs)
    2354             : {
    2355             :         GF_DREPBox *ptr = (GF_DREPBox *)s;
    2356           1 :         ISOM_DECREASE_SIZE(ptr, 8)
    2357           1 :         ptr->nbBytes = gf_bs_read_u64(bs);
    2358           1 :         return GF_OK;
    2359             : }
    2360           3 : GF_Box *drep_box_new()
    2361             : {
    2362           6 :         ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
    2363           3 :         return (GF_Box *)tmp;
    2364             : }
    2365             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2366           1 : GF_Err drep_box_write(GF_Box *s, GF_BitStream *bs)
    2367             : {
    2368             :         GF_Err e;
    2369             :         GF_DREPBox *ptr = (GF_DREPBox *)s;
    2370           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2371           1 :         e = gf_isom_box_write_header(s, bs);
    2372           1 :         if (e) return e;
    2373           1 :         gf_bs_write_u64(bs, ptr->nbBytes);
    2374           1 :         return GF_OK;
    2375             : }
    2376           1 : GF_Err drep_box_size(GF_Box *s)
    2377             : {
    2378           1 :         s->size += 8;
    2379           1 :         return GF_OK;
    2380             : }
    2381             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2382             : 
    2383             : 
    2384             : 
    2385             : /**********************************************************
    2386             :                 TMIN GF_Box
    2387             : **********************************************************/
    2388             : 
    2389           3 : void tmin_box_del(GF_Box *s)
    2390             : {
    2391           3 :         gf_free((GF_TMINBox *)s);
    2392           3 : }
    2393           1 : GF_Err tmin_box_read(GF_Box *s, GF_BitStream *bs)
    2394             : {
    2395             :         GF_TMINBox *ptr = (GF_TMINBox *)s;
    2396           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    2397           1 :         ptr->minTime = gf_bs_read_u32(bs);
    2398           1 :         return GF_OK;
    2399             : }
    2400           3 : GF_Box *tmin_box_new()
    2401             : {
    2402           6 :         ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
    2403           3 :         return (GF_Box *)tmp;
    2404             : }
    2405             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2406           1 : GF_Err tmin_box_write(GF_Box *s, GF_BitStream *bs)
    2407             : {
    2408             :         GF_Err e;
    2409             :         GF_TMINBox *ptr = (GF_TMINBox *)s;
    2410           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2411           1 :         e = gf_isom_box_write_header(s, bs);
    2412           1 :         if (e) return e;
    2413           1 :         gf_bs_write_u32(bs, ptr->minTime);
    2414           1 :         return GF_OK;
    2415             : }
    2416           1 : GF_Err tmin_box_size(GF_Box *s)
    2417             : {
    2418           1 :         s->size += 4;
    2419           1 :         return GF_OK;
    2420             : }
    2421             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2422             : 
    2423             : 
    2424             : /**********************************************************
    2425             :                 TMAX GF_Box
    2426             : **********************************************************/
    2427             : 
    2428           3 : void tmax_box_del(GF_Box *s)
    2429             : {
    2430           3 :         gf_free((GF_TMAXBox *)s);
    2431           3 : }
    2432           1 : GF_Err tmax_box_read(GF_Box *s, GF_BitStream *bs)
    2433             : {
    2434             :         GF_TMAXBox *ptr = (GF_TMAXBox *)s;
    2435           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    2436           1 :         ptr->maxTime = gf_bs_read_u32(bs);
    2437           1 :         return GF_OK;
    2438             : }
    2439           3 : GF_Box *tmax_box_new()
    2440             : {
    2441           6 :         ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
    2442           3 :         return (GF_Box *)tmp;
    2443             : }
    2444             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2445           1 : GF_Err tmax_box_write(GF_Box *s, GF_BitStream *bs)
    2446             : {
    2447             :         GF_Err e;
    2448             :         GF_TMAXBox *ptr = (GF_TMAXBox *)s;
    2449           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2450           1 :         e = gf_isom_box_write_header(s, bs);
    2451           1 :         if (e) return e;
    2452           1 :         gf_bs_write_u32(bs, ptr->maxTime);
    2453           1 :         return GF_OK;
    2454             : }
    2455           1 : GF_Err tmax_box_size(GF_Box *s)
    2456             : {
    2457           1 :         s->size += 4;
    2458           1 :         return GF_OK;
    2459             : }
    2460             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2461             : 
    2462             : 
    2463             : /**********************************************************
    2464             :                 PMAX GF_Box
    2465             : **********************************************************/
    2466             : 
    2467           3 : void pmax_box_del(GF_Box *s)
    2468             : {
    2469           3 :         gf_free((GF_PMAXBox *)s);
    2470           3 : }
    2471           1 : GF_Err pmax_box_read(GF_Box *s, GF_BitStream *bs)
    2472             : {
    2473             :         GF_PMAXBox *ptr = (GF_PMAXBox *)s;
    2474           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    2475           1 :         ptr->maxSize = gf_bs_read_u32(bs);
    2476           1 :         return GF_OK;
    2477             : }
    2478           3 : GF_Box *pmax_box_new()
    2479             : {
    2480           6 :         ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
    2481           3 :         return (GF_Box *)tmp;
    2482             : }
    2483             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2484           1 : GF_Err pmax_box_write(GF_Box *s, GF_BitStream *bs)
    2485             : {
    2486             :         GF_Err e;
    2487             :         GF_PMAXBox *ptr = (GF_PMAXBox *)s;
    2488           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2489           1 :         e = gf_isom_box_write_header(s, bs);
    2490           1 :         if (e) return e;
    2491           1 :         gf_bs_write_u32(bs, ptr->maxSize);
    2492           1 :         return GF_OK;
    2493             : }
    2494           1 : GF_Err pmax_box_size(GF_Box *s)
    2495             : {
    2496           1 :         s->size += 4;
    2497           1 :         return GF_OK;
    2498             : }
    2499             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2500             : 
    2501             : 
    2502             : /**********************************************************
    2503             :                 DMAX GF_Box
    2504             : **********************************************************/
    2505             : 
    2506           3 : void dmax_box_del(GF_Box *s)
    2507             : {
    2508           3 :         gf_free((GF_DMAXBox *)s);
    2509           3 : }
    2510           1 : GF_Err dmax_box_read(GF_Box *s, GF_BitStream *bs)
    2511             : {
    2512             :         GF_DMAXBox *ptr = (GF_DMAXBox *)s;
    2513           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    2514           1 :         ptr->maxDur = gf_bs_read_u32(bs);
    2515           1 :         return GF_OK;
    2516             : }
    2517           3 : GF_Box *dmax_box_new()
    2518             : {
    2519           6 :         ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
    2520           3 :         return (GF_Box *)tmp;
    2521             : }
    2522             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2523           1 : GF_Err dmax_box_write(GF_Box *s, GF_BitStream *bs)
    2524             : {
    2525             :         GF_Err e;
    2526             :         GF_DMAXBox *ptr = (GF_DMAXBox *)s;
    2527           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2528           1 :         e = gf_isom_box_write_header(s, bs);
    2529           1 :         if (e) return e;
    2530           1 :         gf_bs_write_u32(bs, ptr->maxDur);
    2531           1 :         return GF_OK;
    2532             : }
    2533           1 : GF_Err dmax_box_size(GF_Box *s)
    2534             : {
    2535           1 :         s->size += 4;
    2536           1 :         return GF_OK;
    2537             : }
    2538             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2539             : 
    2540             : 
    2541             : /**********************************************************
    2542             :                 PAYT GF_Box
    2543             : **********************************************************/
    2544             : 
    2545           3 : void payt_box_del(GF_Box *s)
    2546             : {
    2547             :         GF_PAYTBox *payt = (GF_PAYTBox *)s;
    2548           3 :         if (payt->payloadString) gf_free(payt->payloadString);
    2549           3 :         gf_free(payt);
    2550           3 : }
    2551           1 : GF_Err payt_box_read(GF_Box *s, GF_BitStream *bs)
    2552             : {
    2553             :         u32 length;
    2554             :         GF_PAYTBox *ptr = (GF_PAYTBox *)s;
    2555             : 
    2556           1 :         ISOM_DECREASE_SIZE(ptr, 5 );
    2557           1 :         ptr->payloadCode = gf_bs_read_u32(bs);
    2558           1 :         length = gf_bs_read_u8(bs);
    2559           1 :         ISOM_DECREASE_SIZE(ptr, length);
    2560           1 :         ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) );
    2561           1 :         if (! ptr->payloadString) return GF_OUT_OF_MEM;
    2562           1 :         gf_bs_read_data(bs, ptr->payloadString, length);
    2563           1 :         ptr->payloadString[length] = 0;
    2564             : 
    2565           1 :         return GF_OK;
    2566             : }
    2567           3 : GF_Box *payt_box_new()
    2568             : {
    2569           6 :         ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
    2570           3 :         return (GF_Box *)tmp;
    2571             : }
    2572             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2573           1 : GF_Err payt_box_write(GF_Box *s, GF_BitStream *bs)
    2574             : {
    2575             :         u32 len;
    2576             :         GF_Err e;
    2577             :         GF_PAYTBox *ptr = (GF_PAYTBox *)s;
    2578           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2579           1 :         e = gf_isom_box_write_header(s, bs);
    2580           1 :         if (e) return e;
    2581           1 :         gf_bs_write_u32(bs, ptr->payloadCode);
    2582           1 :     len = ptr->payloadString ? (u32) strlen(ptr->payloadString) : 0;
    2583           1 :         gf_bs_write_u8(bs, len);
    2584           1 :         if (len) gf_bs_write_data(bs, ptr->payloadString, len);
    2585             :         return GF_OK;
    2586             : }
    2587           1 : GF_Err payt_box_size(GF_Box *s)
    2588             : {
    2589             :         GF_PAYTBox *ptr = (GF_PAYTBox *)s;
    2590           1 :         s->size += 4 + 1;
    2591           1 :         if (ptr->payloadString) ptr->size += strlen(ptr->payloadString);
    2592           1 :         return GF_OK;
    2593             : }
    2594             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2595             : 
    2596             : 
    2597             : /**********************************************************
    2598             :                 PAYT GF_Box
    2599             : **********************************************************/
    2600             : 
    2601           5 : void name_box_del(GF_Box *s)
    2602             : {
    2603             :         GF_NameBox *name = (GF_NameBox *)s;
    2604           5 :         if (name->string) gf_free(name->string);
    2605           5 :         gf_free(name);
    2606           5 : }
    2607           2 : GF_Err name_box_read(GF_Box *s, GF_BitStream *bs)
    2608             : {
    2609             :         u32 length;
    2610             :         GF_NameBox *ptr = (GF_NameBox *)s;
    2611             : 
    2612           2 :         length = (u32) (ptr->size);
    2613           2 :         ptr->string = (char*)gf_malloc(sizeof(char) * (length+1));
    2614           2 :         if (! ptr->string) return GF_OUT_OF_MEM;
    2615             : 
    2616           2 :         gf_bs_read_data(bs, ptr->string, length);
    2617           2 :         ptr->string[length] = 0;
    2618           2 :         return GF_OK;
    2619             : }
    2620           5 : GF_Box *name_box_new()
    2621             : {
    2622          10 :         ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME);
    2623           5 :         return (GF_Box *)tmp;
    2624             : }
    2625             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2626           2 : GF_Err name_box_write(GF_Box *s, GF_BitStream *bs)
    2627             : {
    2628             :         GF_Err e;
    2629             :         GF_NameBox *ptr = (GF_NameBox *)s;
    2630           2 :         if (ptr == NULL) return GF_BAD_PARAM;
    2631           2 :         e = gf_isom_box_write_header(s, bs);
    2632           2 :         if (e) return e;
    2633           2 :         if (ptr->string) {
    2634           0 :                 gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string) + 1);
    2635             :         }
    2636             :         return GF_OK;
    2637             : }
    2638           2 : GF_Err name_box_size(GF_Box *s)
    2639             : {
    2640             :         GF_NameBox *ptr = (GF_NameBox *)s;
    2641           2 :         if (ptr->string) ptr->size += strlen(ptr->string) + 1;
    2642           2 :         return GF_OK;
    2643             : }
    2644             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2645             : 
    2646             : 
    2647           3 : void tssy_box_del(GF_Box *s)
    2648             : {
    2649           3 :         gf_free(s);
    2650           3 : }
    2651           1 : GF_Err tssy_box_read(GF_Box *s, GF_BitStream *bs)
    2652             : {
    2653             :         GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
    2654           1 :         ISOM_DECREASE_SIZE(ptr, 1)
    2655           1 :         gf_bs_read_int(bs, 6);
    2656           1 :         ptr->timestamp_sync = gf_bs_read_int(bs, 2);
    2657           1 :         return GF_OK;
    2658             : }
    2659           3 : GF_Box *tssy_box_new()
    2660             : {
    2661           6 :         ISOM_DECL_BOX_ALLOC(GF_TimeStampSynchronyBox, GF_ISOM_BOX_TYPE_TSSY);
    2662           3 :         return (GF_Box *)tmp;
    2663             : }
    2664             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2665           1 : GF_Err tssy_box_write(GF_Box *s, GF_BitStream *bs)
    2666             : {
    2667             :         GF_Err e;
    2668             :         GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
    2669           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2670           1 :         e = gf_isom_box_write_header(s, bs);
    2671           1 :         if (e) return e;
    2672           1 :         gf_bs_write_int(bs, 0, 6);
    2673           1 :         gf_bs_write_int(bs, ptr->timestamp_sync, 2);
    2674           1 :         return GF_OK;
    2675             : }
    2676           1 : GF_Err tssy_box_size(GF_Box *s)
    2677             : {
    2678           1 :         s->size += 1;
    2679           1 :         return GF_OK;
    2680             : }
    2681             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2682             : 
    2683             : 
    2684           3 : void srpp_box_del(GF_Box *s)
    2685             : {
    2686           3 :         gf_free(s);
    2687           3 : }
    2688             : 
    2689           0 : GF_Err srpp_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    2690             : {
    2691             :         GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
    2692           0 :         switch(a->type) {
    2693           0 :         case GF_ISOM_BOX_TYPE_SCHI:
    2694           0 :                 BOX_FIELD_ASSIGN(info, GF_SchemeInformationBox)
    2695           0 :                 return GF_OK;
    2696           0 :         case GF_ISOM_BOX_TYPE_SCHM:
    2697           0 :                 BOX_FIELD_ASSIGN(scheme_type, GF_SchemeTypeBox)
    2698           0 :                 return GF_OK;
    2699             :         }
    2700             :         return GF_OK;
    2701             : }
    2702             : 
    2703           1 : GF_Err srpp_box_read(GF_Box *s, GF_BitStream *bs)
    2704             : {
    2705             :         GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
    2706             : 
    2707           1 :         ISOM_DECREASE_SIZE(s, 16)
    2708           1 :         ptr->encryption_algorithm_rtp = gf_bs_read_u32(bs);
    2709           1 :         ptr->encryption_algorithm_rtcp = gf_bs_read_u32(bs);
    2710           1 :         ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs);
    2711           1 :         ptr->integrity_algorithm_rtcp = gf_bs_read_u32(bs);
    2712           1 :         return gf_isom_box_array_read(s, bs);
    2713             : }
    2714           3 : GF_Box *srpp_box_new()
    2715             : {
    2716           6 :         ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP);
    2717           3 :         return (GF_Box *)tmp;
    2718             : }
    2719             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2720           1 : GF_Err srpp_box_write(GF_Box *s, GF_BitStream *bs)
    2721             : {
    2722             :         GF_Err e;
    2723             :         GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
    2724           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    2725           1 :         e = gf_isom_full_box_write(s, bs);
    2726           1 :         if (e) return e;
    2727             : 
    2728           1 :         gf_bs_write_u32(bs, ptr->encryption_algorithm_rtp);
    2729           1 :         gf_bs_write_u32(bs, ptr->encryption_algorithm_rtcp);
    2730           1 :         gf_bs_write_u32(bs, ptr->integrity_algorithm_rtp);
    2731           1 :         gf_bs_write_u32(bs, ptr->integrity_algorithm_rtcp);
    2732             : 
    2733           1 :         return GF_OK;
    2734             : }
    2735           1 : GF_Err srpp_box_size(GF_Box *s)
    2736             : {
    2737           1 :         u32 pos = 0;
    2738             :         GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
    2739           1 :         s->size += 16;
    2740           1 :         gf_isom_check_position(s, (GF_Box*)ptr->info, &pos);
    2741           1 :         gf_isom_check_position(s, (GF_Box*)ptr->scheme_type, &pos);
    2742           1 :         return GF_OK;
    2743             : }
    2744             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2745             : 
    2746             : 
    2747             : 
    2748           3 : void rssr_box_del(GF_Box *s)
    2749             : {
    2750           3 :         gf_free(s);
    2751           3 : }
    2752           1 : GF_Err rssr_box_read(GF_Box *s, GF_BitStream *bs)
    2753             : {
    2754             :         GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
    2755           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    2756           1 :         ptr->ssrc = gf_bs_read_u32(bs);
    2757           1 :         return GF_OK;
    2758             : }
    2759           3 : GF_Box *rssr_box_new()
    2760             : {
    2761           6 :         ISOM_DECL_BOX_ALLOC(GF_ReceivedSsrcBox, GF_ISOM_BOX_TYPE_RSSR);
    2762           3 :         return (GF_Box *)tmp;
    2763             : }
    2764             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2765           1 : GF_Err rssr_box_write(GF_Box *s, GF_BitStream *bs)
    2766             : {
    2767             :         GF_Err e;
    2768             :         GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
    2769           1 :         e = gf_isom_box_write_header(s, bs);
    2770           1 :         if (e) return e;
    2771           1 :         gf_bs_write_u32(bs, ptr->ssrc);
    2772           1 :         return GF_OK;
    2773             : }
    2774           1 : GF_Err rssr_box_size(GF_Box *s)
    2775             : {
    2776           1 :         s->size += 4;
    2777           1 :         return GF_OK;
    2778             : }
    2779             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2780             : 
    2781             : 
    2782             : 
    2783             : 
    2784        1316 : void iods_box_del(GF_Box *s)
    2785             : {
    2786             :         GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
    2787        1316 :         if (ptr == NULL) return;
    2788        1316 :         if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor);
    2789        1316 :         gf_free(ptr);
    2790             : }
    2791             : 
    2792             : 
    2793         804 : GF_Err iods_box_read(GF_Box *s, GF_BitStream *bs)
    2794             : {
    2795             :         GF_Err e;
    2796             :         u32 descSize;
    2797             :         char *desc;
    2798             :         GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
    2799             : 
    2800             :         //use the OD codec...
    2801         804 :         descSize = (u32) (ptr->size);
    2802         804 :         desc = (char*)gf_malloc(sizeof(char) * descSize);
    2803         804 :         if (!desc) return GF_OUT_OF_MEM;
    2804             : 
    2805         804 :         gf_bs_read_data(bs, desc, descSize);
    2806         804 :         e = gf_odf_desc_read(desc, descSize, &ptr->descriptor);
    2807             :         //OK, free our desc
    2808         804 :         gf_free(desc);
    2809         804 :         return e;
    2810             : }
    2811             : 
    2812        1316 : GF_Box *iods_box_new()
    2813             : {
    2814        2632 :         ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
    2815        1316 :         return (GF_Box *)tmp;
    2816             : }
    2817             : 
    2818             : 
    2819             : 
    2820             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2821             : 
    2822         626 : GF_Err iods_box_write(GF_Box *s, GF_BitStream *bs)
    2823             : {
    2824             :         GF_Err e;
    2825             :         u32 descSize;
    2826             :         u8 *desc;
    2827             :         GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
    2828         626 :         e = gf_isom_full_box_write(s, bs);
    2829         626 :         if (e) return e;
    2830             :         //call our OD codec
    2831         626 :         e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize);
    2832         626 :         if (e) return e;
    2833         625 :         gf_bs_write_data(bs, desc, descSize);
    2834             :         //and free our stuff maybe!!
    2835         625 :         gf_free(desc);
    2836         625 :         return GF_OK;
    2837             : }
    2838             : 
    2839        1796 : GF_Err iods_box_size(GF_Box *s)
    2840             : {
    2841             :         GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
    2842             : 
    2843        1796 :         ptr->size += gf_odf_desc_size(ptr->descriptor);
    2844        1796 :         return GF_OK;
    2845             : }
    2846             : 
    2847             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2848             : 
    2849       11322 : void mdat_box_del(GF_Box *s)
    2850             : {
    2851             :         GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
    2852       11322 :         if (!s) return;
    2853             : 
    2854       11322 :         if (ptr->data) gf_free(ptr->data);
    2855       11322 :         gf_free(ptr);
    2856             : }
    2857             : 
    2858             : 
    2859        5405 : GF_Err mdat_box_read(GF_Box *s, GF_BitStream *bs)
    2860             : {
    2861             :         GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
    2862        5405 :         if (ptr == NULL) return GF_BAD_PARAM;
    2863             : 
    2864        5405 :         ptr->dataSize = s->size;
    2865        5405 :         ptr->bsOffset = gf_bs_get_position(bs);
    2866             : 
    2867             :         //then skip these bytes
    2868        5405 :         gf_bs_skip_bytes(bs, ptr->dataSize);
    2869        5405 :         return GF_OK;
    2870             : }
    2871             : 
    2872       11322 : GF_Box *mdat_box_new()
    2873             : {
    2874       22644 :         ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
    2875       11322 :         return (GF_Box *)tmp;
    2876             : }
    2877             : 
    2878             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2879             : 
    2880        1049 : GF_Err mdat_box_write(GF_Box *s, GF_BitStream *bs)
    2881             : {
    2882             :         GF_Err e;
    2883             :         GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
    2884        1049 :         e = gf_isom_box_write_header(s, bs);
    2885        1049 :         if (e) return e;
    2886             : 
    2887             :         //make sure we have some data ...
    2888             :         //if not, we handle that independently (edit files)
    2889        1049 :         if (ptr->data) {
    2890           0 :                 gf_bs_write_data(bs, ptr->data, (u32) ptr->dataSize);
    2891             :         }
    2892             :         return GF_OK;
    2893             : }
    2894             : 
    2895        1066 : GF_Err mdat_box_size(GF_Box *s)
    2896             : {
    2897             :         GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
    2898        1066 :         ptr->size += ptr->dataSize;
    2899        1066 :         return GF_OK;
    2900             : }
    2901             : 
    2902             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    2903             : 
    2904        4126 : void mdhd_box_del(GF_Box *s)
    2905             : {
    2906             :         GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
    2907        4126 :         if (ptr == NULL) return;
    2908        4126 :         gf_free(ptr);
    2909             : }
    2910             : 
    2911        3106 : GF_Err mdhd_box_read(GF_Box *s, GF_BitStream *bs)
    2912             : {
    2913             :         GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
    2914             : 
    2915        3106 :         if (ptr->version == 1) {
    2916           0 :                 ISOM_DECREASE_SIZE(ptr, 28)
    2917           0 :                 ptr->creationTime = gf_bs_read_u64(bs);
    2918           0 :                 ptr->modificationTime = gf_bs_read_u64(bs);
    2919           0 :                 ptr->timeScale = gf_bs_read_u32(bs);
    2920           0 :                 ptr->duration = gf_bs_read_u64(bs);
    2921             :         } else {
    2922        3106 :                 ISOM_DECREASE_SIZE(ptr, 16)
    2923        3106 :                 ptr->creationTime = gf_bs_read_u32(bs);
    2924        3106 :                 ptr->modificationTime = gf_bs_read_u32(bs);
    2925        3106 :                 ptr->timeScale = gf_bs_read_u32(bs);
    2926        3106 :                 ptr->duration = gf_bs_read_u32(bs);
    2927             :         }
    2928        3106 :         if (!ptr->timeScale) {
    2929           1 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is 0 - defaulting to 90000\n" ));
    2930           1 :                 ptr->timeScale = 90000;
    2931             :         }
    2932             : 
    2933        3106 :         ptr->original_duration = ptr->duration;
    2934             : 
    2935        3106 :         ISOM_DECREASE_SIZE(ptr, 4)
    2936             :         //our padding bit
    2937        3106 :         gf_bs_read_int(bs, 1);
    2938             :         //the spec is unclear here, just says "the value 0 is interpreted as undetermined"
    2939        3106 :         ptr->packedLanguage[0] = gf_bs_read_int(bs, 5);
    2940        3106 :         ptr->packedLanguage[1] = gf_bs_read_int(bs, 5);
    2941        3106 :         ptr->packedLanguage[2] = gf_bs_read_int(bs, 5);
    2942             :         //but before or after compaction ?? We assume before
    2943        3106 :         if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) {
    2944        3094 :                 ptr->packedLanguage[0] += 0x60;
    2945        3094 :                 ptr->packedLanguage[1] += 0x60;
    2946        3094 :                 ptr->packedLanguage[2] += 0x60;
    2947             :         } else {
    2948          12 :                 ptr->packedLanguage[0] = 'u';
    2949          12 :                 ptr->packedLanguage[1] = 'n';
    2950          12 :                 ptr->packedLanguage[2] = 'd';
    2951             :         }
    2952        3106 :         ptr->reserved = gf_bs_read_u16(bs);
    2953        3106 :         return GF_OK;
    2954             : }
    2955             : 
    2956        4126 : GF_Box *mdhd_box_new()
    2957             : {
    2958        8252 :         ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);
    2959             : 
    2960        4126 :         tmp->packedLanguage[0] = 'u';
    2961        4126 :         tmp->packedLanguage[1] = 'n';
    2962        4126 :         tmp->packedLanguage[2] = 'd';
    2963        4126 :         return (GF_Box *)tmp;
    2964             : }
    2965             : 
    2966             : 
    2967             : #ifndef GPAC_DISABLE_ISOM_WRITE
    2968             : 
    2969        3176 : GF_Err mdhd_box_write(GF_Box *s, GF_BitStream *bs)
    2970             : {
    2971             :         GF_Err e;
    2972             :         GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
    2973        3176 :         e = gf_isom_full_box_write(s, bs);
    2974        3176 :         if (e) return e;
    2975        3176 :         if (ptr->version == 1) {
    2976           0 :                 gf_bs_write_u64(bs, ptr->creationTime);
    2977           0 :                 gf_bs_write_u64(bs, ptr->modificationTime);
    2978           0 :                 gf_bs_write_u32(bs, ptr->timeScale);
    2979           0 :                 gf_bs_write_u64(bs, ptr->duration);
    2980             :         } else {
    2981        3176 :                 gf_bs_write_u32(bs, (u32) ptr->creationTime);
    2982        3176 :                 gf_bs_write_u32(bs, (u32) ptr->modificationTime);
    2983        3176 :                 gf_bs_write_u32(bs, ptr->timeScale);
    2984        3176 :                 gf_bs_write_u32(bs, (u32) ptr->duration);
    2985             :         }
    2986             :         //SPECS: BIT(1) of padding
    2987        3176 :         gf_bs_write_int(bs, 0, 1);
    2988        3176 :         gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5);
    2989        3176 :         gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5);
    2990        3176 :         gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5);
    2991        3176 :         gf_bs_write_u16(bs, ptr->reserved);
    2992        3176 :         return GF_OK;
    2993             : }
    2994             : 
    2995        6125 : GF_Err mdhd_box_size(GF_Box *s)
    2996             : {
    2997             :         GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
    2998        6125 :         ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
    2999             : 
    3000        6125 :         ptr->size += 4;
    3001        6125 :         ptr->size += (ptr->version == 1) ? 28 : 16;
    3002        6125 :         return GF_OK;
    3003             : }
    3004             : 
    3005             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3006             : 
    3007             : 
    3008        4125 : void mdia_box_del(GF_Box *s)
    3009             : {
    3010             :         GF_MediaBox *ptr = (GF_MediaBox *)s;
    3011        4125 :         if (ptr == NULL) return;
    3012        4125 :         if (ptr->nalu_parser) gf_bs_del(ptr->nalu_parser);
    3013        4125 :         if (ptr->nalu_out_bs) gf_bs_del(ptr->nalu_out_bs);
    3014        4125 :         if (ptr->nalu_ps_bs) gf_bs_del(ptr->nalu_ps_bs);
    3015        4125 :         if (ptr->extracted_bs) gf_bs_del(ptr->extracted_bs);
    3016        4125 :         if (ptr->extracted_samp) gf_isom_sample_del(&ptr->extracted_samp);
    3017        4125 :         if (ptr->in_sample_buffer) gf_free(ptr->in_sample_buffer);
    3018        4125 :         if (ptr->tmp_nal_copy_buffer) gf_free(ptr->tmp_nal_copy_buffer);
    3019        4125 :         gf_free(ptr);
    3020             : }
    3021             : 
    3022             : 
    3023       12379 : GF_Err mdia_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3024             : {
    3025             :         GF_MediaBox *ptr = (GF_MediaBox *)s;
    3026       12379 :         switch(a->type) {
    3027        4116 :         case GF_ISOM_BOX_TYPE_MDHD:
    3028        4116 :                 BOX_FIELD_ASSIGN(mediaHeader, GF_MediaHeaderBox)
    3029        4116 :                 return GF_OK;
    3030             : 
    3031        4116 :         case GF_ISOM_BOX_TYPE_HDLR:
    3032        4116 :                 BOX_FIELD_ASSIGN(handler, GF_HandlerBox)
    3033        4116 :                 return GF_OK;
    3034             : 
    3035        4116 :         case GF_ISOM_BOX_TYPE_MINF:
    3036        4116 :                 BOX_FIELD_ASSIGN(information, GF_MediaInformationBox)
    3037        4116 :                 return GF_OK;
    3038             :         }
    3039             :         return GF_OK;
    3040             : }
    3041             : 
    3042             : 
    3043        3106 : GF_Err mdia_box_read(GF_Box *s, GF_BitStream *bs)
    3044             : {
    3045             :         GF_Err e;
    3046        3106 :         u64 cookie = gf_bs_get_cookie(bs);
    3047        3106 :         cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
    3048        3106 :         gf_bs_set_cookie(bs, cookie);
    3049        3106 :         e = gf_isom_box_array_read(s, bs);
    3050        3106 :         gf_bs_set_cookie(bs, cookie);
    3051             : 
    3052        3106 :         if (e) return e;
    3053        3106 :         if (!((GF_MediaBox *)s)->information) {
    3054           1 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaInformationBox\n"));
    3055             :                 return GF_ISOM_INVALID_FILE;
    3056             :         }
    3057        3105 :         if (!((GF_MediaBox *)s)->handler) {
    3058           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing HandlerBox\n"));
    3059             :                 return GF_ISOM_INVALID_FILE;
    3060             :         }
    3061        3105 :         if (!((GF_MediaBox *)s)->mediaHeader) {
    3062           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaHeaderBox\n"));
    3063             :                 return GF_ISOM_INVALID_FILE;
    3064             :         }
    3065             :         return GF_OK;
    3066             : }
    3067             : 
    3068        4125 : GF_Box *mdia_box_new()
    3069             : {
    3070        8250 :         ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
    3071        4125 :         return (GF_Box *)tmp;
    3072             : }
    3073             : 
    3074             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3075             : 
    3076        3176 : GF_Err mdia_box_write(GF_Box *s, GF_BitStream *bs)
    3077             : {
    3078        3176 :         return gf_isom_box_write_header(s, bs);
    3079             : }
    3080             : 
    3081        6125 : GF_Err mdia_box_size(GF_Box *s)
    3082             : {
    3083        6125 :         u32 pos = 0;
    3084             :         GF_MediaBox *ptr = (GF_MediaBox *)s;
    3085             :         //Header first
    3086        6125 :         gf_isom_check_position(s, (GF_Box*)ptr->mediaHeader, &pos);
    3087             :         //then handler
    3088        6125 :         gf_isom_check_position(s, (GF_Box*)ptr->handler, &pos);
    3089             : 
    3090             : #if 0
    3091             :         //elng before info for CMAF info - we deactiveate for now, no specific errors raised and CMAF should not impose any order
    3092             :         GF_Box *elng = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ELNG);
    3093             :         if (elng)
    3094             :                 gf_isom_check_position(s, elng, &pos);
    3095             : #endif
    3096             : 
    3097             :         //then info
    3098        6125 :         gf_isom_check_position(s, (GF_Box*)ptr->information, &pos);
    3099        6125 :         return GF_OK;
    3100             : }
    3101             : 
    3102             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3103             : 
    3104           7 : void mfra_box_del(GF_Box *s)
    3105             : {
    3106             :         GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
    3107           7 :         if (ptr == NULL) return;
    3108           7 :         gf_list_del(ptr->tfra_list);
    3109           7 :         gf_free(ptr);
    3110             : }
    3111             : 
    3112           7 : GF_Box *mfra_box_new()
    3113             : {
    3114          14 :         ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA);
    3115           7 :         tmp->tfra_list = gf_list_new();
    3116           7 :         return (GF_Box *)tmp;
    3117             : }
    3118             : 
    3119          12 : GF_Err mfra_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3120             : {
    3121             :         GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
    3122          12 :         switch(a->type) {
    3123           9 :         case GF_ISOM_BOX_TYPE_TFRA:
    3124           9 :                 BOX_FIELD_LIST_ASSIGN(tfra_list);
    3125             :                 return GF_OK;
    3126           3 :         case GF_ISOM_BOX_TYPE_MFRO:
    3127           3 :                 BOX_FIELD_ASSIGN(mfro, GF_MovieFragmentRandomAccessOffsetBox)
    3128           3 :                 return GF_OK;
    3129             :         }
    3130             :         return GF_OK;
    3131             : }
    3132             : 
    3133           4 : GF_Err mfra_box_read(GF_Box *s, GF_BitStream *bs)
    3134             : {
    3135           4 :         return gf_isom_box_array_read(s, bs);
    3136             : }
    3137             : 
    3138             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3139             : 
    3140           2 : GF_Err mfra_box_write(GF_Box *s, GF_BitStream *bs)
    3141             : {
    3142           2 :         return gf_isom_box_write_header(s, bs);
    3143             : }
    3144             : 
    3145           2 : GF_Err mfra_box_size(GF_Box *s)
    3146             : {
    3147           2 :         u32 pos=0;
    3148             :         GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
    3149           2 :         gf_isom_check_position_list(s, ptr->tfra_list, &pos);
    3150           2 :         gf_isom_check_position(s, (GF_Box *)ptr->mfro, &pos);
    3151           2 :         return GF_OK;
    3152             : }
    3153             : 
    3154             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3155             : 
    3156             : 
    3157          16 : void tfra_box_del(GF_Box *s)
    3158             : {
    3159             :         GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
    3160          16 :         if (ptr == NULL) return;
    3161          16 :         if (ptr->entries) gf_free(ptr->entries);
    3162          16 :         gf_free(ptr);
    3163             : }
    3164             : 
    3165          16 : GF_Box *tfra_box_new()
    3166             : {
    3167          32 :         ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA);
    3168          16 :         return (GF_Box *)tmp;
    3169             : }
    3170             : 
    3171          10 : GF_Err tfra_box_read(GF_Box *s, GF_BitStream *bs)
    3172             : {
    3173             :         u32 i;
    3174             :         GF_RandomAccessEntry *p = 0;
    3175             :         GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
    3176             : 
    3177          10 :         ISOM_DECREASE_SIZE(ptr, 12);
    3178             : 
    3179          10 :         ptr->track_id = gf_bs_read_u32(bs);
    3180          10 :         if (gf_bs_read_int(bs, 26) != 0)
    3181             :                 return GF_ISOM_INVALID_FILE;
    3182             : 
    3183          10 :         ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
    3184          10 :         ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
    3185          10 :         ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
    3186             : 
    3187          10 :         ptr->nb_entries = gf_bs_read_u32(bs);
    3188             : 
    3189          10 :         if (ptr->version == 1) {
    3190           0 :                 if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
    3191           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
    3192             :                         return GF_ISOM_INVALID_FILE;
    3193             :                 }
    3194             :         } else {
    3195          10 :                 if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
    3196           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
    3197             :                         return GF_ISOM_INVALID_FILE;
    3198             :                 }
    3199             :         }
    3200             : 
    3201          10 :         if (ptr->nb_entries) {
    3202           9 :                 p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
    3203           9 :                 if (!p) return GF_OUT_OF_MEM;
    3204             :         }
    3205             : 
    3206          10 :         ptr->entries = p;
    3207             : 
    3208          19 :         for (i=0; i<ptr->nb_entries; i++) {
    3209             :                 memset(p, 0, sizeof(GF_RandomAccessEntry));
    3210             : 
    3211           9 :                 if (ptr->version == 1) {
    3212           0 :                         p->time = gf_bs_read_u64(bs);
    3213           0 :                         p->moof_offset = gf_bs_read_u64(bs);
    3214             :                 } else {
    3215           9 :                         p->time = gf_bs_read_u32(bs);
    3216           9 :                         p->moof_offset = gf_bs_read_u32(bs);
    3217             :                 }
    3218           9 :                 p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
    3219           9 :                 p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
    3220           9 :                 p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);
    3221             : 
    3222           9 :                 ++p;
    3223             :         }
    3224             : 
    3225             :         return GF_OK;
    3226             : }
    3227             : 
    3228             : 
    3229             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3230             : 
    3231           4 : GF_Err tfra_box_write(GF_Box *s, GF_BitStream *bs)
    3232             : {
    3233             :         GF_Err e;
    3234             :         u32 i, sap_nb_entries;
    3235             :         GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
    3236             : 
    3237           4 :         e = gf_isom_full_box_write(s, bs);
    3238           4 :         if (e) return e;
    3239             : 
    3240           4 :         gf_bs_write_u32(bs, ptr->track_id);
    3241           4 :         gf_bs_write_int(bs, 0, 26);
    3242             : 
    3243           4 :         gf_bs_write_int(bs, ptr->traf_bits/8 - 1, 2);
    3244           4 :         gf_bs_write_int(bs, ptr->trun_bits/8 - 1, 2);
    3245           4 :         gf_bs_write_int(bs, ptr->sample_bits/8 - 1, 2);
    3246             : 
    3247             :         sap_nb_entries = 0;
    3248          28 :         for (i=0; i<ptr->nb_entries; i++) {
    3249          24 :                 GF_RandomAccessEntry *p = &ptr->entries[i];
    3250             :                 //no sap found, do not store
    3251          24 :                 if (p->trun_number) sap_nb_entries++;
    3252             :         }
    3253             : 
    3254           4 :         gf_bs_write_u32(bs, sap_nb_entries);
    3255             : 
    3256          28 :         for (i=0; i<ptr->nb_entries; i++) {
    3257          24 :                 GF_RandomAccessEntry *p = &ptr->entries[i];
    3258             :                 //no sap found, do not store
    3259          24 :                 if (!p->trun_number) continue;
    3260          18 :                 if (ptr->version==1) {
    3261           0 :                         gf_bs_write_u64(bs, p->time);
    3262           0 :                         gf_bs_write_u64(bs, p->moof_offset);
    3263             :                 } else {
    3264          18 :                         gf_bs_write_u32(bs, (u32) p->time);
    3265          18 :                         gf_bs_write_u32(bs, (u32) p->moof_offset);
    3266             :                 }
    3267          18 :                 gf_bs_write_int(bs, p->traf_number, ptr->traf_bits);
    3268          18 :                 gf_bs_write_int(bs, p->trun_number, ptr->trun_bits);
    3269          18 :                 gf_bs_write_int(bs, p->sample_number, ptr->sample_bits);
    3270             :         }
    3271             :         return GF_OK;
    3272             : }
    3273             : 
    3274           4 : GF_Err tfra_box_size(GF_Box *s)
    3275             : {
    3276             :         u32 i;
    3277             :         GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
    3278           4 :         ptr->size += 12;
    3279             : 
    3280          28 :         for (i=0; i<ptr->nb_entries; i++) {
    3281          24 :                 GF_RandomAccessEntry *p = &ptr->entries[i];
    3282             :                 //no sap found, do not store
    3283          24 :                 if (!p->trun_number) continue;
    3284          18 :                 ptr->size +=  ((ptr->version==1) ? 16 : 8 ) + ptr->traf_bits/8 + ptr->trun_bits/8 + ptr->sample_bits/8;
    3285             :         }
    3286           4 :         return GF_OK;
    3287             : }
    3288             : 
    3289             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3290             : 
    3291             : 
    3292             : 
    3293           7 : void mfro_box_del(GF_Box *s)
    3294             : {
    3295             :         GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
    3296           7 :         if (ptr == NULL) return;
    3297           7 :         gf_free(ptr);
    3298             : }
    3299             : 
    3300           7 : GF_Box *mfro_box_new()
    3301             : {
    3302          14 :         ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessOffsetBox, GF_ISOM_BOX_TYPE_MFRO);
    3303           7 :         return (GF_Box *)tmp;
    3304             : }
    3305             : 
    3306           4 : GF_Err mfro_box_read(GF_Box *s, GF_BitStream *bs)
    3307             : {
    3308             :         GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
    3309             : 
    3310           4 :         ISOM_DECREASE_SIZE(ptr, 4);
    3311           4 :         ptr->container_size = gf_bs_read_u32(bs);
    3312           4 :         return GF_OK;
    3313             : }
    3314             : 
    3315             : 
    3316             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3317             : 
    3318           2 : GF_Err mfro_box_write(GF_Box *s, GF_BitStream *bs)
    3319             : {
    3320             :         GF_Err e;
    3321             :         GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
    3322             : 
    3323           2 :         e = gf_isom_full_box_write(s, bs);
    3324           2 :         if (e) return e;
    3325             : 
    3326           2 :         gf_bs_write_u32(bs, ptr->container_size);
    3327           2 :         return GF_OK;
    3328             : }
    3329             : 
    3330           2 : GF_Err mfro_box_size(GF_Box *s)
    3331             : {
    3332           2 :         s->size += 4;
    3333           2 :         return GF_OK;
    3334             : }
    3335             : 
    3336             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3337             : 
    3338             : 
    3339          44 : void elng_box_del(GF_Box *s)
    3340             : {
    3341             :         GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
    3342          44 :         if (ptr == NULL) return;
    3343          44 :         if (ptr->extended_language) gf_free(ptr->extended_language);
    3344          44 :         gf_free(ptr);
    3345             : }
    3346             : 
    3347          32 : GF_Err elng_box_read(GF_Box *s, GF_BitStream *bs)
    3348             : {
    3349             :         GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
    3350             : 
    3351          32 :         if (ptr->size) {
    3352          31 :                 ptr->extended_language = (char*)gf_malloc((u32) ptr->size);
    3353          31 :                 if (ptr->extended_language == NULL) return GF_OUT_OF_MEM;
    3354          31 :                 gf_bs_read_data(bs, ptr->extended_language, (u32) ptr->size);
    3355             :                 /*safety check in case the string is not null-terminated*/
    3356          31 :                 if (ptr->extended_language[ptr->size-1]) {
    3357           0 :                         char *str = (char*)gf_malloc((u32) ptr->size + 1);
    3358           0 :                         if (!str) return GF_OUT_OF_MEM;
    3359           0 :                         memcpy(str, ptr->extended_language, (u32) ptr->size);
    3360           0 :                         str[ptr->size] = 0;
    3361           0 :                         gf_free(ptr->extended_language);
    3362           0 :                         ptr->extended_language = str;
    3363             :                 }
    3364             :         }
    3365             :         return GF_OK;
    3366             : }
    3367             : 
    3368          44 : GF_Box *elng_box_new()
    3369             : {
    3370          88 :         ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG);
    3371          44 :         return (GF_Box *)tmp;
    3372             : }
    3373             : 
    3374             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3375             : 
    3376          16 : GF_Err elng_box_write(GF_Box *s, GF_BitStream *bs)
    3377             : {
    3378             :         GF_Err e;
    3379             :         GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
    3380          16 :         e = gf_isom_full_box_write(s, bs);
    3381          16 :         if (e) return e;
    3382          16 :         if (ptr->extended_language) {
    3383          15 :                 gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language)+1));
    3384             :         }
    3385             :         return GF_OK;
    3386             : }
    3387             : 
    3388          42 : GF_Err elng_box_size(GF_Box *s)
    3389             : {
    3390             :         GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
    3391             : 
    3392          42 :         if (ptr->extended_language) {
    3393          41 :                 ptr->size += strlen(ptr->extended_language)+1;
    3394             :         }
    3395          42 :         return GF_OK;
    3396             : }
    3397             : 
    3398             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3399             : 
    3400             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    3401             : 
    3402        7675 : void mfhd_box_del(GF_Box *s)
    3403             : {
    3404             :         GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
    3405        7675 :         if (ptr == NULL) return;
    3406        7675 :         gf_free(ptr);
    3407             : }
    3408             : 
    3409        4102 : GF_Err mfhd_box_read(GF_Box *s, GF_BitStream *bs)
    3410             : {
    3411             :         GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
    3412        4102 :         ISOM_DECREASE_SIZE(ptr, 4);
    3413        4102 :         ptr->sequence_number = gf_bs_read_u32(bs);
    3414        4102 :         return GF_OK;
    3415             : }
    3416             : 
    3417        7675 : GF_Box *mfhd_box_new()
    3418             : {
    3419       15350 :         ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
    3420        7675 :         return (GF_Box *)tmp;
    3421             : }
    3422             : 
    3423             : 
    3424             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3425             : 
    3426             : 
    3427        3746 : GF_Err mfhd_box_write(GF_Box *s, GF_BitStream *bs)
    3428             : {
    3429             :         GF_Err e;
    3430             :         GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *) s;
    3431        3746 :         if (!s) return GF_BAD_PARAM;
    3432             : 
    3433        3746 :         e = gf_isom_full_box_write(s, bs);
    3434        3746 :         if (e) return e;
    3435        3746 :         gf_bs_write_u32(bs, ptr->sequence_number);
    3436        3746 :         return GF_OK;
    3437             : }
    3438             : 
    3439       10776 : GF_Err mfhd_box_size(GF_Box *s)
    3440             : {
    3441       10776 :         s->size += 4;
    3442       10776 :         return GF_OK;
    3443             : }
    3444             : 
    3445             : 
    3446             : 
    3447             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3448             : 
    3449             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    3450             : 
    3451             : 
    3452        4125 : void minf_box_del(GF_Box *s)
    3453             : {
    3454             :         GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
    3455        4125 :         if (ptr == NULL) return;
    3456             : 
    3457             :         //if we have a Handler not self-contained, delete it (the self-contained belongs to the movie)
    3458        4125 :         if (ptr->dataHandler) {
    3459        2668 :                 gf_isom_datamap_close(ptr);
    3460             :         }
    3461        4125 :         gf_free(ptr);
    3462             : }
    3463             : 
    3464       12469 : GF_Err minf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3465             : {
    3466             :         GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
    3467       12469 :         switch (a->type) {
    3468        4110 :         case GF_ISOM_BOX_TYPE_NMHD:
    3469             :         case GF_ISOM_BOX_TYPE_STHD:
    3470             :         case GF_ISOM_BOX_TYPE_VMHD:
    3471             :         case GF_ISOM_BOX_TYPE_SMHD:
    3472             :         case GF_ISOM_BOX_TYPE_HMHD:
    3473             :         case GF_ISOM_BOX_TYPE_GMHD:
    3474        4110 :                 BOX_FIELD_ASSIGN(InfoHeader, GF_Box)
    3475        4110 :                 return GF_OK;
    3476             : 
    3477        4110 :         case GF_ISOM_BOX_TYPE_DINF:
    3478        4110 :                 BOX_FIELD_ASSIGN(dataInformation, GF_DataInformationBox)
    3479        4110 :                 return GF_OK;
    3480             : 
    3481        4116 :         case GF_ISOM_BOX_TYPE_STBL:
    3482        4116 :                 BOX_FIELD_ASSIGN(sampleTable, GF_SampleTableBox)
    3483        4116 :                 return GF_OK;
    3484             :         }
    3485             :         return GF_OK;
    3486             : }
    3487             : 
    3488             : 
    3489        3106 : GF_Err minf_box_read(GF_Box *s, GF_BitStream *bs)
    3490             : {
    3491             :         GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
    3492             :         GF_Err e;
    3493             : 
    3494        3106 :         e = gf_isom_box_array_read(s, bs);
    3495             : 
    3496        3106 :         if (!e && ! ptr->dataInformation) {
    3497             :                 GF_Box *url;
    3498           7 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing DataInformationBox\n"));
    3499             :                 //commented on purpose, we are still able to handle the file, we only throw an error but keep processing
    3500             : //              e = GF_ISOM_INVALID_FILE;
    3501             : 
    3502             :                 //add a dinf box to avoid any access to a null dinf
    3503           7 :                 ptr->dataInformation = (GF_DataInformationBox *) gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DINF);
    3504           7 :                 if (!ptr->dataInformation) return GF_OUT_OF_MEM;
    3505             : 
    3506           7 :                 ptr->dataInformation->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&ptr->dataInformation->child_boxes, GF_ISOM_BOX_TYPE_DREF);
    3507           7 :                 if (!ptr->dataInformation->dref) return GF_OUT_OF_MEM;
    3508             : 
    3509           7 :                 url = gf_isom_box_new_parent(&ptr->dataInformation->dref->child_boxes, GF_ISOM_BOX_TYPE_URL);
    3510           7 :                 if (!url) return GF_OUT_OF_MEM;
    3511           7 :                 ((GF_FullBox*)url)->flags = 1;
    3512             :         }
    3513             :         return e;
    3514             : }
    3515             : 
    3516        4125 : GF_Box *minf_box_new()
    3517             : {
    3518        8250 :         ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
    3519        4125 :         return (GF_Box *)tmp;
    3520             : }
    3521             : 
    3522             : 
    3523             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3524             : 
    3525        3176 : GF_Err minf_box_write(GF_Box *s, GF_BitStream *bs)
    3526             : {
    3527        3176 :         return gf_isom_box_write_header(s, bs);
    3528             : }
    3529             : 
    3530        6125 : GF_Err minf_box_size(GF_Box *s)
    3531             : {
    3532        6125 :         u32 pos=0;
    3533             :         GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
    3534             :         //Header first
    3535        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->InfoHeader, &pos);
    3536             :         //then dataInfo
    3537        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->dataInformation, &pos);
    3538        6125 :         gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_MVCI), &pos);
    3539             :         //then sampleTable
    3540        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->sampleTable, &pos);
    3541        6125 :         return GF_OK;
    3542             : }
    3543             : 
    3544             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3545             : 
    3546             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    3547             : 
    3548        7736 : void moof_box_del(GF_Box *s)
    3549             : {
    3550             :         GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
    3551        7736 :         if (ptr == NULL) return;
    3552             : 
    3553        7736 :         gf_list_del(ptr->TrackList);
    3554        7736 :         if (ptr->PSSHs) gf_list_del(ptr->PSSHs);
    3555        7736 :         if (ptr->mdat) gf_free(ptr->mdat);
    3556        7736 :         gf_free(ptr);
    3557             : }
    3558             : 
    3559        8343 : GF_Err moof_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3560             : {
    3561             :         GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
    3562        8343 :         switch (a->type) {
    3563        4101 :         case GF_ISOM_BOX_TYPE_MFHD:
    3564        4101 :                 BOX_FIELD_ASSIGN(mfhd, GF_MovieFragmentHeaderBox)
    3565        4101 :                 return GF_OK;
    3566        4242 :         case GF_ISOM_BOX_TYPE_TRAF:
    3567        4242 :                 BOX_FIELD_LIST_ASSIGN(TrackList)
    3568             :                 return GF_OK;
    3569           0 :         case GF_ISOM_BOX_TYPE_PSSH:
    3570           0 :                 BOX_FIELD_LIST_ASSIGN(PSSHs)
    3571             :                 return GF_OK;
    3572             :         }
    3573             :         return GF_OK;
    3574             : }
    3575             : 
    3576        4102 : GF_Err moof_box_read(GF_Box *s, GF_BitStream *bs)
    3577             : {
    3578        4102 :         return gf_isom_box_array_read(s, bs);
    3579             : }
    3580             : 
    3581        7736 : GF_Box *moof_box_new()
    3582             : {
    3583       15472 :         ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
    3584        7736 :         tmp->TrackList = gf_list_new();
    3585        7736 :         return (GF_Box *)tmp;
    3586             : }
    3587             : 
    3588             : 
    3589             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3590             : 
    3591        3746 : GF_Err moof_box_write(GF_Box *s, GF_BitStream *bs)
    3592             : {
    3593        3746 :         return gf_isom_box_write_header(s, bs);
    3594             : }
    3595             : 
    3596       10774 : GF_Err moof_box_size(GF_Box *s)
    3597             : {
    3598       10774 :         u32 pos=0;
    3599             :         GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *) s;
    3600       10774 :         if (!s) return GF_BAD_PARAM;
    3601             :         //Header First
    3602       10774 :         gf_isom_check_position(s, (GF_Box *)ptr->mfhd, &pos);
    3603             :         //then PSSH
    3604       10774 :         gf_isom_check_position_list(s, ptr->PSSHs, &pos);
    3605             :         //then the track list
    3606       10774 :         gf_isom_check_position_list(s, ptr->TrackList, &pos);
    3607       10774 :         return GF_OK;
    3608             : }
    3609             : 
    3610             : 
    3611             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3612             : 
    3613             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    3614             : 
    3615        2989 : void moov_box_del(GF_Box *s)
    3616             : {
    3617             :         GF_MovieBox *ptr = (GF_MovieBox *)s;
    3618        2989 :         if (ptr == NULL) return;
    3619        2989 :         gf_list_del(ptr->trackList);
    3620        2989 :         gf_free(ptr);
    3621             : }
    3622             : 
    3623        9509 : GF_Err moov_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3624             : {
    3625             :         GF_MovieBox *ptr = (GF_MovieBox *)s;
    3626        9509 :         switch (a->type) {
    3627        1314 :         case GF_ISOM_BOX_TYPE_IODS:
    3628        1314 :                 BOX_FIELD_ASSIGN(iods, GF_ObjectDescriptorBox)
    3629             :                 //if no IOD, delete the box
    3630        1314 :                 if (ptr->iods && !ptr->iods->descriptor) {
    3631           0 :                         ptr->iods = NULL;
    3632           0 :                         gf_isom_box_del_parent(&s->child_boxes, a);
    3633             :                 }
    3634             :                 return GF_OK;
    3635             : 
    3636        2951 :         case GF_ISOM_BOX_TYPE_MVHD:
    3637        2951 :                 BOX_FIELD_ASSIGN(mvhd, GF_MovieHeaderBox)
    3638        2951 :                 return GF_OK;
    3639             : 
    3640         142 :         case GF_ISOM_BOX_TYPE_UDTA:
    3641         142 :                 BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
    3642         142 :                 return GF_OK;
    3643             : 
    3644             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    3645         593 :         case GF_ISOM_BOX_TYPE_MVEX:
    3646         593 :                 BOX_FIELD_ASSIGN(mvex, GF_MovieExtendsBox)
    3647             :                 if (ptr->mvex)
    3648         593 :                         ptr->mvex->mov = ptr->mov;
    3649         593 :                 return GF_OK;
    3650             : #endif
    3651             : 
    3652           0 :         case GF_ISOM_BOX_TYPE_META:
    3653           0 :                 BOX_FIELD_ASSIGN(meta, GF_MetaBox)
    3654           0 :                 return GF_OK;
    3655             : 
    3656        4116 :         case GF_ISOM_BOX_TYPE_TRAK:
    3657        4116 :                 if (is_rem) {
    3658           0 :                         gf_list_del_item(ptr->trackList, a);
    3659           0 :                         return GF_OK;
    3660             :                 }
    3661             :                 //set our pointer to this obj
    3662        4116 :                 ((GF_TrackBox *)a)->moov = ptr;
    3663        4116 :                 ((GF_TrackBox *)a)->index = gf_list_count(ptr->trackList);
    3664        4116 :                 return gf_list_add(ptr->trackList, a);
    3665             :         }
    3666             :         return GF_OK;
    3667             : }
    3668             : 
    3669             : 
    3670        1666 : GF_Err moov_box_read(GF_Box *s, GF_BitStream *bs)
    3671             : {
    3672        1666 :         return gf_isom_box_array_read(s, bs);
    3673             : }
    3674             : 
    3675        2989 : GF_Box *moov_box_new()
    3676             : {
    3677        5978 :         ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
    3678        2989 :         tmp->trackList = gf_list_new();
    3679        2989 :         if (!tmp->trackList) {
    3680           0 :                 gf_free(tmp);
    3681           0 :                 return NULL;
    3682             :         }
    3683             :         return (GF_Box *)tmp;
    3684             : }
    3685             : 
    3686             : 
    3687             : 
    3688             : #ifndef GPAC_DISABLE_ISOM_WRITE
    3689             : 
    3690             : 
    3691        1373 : GF_Err moov_box_write(GF_Box *s, GF_BitStream *bs)
    3692             : {
    3693        1373 :         return gf_isom_box_write_header(s, bs);
    3694             : }
    3695             : 
    3696        3377 : GF_Err moov_box_size(GF_Box *s)
    3697             : {
    3698        3377 :         u32 pos=0;
    3699             :         GF_MovieBox *ptr = (GF_MovieBox *)s;
    3700             : 
    3701        3377 :         gf_isom_check_position(s, (GF_Box *) ptr->mvhd, &pos);
    3702        3377 :         gf_isom_check_position(s, (GF_Box *) ptr->iods, &pos);
    3703        3377 :         gf_isom_check_position(s, (GF_Box *) ptr->meta, &pos);
    3704             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    3705        3377 :         if (ptr->mvex && !ptr->mvex_after_traks) {
    3706         346 :                 gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
    3707             :         }
    3708             : #endif
    3709        3377 :         gf_isom_check_position_list(s, ptr->trackList, &pos);
    3710             : 
    3711             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    3712        3377 :         if (ptr->mvex && ptr->mvex_after_traks) {
    3713           0 :                 gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
    3714             :         }
    3715             : #endif
    3716        3377 :         return GF_OK;
    3717             : }
    3718             : 
    3719             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    3720             : 
    3721        1298 : void audio_sample_entry_box_del(GF_Box *s)
    3722             : {
    3723             :         GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
    3724        1298 :         if (ptr == NULL) return;
    3725        1298 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    3726        1298 :         if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
    3727        1298 :         gf_free(ptr);
    3728             : }
    3729             : 
    3730        1336 : GF_Err audio_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    3731             : {
    3732             :         GF_UnknownBox *wave = NULL;
    3733             :         Bool drop_wave=GF_FALSE;
    3734             :         GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
    3735             : 
    3736        1336 :         switch (a->type) {
    3737         679 :         case GF_ISOM_BOX_TYPE_ESDS:
    3738         679 :                 BOX_FIELD_ASSIGN(esd, GF_ESDBox)
    3739         679 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3740         679 :                 break;
    3741             : 
    3742          31 :         case GF_ISOM_BOX_TYPE_DAMR:
    3743             :         case GF_ISOM_BOX_TYPE_DEVC:
    3744             :         case GF_ISOM_BOX_TYPE_DQCP:
    3745             :         case GF_ISOM_BOX_TYPE_DSMV:
    3746          31 :                 BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
    3747             :                 /*for 3GP config, remember sample entry type in config*/
    3748          31 :                 ptr->cfg_3gpp->cfg.type = ptr->type;
    3749          31 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3750          31 :                 break;
    3751             : 
    3752           5 :         case GF_ISOM_BOX_TYPE_DOPS:
    3753           5 :                 BOX_FIELD_ASSIGN(cfg_opus, GF_OpusSpecificBox)
    3754           5 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3755           5 :                 break;
    3756          15 :         case GF_ISOM_BOX_TYPE_DAC3:
    3757          15 :                 BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
    3758          15 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3759          15 :                 break;
    3760           5 :         case GF_ISOM_BOX_TYPE_DEC3:
    3761           5 :                 BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
    3762           5 :                 break;
    3763           5 :         case GF_ISOM_BOX_TYPE_DMLP:
    3764           5 :                 BOX_FIELD_ASSIGN(cfg_mlp, GF_TrueHDConfigBox)
    3765           5 :                 break;
    3766           0 :         case GF_ISOM_BOX_TYPE_MHAC:
    3767           0 :                 BOX_FIELD_ASSIGN(cfg_mha, GF_MHAConfigBox)
    3768           0 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3769           0 :                 break;
    3770           5 :         case GF_ISOM_BOX_TYPE_DFLA:
    3771           5 :                 BOX_FIELD_ASSIGN(cfg_flac, GF_FLACConfigBox)
    3772           5 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3773           5 :                 break;
    3774             : 
    3775           0 :         case GF_ISOM_BOX_TYPE_UNKNOWN:
    3776             :                 wave = (GF_UnknownBox *)a;
    3777             :                 /*HACK for QT files: get the esds box from the track*/
    3778           0 :                 if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
    3779           0 :                         if (is_rem) {
    3780             :                                 return GF_OK;
    3781             :                         }
    3782           0 :                         if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
    3783             :                         //wave subboxes may have been properly parsed
    3784           0 :                         if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
    3785             :                                 u32 i;
    3786           0 :                 for (i =0; i<gf_list_count(wave->child_boxes); i++) {
    3787           0 :                     GF_Box *inner_box = (GF_Box *)gf_list_get(wave->child_boxes, i);
    3788           0 :                     if (inner_box->type == GF_ISOM_BOX_TYPE_ESDS) {
    3789           0 :                         ptr->esd = (GF_ESDBox *)inner_box;
    3790           0 :                                                 if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
    3791           0 :                                 gf_list_rem(a->child_boxes, i);
    3792             :                                 drop_wave=GF_TRUE;
    3793           0 :                                 ptr->compression_id = 0;
    3794           0 :                                 gf_list_add(ptr->child_boxes, inner_box);
    3795             :                                                 }
    3796             :                     }
    3797             :                 }
    3798           0 :                                 if (drop_wave) {
    3799           0 :                                         gf_isom_box_del_parent(&ptr->child_boxes, a);
    3800           0 :                         ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3801           0 :                                         ptr->version = 0;
    3802           0 :                                         return GF_OK;
    3803             :                                 }
    3804           0 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
    3805           0 :                 return GF_OK;
    3806             :             }
    3807           0 :             gf_isom_box_del_parent(&ptr->child_boxes, a);
    3808           0 :             return GF_ISOM_INVALID_MEDIA;
    3809             : 
    3810             :                 }
    3811           0 :                 ptr->qtff_mode &= ~GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;
    3812             : 
    3813           0 :                 if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
    3814           0 :                         ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;
    3815             :                 }
    3816             :                 return GF_OK;
    3817          89 :         case GF_QT_BOX_TYPE_WAVE:
    3818             :         {
    3819             :                 u32 subtype = 0;
    3820             :                 GF_Box **cfg_ptr = NULL;
    3821          89 :                 if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
    3822           1 :                         cfg_ptr = (GF_Box **) &ptr->esd;
    3823             :                         subtype = GF_ISOM_BOX_TYPE_ESDS;
    3824             :                 }
    3825          88 :                 else if (s->type == GF_ISOM_BOX_TYPE_AC3) {
    3826           0 :                         cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
    3827             :                         subtype = GF_ISOM_BOX_TYPE_DAC3;
    3828             :                 }
    3829          88 :                 else if (s->type == GF_ISOM_BOX_TYPE_EC3) {
    3830           0 :                         cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
    3831             :                         subtype = GF_ISOM_BOX_TYPE_DEC3;
    3832             :                 }
    3833          88 :                 else if (s->type == GF_ISOM_BOX_TYPE_OPUS) {
    3834           0 :                         cfg_ptr = (GF_Box **) &ptr->cfg_opus;
    3835             :                         subtype = GF_ISOM_BOX_TYPE_DOPS;
    3836             :                 }
    3837          88 :                 else if ((s->type == GF_ISOM_BOX_TYPE_MHA1)
    3838             :                         || (s->type == GF_ISOM_BOX_TYPE_MHA2)
    3839          88 :                         || (s->type == GF_ISOM_BOX_TYPE_MHM1)
    3840          88 :                         || (s->type == GF_ISOM_BOX_TYPE_MHM2)
    3841             :                 ) {
    3842           0 :                         cfg_ptr = (GF_Box **) &ptr->cfg_mha;
    3843           0 :                         subtype = GF_ISOM_BOX_TYPE_MHAC;
    3844             :                 }
    3845          88 :                 else if (s->type == GF_ISOM_BOX_TYPE_MLPA) {
    3846           0 :                         cfg_ptr = (GF_Box **) &ptr->cfg_mlp;
    3847             :                         subtype = GF_ISOM_BOX_TYPE_DMLP;
    3848             :                 }
    3849             : 
    3850             :                 if (cfg_ptr) {
    3851           1 :                         if (is_rem) {
    3852           0 :                                 *cfg_ptr = NULL;
    3853           0 :                                 return GF_OK;
    3854             :                         }
    3855           1 :                         if (*cfg_ptr) ERROR_ON_DUPLICATED_BOX(a, ptr)
    3856             : 
    3857             :                         //wave subboxes may have been properly parsed
    3858           1 :                         if (gf_list_count(a->child_boxes)) {
    3859             :                                 u32 i;
    3860           1 :                 for (i =0; i<gf_list_count(a->child_boxes); i++) {
    3861           2 :                     GF_Box *inner_box = (GF_Box *)gf_list_get(a->child_boxes, i);
    3862           2 :                     if (inner_box->type == subtype) {
    3863           1 :                         *cfg_ptr = inner_box;
    3864           1 :                                                 if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
    3865           0 :                                 gf_list_rem(a->child_boxes, i);
    3866             :                                 drop_wave=GF_TRUE;
    3867           0 :                                 gf_list_add(ptr->child_boxes, inner_box);
    3868             :                                                 }
    3869             :                                                 break;
    3870             :                     }
    3871             :                 }
    3872             :                                 if (drop_wave) {
    3873           0 :                                         gf_isom_box_del_parent(&ptr->child_boxes, a);
    3874           0 :                         ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3875           0 :                                         ptr->compression_id = 0;
    3876           0 :                                         ptr->version = 0;
    3877           0 :                                         return GF_OK;
    3878             :                                 }
    3879           1 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
    3880           1 :                 return GF_OK;
    3881             :             }
    3882             :                 }
    3883             :         }
    3884          88 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
    3885          88 :                 return GF_OK;
    3886             :         }
    3887             :         return GF_OK;
    3888             : }
    3889         974 : GF_Err audio_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
    3890             : {
    3891             :         GF_MPEGAudioSampleEntryBox *ptr;
    3892             :         char *data;
    3893             :         u8 a, b, c, d;
    3894             :         u32 i, size, v, nb_alnum;
    3895             :         GF_Err e;
    3896             :         u64 pos, start;
    3897             : 
    3898             :         ptr = (GF_MPEGAudioSampleEntryBox *)s;
    3899             : 
    3900         974 :         start = gf_bs_get_position(bs);
    3901         974 :         gf_bs_seek(bs, start + 8);
    3902         974 :         v = gf_bs_read_u16(bs);
    3903         974 :         if (v)
    3904          95 :                 ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;
    3905             : 
    3906             :         //try to disambiguate QTFF v1 and MP4 v1 audio sample entries ...
    3907         974 :         if (v==1) {
    3908             :                 //go to end of ISOM audio sample entry, skip 4 byte (box size field), read 4 bytes (box type) and check if this looks like a box
    3909          95 :                 gf_bs_seek(bs, start + 8 + 20  + 4);
    3910          95 :                 a = gf_bs_read_u8(bs);
    3911          95 :                 b = gf_bs_read_u8(bs);
    3912          95 :                 c = gf_bs_read_u8(bs);
    3913          95 :                 d = gf_bs_read_u8(bs);
    3914             :                 nb_alnum = 0;
    3915          95 :                 if (isalnum(a)) nb_alnum++;
    3916          95 :                 if (isalnum(b)) nb_alnum++;
    3917          95 :                 if (isalnum(c)) nb_alnum++;
    3918          95 :                 if (isalnum(d)) nb_alnum++;
    3919          95 :                 if (nb_alnum>2) ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
    3920             :         }
    3921             : 
    3922         974 :         gf_bs_seek(bs, start);
    3923         974 :         e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
    3924         974 :         if (e) return e;
    3925         974 :         pos = gf_bs_get_position(bs);
    3926         974 :         size = (u32) s->size;
    3927             : 
    3928             :         //when cookie is set on bs, always convert qtff-style mp4a to isobmff-style
    3929             :         //since the conversion is done in addBox and we don't have the bitstream there (arg...), flag the box
    3930         974 :         if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_QT_CONV) {
    3931           5 :                 ptr->qtff_mode |= GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;
    3932             :         }
    3933             : 
    3934         974 :         e = gf_isom_box_array_read(s, bs);
    3935         974 :         if (!e) {
    3936         974 :                 if (s->type==GF_ISOM_BOX_TYPE_ENCA) {
    3937         184 :                         GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);
    3938             : 
    3939         184 :                         if (sinf && sinf->original_format) {
    3940         183 :                                 u32 type = sinf->original_format->data_format;
    3941         183 :                                 switch (type) {
    3942           0 :                                 case GF_ISOM_SUBTYPE_3GP_AMR:
    3943             :                                 case GF_ISOM_SUBTYPE_3GP_AMR_WB:
    3944             :                                 case GF_ISOM_SUBTYPE_3GP_EVRC:
    3945             :                                 case GF_ISOM_SUBTYPE_3GP_QCELP:
    3946             :                                 case GF_ISOM_SUBTYPE_3GP_SMV:
    3947           0 :                                         if (ptr->cfg_3gpp) ptr->cfg_3gpp->cfg.type = type;
    3948             :                                         break;
    3949             :                                 }
    3950             :                         }
    3951             :                 }
    3952             :                 return GF_OK;
    3953             :         }
    3954           0 :         if (size<8) return GF_ISOM_INVALID_FILE;
    3955             : 
    3956             : 
    3957             :         /*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/
    3958           0 :         gf_bs_seek(bs, pos);
    3959           0 :         data = (char*)gf_malloc(sizeof(char) * size);
    3960           0 :         if (!data) return GF_OUT_OF_MEM;
    3961             : 
    3962           0 :         gf_bs_read_data(bs, data, size);
    3963           0 :         for (i=0; i<size-8; i++) {
    3964           0 :                 if (GF_4CC((u32)data[i+4], (u8)data[i+5], (u8)data[i+6], (u8)data[i+7]) == GF_ISOM_BOX_TYPE_ESDS) {
    3965           0 :                         GF_BitStream *mybs = gf_bs_new(data + i, size - i, GF_BITSTREAM_READ);
    3966           0 :                         if (ptr->esd) gf_isom_box_del_parent(&ptr->child_boxes, (GF_Box *)ptr->esd);
    3967           0 :                         ptr->esd = NULL;
    3968           0 :                         e = gf_isom_box_parse((GF_Box **)&ptr->esd, mybs);
    3969           0 :                         gf_bs_del(mybs);
    3970           0 :                         if (e==GF_OK) {
    3971           0 :                                 if (!ptr->child_boxes) ptr->child_boxes = gf_list_new();
    3972           0 :                                 gf_list_add(ptr->child_boxes, ptr->esd);
    3973           0 :                         } else if (ptr->esd) {
    3974           0 :                                 gf_isom_box_del((GF_Box *)ptr->esd);
    3975           0 :                                 ptr->esd = NULL;
    3976             :                         }
    3977             :                         break;
    3978             :                 }
    3979             :         }
    3980           0 :         gf_free(data);
    3981           0 :         return e;
    3982             : }
    3983             : 
    3984        1298 : GF_Box *audio_sample_entry_box_new()
    3985             : {
    3986        2596 :         ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
    3987        1298 :         gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
    3988        1298 :         return (GF_Box *)tmp;
    3989             : }
    3990             : 
    3991           0 : GF_Box *enca_box_new()
    3992             : {
    3993           0 :         ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA);
    3994           0 :         gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
    3995           0 :         return (GF_Box *)tmp;
    3996             : }
    3997             : 
    3998             : 
    3999             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4000             : 
    4001         741 : GF_Err audio_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
    4002             : {
    4003             :         GF_Err e;
    4004         741 :         e = gf_isom_box_write_header(s, bs);
    4005         741 :         if (e) return e;
    4006         741 :         gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
    4007         741 :         return GF_OK;
    4008             : }
    4009             : 
    4010        1327 : GF_Err audio_sample_entry_box_size(GF_Box *s)
    4011             : {
    4012        1327 :         u32 pos=0;
    4013             :         GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
    4014        1327 :         gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
    4015        1327 :         if (ptr->qtff_mode)
    4016             :                 return GF_OK;
    4017             : 
    4018        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
    4019        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
    4020        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_opus, &pos);
    4021        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_ac3, &pos);
    4022        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_flac, &pos);
    4023        1212 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_mlp, &pos);
    4024        1212 :         return GF_OK;
    4025             : }
    4026             : 
    4027             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4028             : 
    4029             : 
    4030          14 : void gen_sample_entry_box_del(GF_Box *s)
    4031             : {
    4032             :         GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
    4033          14 :         if (ptr == NULL) return;
    4034          14 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    4035          14 :         gf_free(ptr);
    4036             : }
    4037             : 
    4038             : 
    4039          12 : GF_Err gen_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
    4040             : {
    4041          12 :         GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
    4042          12 :         if (e) return e;
    4043          12 :         ISOM_DECREASE_SIZE(s, 8);
    4044          12 :         return gf_isom_box_array_read(s, bs);
    4045             : }
    4046             : 
    4047          14 : GF_Box *gen_sample_entry_box_new()
    4048             : {
    4049          28 :         ISOM_DECL_BOX_ALLOC(GF_SampleEntryBox, GF_QT_SUBTYPE_C608);//type will be overriten
    4050          14 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    4051          14 :         return (GF_Box *)tmp;
    4052             : }
    4053             : 
    4054             : 
    4055             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4056             : 
    4057           9 : GF_Err gen_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
    4058             : {
    4059             :         GF_Err e;
    4060             :         GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
    4061           9 :         e = gf_isom_box_write_header(s, bs);
    4062           9 :         if (e) return e;
    4063             : 
    4064           9 :         gf_bs_write_data(bs, ptr->reserved, 6);
    4065           9 :         gf_bs_write_u16(bs, ptr->dataReferenceIndex);
    4066           9 :         return GF_OK;
    4067             : }
    4068             : 
    4069          15 : GF_Err gen_sample_entry_box_size(GF_Box *s)
    4070             : {
    4071             :         GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
    4072          15 :         ptr->size += 8;
    4073          15 :         return GF_OK;
    4074             : }
    4075             : 
    4076             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4077             : 
    4078         313 : void mp4s_box_del(GF_Box *s)
    4079             : {
    4080             :         GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
    4081         313 :         if (ptr == NULL) return;
    4082         313 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    4083         313 :         if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
    4084         313 :         gf_free(ptr);
    4085             : }
    4086             : 
    4087         178 : GF_Err mp4s_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    4088             : {
    4089             :         GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
    4090         178 :         switch (a->type) {
    4091         178 :         case GF_ISOM_BOX_TYPE_ESDS:
    4092         178 :                 BOX_FIELD_ASSIGN(esd, GF_ESDBox)
    4093         178 :                 break;
    4094             :         }
    4095             :         return GF_OK;
    4096             : }
    4097             : 
    4098         183 : GF_Err mp4s_box_read(GF_Box *s, GF_BitStream *bs)
    4099             : {
    4100             :         GF_Err e;
    4101             :         GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
    4102             : 
    4103         183 :         e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
    4104         183 :         if (e) return e;
    4105             : 
    4106         183 :         ISOM_DECREASE_SIZE(ptr, 8);
    4107         183 :         return gf_isom_box_array_read(s, bs);
    4108             : }
    4109             : 
    4110         313 : GF_Box *mp4s_box_new()
    4111             : {
    4112         626 :         ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
    4113         313 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    4114         313 :         return (GF_Box *)tmp;
    4115             : }
    4116             : 
    4117           0 : GF_Box *encs_box_new()
    4118             : {
    4119           0 :         ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS);
    4120           0 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    4121           0 :         return (GF_Box *)tmp;
    4122             : }
    4123             : 
    4124             : 
    4125             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4126             : 
    4127         169 : GF_Err mp4s_box_write(GF_Box *s, GF_BitStream *bs)
    4128             : {
    4129             :         GF_Err e;
    4130             :         GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
    4131             : 
    4132         169 :         e = gf_isom_box_write_header(s, bs);
    4133         169 :         if (e) return e;
    4134         169 :         gf_bs_write_data(bs, ptr->reserved, 6);
    4135         169 :         gf_bs_write_u16(bs, ptr->dataReferenceIndex);
    4136         169 :     return GF_OK;
    4137             : }
    4138             : 
    4139         431 : GF_Err mp4s_box_size(GF_Box *s)
    4140             : {
    4141         431 :         u32 pos=0;
    4142             :         GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
    4143         431 :         s->size += 8;
    4144         431 :         gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
    4145         431 :     return GF_OK;
    4146             : }
    4147             : 
    4148             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4149             : 
    4150        3304 : void video_sample_entry_box_del(GF_Box *s)
    4151             : {
    4152             :         GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
    4153        3304 :         if (ptr == NULL) return;
    4154        3304 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    4155             : 
    4156        3304 :         if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
    4157             :         /*for publishing*/
    4158        3304 :         if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);
    4159        3304 :         gf_free(ptr);
    4160             : }
    4161             : 
    4162        5020 : GF_Err video_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    4163             : {
    4164             :         GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
    4165        5020 :         switch (a->type) {
    4166         191 :         case GF_ISOM_BOX_TYPE_ESDS:
    4167         191 :                 BOX_FIELD_ASSIGN(esd, GF_ESDBox)
    4168         191 :                 break;
    4169           0 :         case GF_ISOM_BOX_TYPE_RINF:
    4170           0 :                 BOX_FIELD_ASSIGN(rinf, GF_RestrictedSchemeInfoBox)
    4171           0 :                 break;
    4172         922 :         case GF_ISOM_BOX_TYPE_AVCC:
    4173         922 :                 BOX_FIELD_ASSIGN(avc_config, GF_AVCConfigurationBox)
    4174         922 :                 break;
    4175         332 :         case GF_ISOM_BOX_TYPE_HVCC:
    4176         332 :                 BOX_FIELD_ASSIGN(hevc_config, GF_HEVCConfigurationBox)
    4177         332 :                 break;
    4178           0 :         case GF_ISOM_BOX_TYPE_VVCC:
    4179           0 :                 BOX_FIELD_ASSIGN(vvc_config, GF_VVCConfigurationBox)
    4180           0 :                 break;
    4181          21 :         case GF_ISOM_BOX_TYPE_SVCC:
    4182          21 :                 BOX_FIELD_ASSIGN(svc_config, GF_AVCConfigurationBox)
    4183          21 :                 break;
    4184           0 :         case GF_ISOM_BOX_TYPE_MVCC:
    4185           0 :                 BOX_FIELD_ASSIGN(mvc_config, GF_AVCConfigurationBox)
    4186           0 :                 break;
    4187          11 :         case GF_ISOM_BOX_TYPE_LHVC:
    4188          11 :                 BOX_FIELD_ASSIGN(lhvc_config, GF_HEVCConfigurationBox)
    4189          11 :                 break;
    4190         329 :         case GF_ISOM_BOX_TYPE_AV1C:
    4191         329 :                 BOX_FIELD_ASSIGN(av1_config, GF_AV1ConfigurationBox)
    4192         329 :                 break;
    4193         176 :         case GF_ISOM_BOX_TYPE_VPCC:
    4194         176 :                 BOX_FIELD_ASSIGN(vp_config, GF_VPConfigurationBox)
    4195         176 :                 break;
    4196           3 :         case GF_ISOM_BOX_TYPE_DVCC:
    4197           3 :                 BOX_FIELD_ASSIGN(dovi_config, GF_DOVIConfigurationBox)
    4198           3 :                 break;
    4199           4 :         case GF_ISOM_BOX_TYPE_UUID:
    4200           4 :                 if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) {
    4201           1 :                         BOX_FIELD_ASSIGN(ipod_ext, GF_UnknownUUIDBox)
    4202             :                 } else {
    4203             :                         return GF_OK;
    4204             :                 }
    4205           1 :                 break;
    4206           9 :         case GF_ISOM_BOX_TYPE_D263:
    4207           9 :                 BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
    4208             :                 /*for 3GP config, remember sample entry type in config*/
    4209             :                 if (ptr->cfg_3gpp)
    4210           9 :                         ptr->cfg_3gpp->cfg.type = ptr->type;
    4211             :                 break;
    4212             : 
    4213          19 :         case GF_ISOM_BOX_TYPE_JP2H:
    4214          19 :                 BOX_FIELD_ASSIGN(jp2h, GF_J2KHeaderBox)
    4215          19 :                 return GF_OK;
    4216             : 
    4217         416 :         case GF_ISOM_BOX_TYPE_PASP:
    4218             :         case GF_ISOM_BOX_TYPE_CLAP:
    4219             :         case GF_ISOM_BOX_TYPE_COLR:
    4220             :         case GF_ISOM_BOX_TYPE_MDCV:
    4221             :         case GF_ISOM_BOX_TYPE_CLLI:
    4222             :         case GF_ISOM_BOX_TYPE_CCST:
    4223             :         case GF_ISOM_BOX_TYPE_AUXI:
    4224             :         case GF_ISOM_BOX_TYPE_RVCC:
    4225             :         case GF_ISOM_BOX_TYPE_M4DS:
    4226         416 :                 if (!is_rem && !gf_isom_box_check_unique(s->child_boxes, a)) {
    4227           0 :                         ERROR_ON_DUPLICATED_BOX(a, ptr)
    4228             :                 }
    4229             :                 return GF_OK;
    4230             :         }
    4231             :         return GF_OK;
    4232             : }
    4233             : 
    4234        2233 : GF_Err video_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
    4235             : {
    4236             :         GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
    4237             :         GF_Err e;
    4238        2233 :         e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
    4239        2233 :         if (e) return e;
    4240        2233 :         e = gf_isom_box_array_read(s, bs);
    4241        2233 :         if (e) return e;
    4242             :         /*this is an AVC sample desc*/
    4243        2233 :         if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config)
    4244         936 :                 AVC_RewriteESDescriptor(mp4v);
    4245             :         /*this is an HEVC sample desc*/
    4246        2233 :         if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1))
    4247         483 :                 HEVC_RewriteESDescriptor(mp4v);
    4248             :         /*this is an AV1 sample desc*/
    4249        2233 :         if (mp4v->av1_config)
    4250         329 :                 AV1_RewriteESDescriptor(mp4v);
    4251             :         /*this is a VP8-9 sample desc*/
    4252        2233 :         if (mp4v->vp_config)
    4253         176 :                 VP9_RewriteESDescriptor(mp4v);
    4254             : 
    4255        2233 :         if (s->type==GF_ISOM_BOX_TYPE_ENCV) {
    4256         671 :                 GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);
    4257             : 
    4258         671 :                 if (sinf && sinf->original_format) {
    4259         670 :                         u32 type = sinf->original_format->data_format;
    4260         670 :                         switch (type) {
    4261           0 :                         case GF_ISOM_SUBTYPE_3GP_H263:
    4262           0 :                                 if (mp4v->cfg_3gpp) mp4v->cfg_3gpp->cfg.type = type;
    4263             :                                 break;
    4264             :                         }
    4265             :                 }
    4266             :         }
    4267             :         return GF_OK;
    4268             : }
    4269             : 
    4270        3304 : GF_Box *video_sample_entry_box_new()
    4271             : {
    4272             :         GF_MPEGVisualSampleEntryBox *tmp;
    4273        3304 :         GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox);
    4274        3304 :         if (tmp == NULL) return NULL;
    4275             : 
    4276        3304 :         gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
    4277        3304 :         return (GF_Box *)tmp;
    4278             : }
    4279             : 
    4280             : 
    4281             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4282             : 
    4283        1996 : GF_Err video_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
    4284             : {
    4285             :         GF_Err e;
    4286        1996 :         e = gf_isom_box_write_header(s, bs);
    4287        1996 :         if (e) return e;
    4288        1996 :         gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
    4289        1996 :         return GF_OK;
    4290             : }
    4291             : 
    4292        3463 : GF_Err video_sample_entry_box_size(GF_Box *s)
    4293             : {
    4294             :         GF_Box *b;
    4295        3463 :         u32 pos=0;
    4296             :         GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
    4297        3463 :         gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
    4298             : 
    4299             :         /*make sure we write the config box first, we don't care about the rest*/
    4300             : 
    4301             :         /*mp4v*/
    4302        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
    4303        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
    4304             :         /*avc / SVC + MVC*/
    4305        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->avc_config, &pos);
    4306        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->svc_config, &pos);
    4307        3463 :         if (ptr->mvc_config) {
    4308           0 :                 gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_VWID), &pos);
    4309           0 :                 gf_isom_check_position(s, (GF_Box *)ptr->mvc_config, &pos);
    4310             :         }
    4311             : 
    4312             :         /*HEVC*/
    4313        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->hevc_config, &pos);
    4314        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->lhvc_config, &pos);
    4315             : 
    4316             :         /*VVC*/
    4317        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->vvc_config, &pos);
    4318             :         
    4319             :         /*AV1*/
    4320        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->av1_config, &pos);
    4321             : 
    4322             :         /*VPx*/
    4323        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->vp_config, &pos);
    4324             : 
    4325             :         /*JP2H*/
    4326        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->jp2h, &pos);
    4327             : 
    4328             :         /*DolbyVision*/
    4329        3463 :         gf_isom_check_position(s, (GF_Box *)ptr->dovi_config, &pos);
    4330             : 
    4331        3463 :         b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ST3D);
    4332        3463 :         if (b) gf_isom_check_position(s, b, &pos);
    4333             : 
    4334        3463 :         b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SV3D);
    4335        3463 :         if (b) gf_isom_check_position(s, b, &pos);
    4336        3463 :         return GF_OK;
    4337             : }
    4338             : 
    4339             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4340             : 
    4341             : 
    4342             : 
    4343             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    4344             : 
    4345         602 : void mvex_box_del(GF_Box *s)
    4346             : {
    4347             :         GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
    4348         602 :         if (ptr == NULL) return;
    4349         602 :         gf_list_del(ptr->TrackExList);
    4350         602 :         gf_list_del(ptr->TrackExPropList);
    4351         602 :         gf_free(ptr);
    4352             : }
    4353             : 
    4354             : 
    4355         960 : GF_Err mvex_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    4356             : {
    4357             :         GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
    4358             : 
    4359         960 :         switch (a->type) {
    4360         722 :         case GF_ISOM_BOX_TYPE_TREX:
    4361         722 :                 BOX_FIELD_LIST_ASSIGN(TrackExList)
    4362             :                 return GF_OK;
    4363           0 :         case GF_ISOM_BOX_TYPE_TREP:
    4364           0 :                 BOX_FIELD_LIST_ASSIGN(TrackExPropList)
    4365             :                 return GF_OK;
    4366         238 :         case GF_ISOM_BOX_TYPE_MEHD:
    4367         238 :                 BOX_FIELD_ASSIGN(mehd, GF_MovieExtendsHeaderBox)
    4368         238 :                 return GF_OK;
    4369             :         }
    4370             :         return GF_OK;
    4371             : }
    4372             : 
    4373             : 
    4374             : 
    4375         253 : GF_Err mvex_box_read(GF_Box *s, GF_BitStream *bs)
    4376             : {
    4377         253 :         return gf_isom_box_array_read(s, bs);
    4378             : }
    4379             : 
    4380         602 : GF_Box *mvex_box_new()
    4381             : {
    4382        1204 :         ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
    4383         602 :         tmp->TrackExList = gf_list_new();
    4384         602 :         if (!tmp->TrackExList) {
    4385           0 :                 gf_free(tmp);
    4386           0 :                 return NULL;
    4387             :         }
    4388         602 :         tmp->TrackExPropList = gf_list_new();
    4389         602 :         if (!tmp->TrackExPropList) {
    4390           0 :                 gf_list_del(tmp->TrackExList);
    4391           0 :                 gf_free(tmp);
    4392           0 :                 return NULL;
    4393             :         }
    4394             :         return (GF_Box *)tmp;
    4395             : }
    4396             : 
    4397             : 
    4398             : 
    4399             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4400             : 
    4401             : 
    4402         342 : GF_Err mvex_box_write(GF_Box *s, GF_BitStream *bs)
    4403             : {
    4404         342 :         return gf_isom_box_write_header(s, bs);
    4405             : }
    4406             : 
    4407         347 : GF_Err mvex_box_size(GF_Box *s)
    4408             : {
    4409         347 :         u32 pos=0;
    4410             :         GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *) s;
    4411         347 :         gf_isom_check_position(s, (GF_Box *)ptr->mehd, &pos);
    4412         347 :         gf_isom_check_position_list(s, ptr->TrackExList, &pos);
    4413         347 :         gf_isom_check_position_list(s, ptr->TrackExPropList, &pos);
    4414         347 :         return GF_OK;
    4415             : }
    4416             : 
    4417             : 
    4418             : 
    4419             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4420             : 
    4421         583 : GF_Box *mehd_box_new()
    4422             : {
    4423        1166 :         ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
    4424         583 :         return (GF_Box *)tmp;
    4425             : }
    4426         583 : void mehd_box_del(GF_Box *s)
    4427             : {
    4428         583 :         gf_free(s);
    4429         583 : }
    4430         239 : GF_Err mehd_box_read(GF_Box *s, GF_BitStream *bs)
    4431             : {
    4432             :         GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
    4433             : 
    4434         239 :         if (ptr->version==1) {
    4435           3 :                 ISOM_DECREASE_SIZE(ptr, 8);
    4436           3 :                 ptr->fragment_duration = gf_bs_read_u64(bs);
    4437             :         } else {
    4438         236 :                 ISOM_DECREASE_SIZE(ptr, 4);
    4439         236 :                 ptr->fragment_duration = (u64) gf_bs_read_u32(bs);
    4440             :         }
    4441             :         return GF_OK;
    4442             : }
    4443             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4444         342 : GF_Err mehd_box_write(GF_Box *s, GF_BitStream *bs)
    4445             : {
    4446             :         GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
    4447         342 :         GF_Err e = gf_isom_full_box_write(s, bs);
    4448         342 :         if (e) return e;
    4449         342 :         if (ptr->version == 1) {
    4450           0 :                 gf_bs_write_u64(bs, ptr->fragment_duration);
    4451             :         } else {
    4452         342 :                 gf_bs_write_u32(bs, (u32) ptr->fragment_duration);
    4453             :         }
    4454             :         return GF_OK;
    4455             : }
    4456         347 : GF_Err mehd_box_size(GF_Box *s)
    4457             : {
    4458             :         GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
    4459         347 :         ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0;
    4460         347 :         s->size += (ptr->version == 1) ? 8 : 4;
    4461         347 :         return GF_OK;
    4462             : }
    4463             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4464             : 
    4465             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    4466             : 
    4467             : 
    4468        2961 : void mvhd_box_del(GF_Box *s)
    4469             : {
    4470             :         GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
    4471        2961 :         if (ptr == NULL) return;
    4472        2961 :         gf_free(ptr);
    4473             : }
    4474             : 
    4475             : 
    4476        1666 : GF_Err mvhd_box_read(GF_Box *s, GF_BitStream *bs)
    4477             : {
    4478             :         GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
    4479        1666 :         if (ptr == NULL) return GF_BAD_PARAM;
    4480        1666 :         if (ptr->version == 1) {
    4481           0 :                 ISOM_DECREASE_SIZE(ptr, 28);
    4482           0 :                 ptr->creationTime = gf_bs_read_u64(bs);
    4483           0 :                 ptr->modificationTime = gf_bs_read_u64(bs);
    4484           0 :                 ptr->timeScale = gf_bs_read_u32(bs);
    4485           0 :                 ptr->duration = gf_bs_read_u64(bs);
    4486             :         } else {
    4487        1666 :                 ISOM_DECREASE_SIZE(ptr, 16);
    4488        1666 :                 ptr->creationTime = gf_bs_read_u32(bs);
    4489        1666 :                 ptr->modificationTime = gf_bs_read_u32(bs);
    4490        1666 :                 ptr->timeScale = gf_bs_read_u32(bs);
    4491        1666 :                 ptr->duration = gf_bs_read_u32(bs);
    4492             :         }
    4493        1666 :         if (!ptr->timeScale) {
    4494           1 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n" ));
    4495           1 :                 ptr->timeScale = 600;
    4496             :         }
    4497        1666 :         ISOM_DECREASE_SIZE(ptr, 80);
    4498        1666 :         ptr->preferredRate = gf_bs_read_u32(bs);
    4499        1666 :         ptr->preferredVolume = gf_bs_read_u16(bs);
    4500        1666 :         gf_bs_read_data(bs, ptr->reserved, 10);
    4501        1666 :         ptr->matrixA = gf_bs_read_u32(bs);
    4502        1666 :         ptr->matrixB = gf_bs_read_u32(bs);
    4503        1666 :         ptr->matrixU = gf_bs_read_u32(bs);
    4504        1666 :         ptr->matrixC = gf_bs_read_u32(bs);
    4505        1666 :         ptr->matrixD = gf_bs_read_u32(bs);
    4506        1666 :         ptr->matrixV = gf_bs_read_u32(bs);
    4507        1666 :         ptr->matrixX = gf_bs_read_u32(bs);
    4508        1666 :         ptr->matrixY = gf_bs_read_u32(bs);
    4509        1666 :         ptr->matrixW = gf_bs_read_u32(bs);
    4510        1666 :         ptr->previewTime = gf_bs_read_u32(bs);
    4511        1666 :         ptr->previewDuration = gf_bs_read_u32(bs);
    4512        1666 :         ptr->posterTime = gf_bs_read_u32(bs);
    4513        1666 :         ptr->selectionTime = gf_bs_read_u32(bs);
    4514        1666 :         ptr->selectionDuration = gf_bs_read_u32(bs);
    4515        1666 :         ptr->currentTime = gf_bs_read_u32(bs);
    4516        1666 :         ptr->nextTrackID = gf_bs_read_u32(bs);
    4517        1666 :         ptr->original_duration = ptr->duration;
    4518        1666 :         return GF_OK;
    4519             : }
    4520             : 
    4521        2961 : GF_Box *mvhd_box_new()
    4522             : {
    4523        5922 :         ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);
    4524             : 
    4525        2961 :         tmp->preferredRate = (1<<16);
    4526        2961 :         tmp->preferredVolume = (1<<8);
    4527             : 
    4528        2961 :         tmp->matrixA = (1<<16);
    4529        2961 :         tmp->matrixD = (1<<16);
    4530        2961 :         tmp->matrixW = (1<<30);
    4531             : 
    4532        2961 :         tmp->nextTrackID = 1;
    4533             : 
    4534        2961 :         return (GF_Box *)tmp;
    4535             : }
    4536             : 
    4537             : 
    4538             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4539             : 
    4540        1373 : GF_Err mvhd_box_write(GF_Box *s, GF_BitStream *bs)
    4541             : {
    4542             :         GF_Err e;
    4543             :         GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
    4544        1373 :         e = gf_isom_full_box_write(s, bs);
    4545        1373 :         if (e) return e;
    4546        1373 :         if (ptr->version == 1) {
    4547           0 :                 gf_bs_write_u64(bs, ptr->creationTime);
    4548           0 :                 gf_bs_write_u64(bs, ptr->modificationTime);
    4549           0 :                 gf_bs_write_u32(bs, ptr->timeScale);
    4550           0 :                 gf_bs_write_u64(bs, ptr->duration);
    4551             :         } else {
    4552        1373 :                 gf_bs_write_u32(bs, (u32) ptr->creationTime);
    4553        1373 :                 gf_bs_write_u32(bs, (u32) ptr->modificationTime);
    4554        1373 :                 gf_bs_write_u32(bs, ptr->timeScale);
    4555        1373 :                 gf_bs_write_u32(bs, (u32) ptr->duration);
    4556             :         }
    4557        1373 :         gf_bs_write_u32(bs, ptr->preferredRate);
    4558        1373 :         gf_bs_write_u16(bs, ptr->preferredVolume);
    4559        1373 :         gf_bs_write_data(bs, ptr->reserved, 10);
    4560        1373 :         gf_bs_write_u32(bs, ptr->matrixA);
    4561        1373 :         gf_bs_write_u32(bs, ptr->matrixB);
    4562        1373 :         gf_bs_write_u32(bs, ptr->matrixU);
    4563        1373 :         gf_bs_write_u32(bs, ptr->matrixC);
    4564        1373 :         gf_bs_write_u32(bs, ptr->matrixD);
    4565        1373 :         gf_bs_write_u32(bs, ptr->matrixV);
    4566        1373 :         gf_bs_write_u32(bs, ptr->matrixX);
    4567        1373 :         gf_bs_write_u32(bs, ptr->matrixY);
    4568        1373 :         gf_bs_write_u32(bs, ptr->matrixW);
    4569        1373 :         gf_bs_write_u32(bs, ptr->previewTime);
    4570        1373 :         gf_bs_write_u32(bs, ptr->previewDuration);
    4571        1373 :         gf_bs_write_u32(bs, ptr->posterTime);
    4572        1373 :         gf_bs_write_u32(bs, ptr->selectionTime);
    4573        1373 :         gf_bs_write_u32(bs, ptr->selectionDuration);
    4574        1373 :         gf_bs_write_u32(bs, ptr->currentTime);
    4575        1373 :         gf_bs_write_u32(bs, ptr->nextTrackID);
    4576        1373 :         return GF_OK;
    4577             : }
    4578             : 
    4579        3377 : GF_Err mvhd_box_size(GF_Box *s)
    4580             : {
    4581             :         GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
    4582        3377 :         if (ptr->duration==(u64) -1) ptr->version = 0;
    4583        3377 :         else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
    4584             : 
    4585        3377 :         ptr->size += (ptr->version == 1) ? 28 : 16;
    4586        3377 :         ptr->size += 80;
    4587        3377 :         return GF_OK;
    4588             : }
    4589             : 
    4590             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4591             : 
    4592             : 
    4593         643 : void nmhd_box_del(GF_Box *s)
    4594             : {
    4595             :         GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s;
    4596         643 :         if (ptr == NULL) return;
    4597         643 :         gf_free(ptr);
    4598             : }
    4599             : 
    4600             : 
    4601             : 
    4602         420 : GF_Err nmhd_box_read(GF_Box *s, GF_BitStream *bs)
    4603             : {
    4604         420 :         return GF_OK;
    4605             : }
    4606             : 
    4607         643 : GF_Box *nmhd_box_new()
    4608             : {
    4609        1286 :         ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
    4610         643 :         return (GF_Box *)tmp;
    4611             : }
    4612             : 
    4613             : 
    4614             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4615             : 
    4616         417 : GF_Err nmhd_box_write(GF_Box *s, GF_BitStream *bs)
    4617             : {
    4618         417 :         return gf_isom_full_box_write(s, bs);
    4619             : }
    4620             : 
    4621         999 : GF_Err nmhd_box_size(GF_Box *s)
    4622             : {
    4623         999 :         return GF_OK;
    4624             : }
    4625             : 
    4626             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4627             : 
    4628             : 
    4629             : 
    4630           3 : void padb_box_del(GF_Box *s)
    4631             : {
    4632             :         GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
    4633           3 :         if (ptr == NULL) return;
    4634           3 :         if (ptr->padbits) gf_free(ptr->padbits);
    4635           3 :         gf_free(ptr);
    4636             : }
    4637             : 
    4638             : 
    4639           1 : GF_Err padb_box_read(GF_Box *s,GF_BitStream *bs)
    4640             : {
    4641             :         u32 i;
    4642             :         GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
    4643             : 
    4644           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    4645           1 :         ptr->SampleCount = gf_bs_read_u32(bs);
    4646           1 :         if (ptr->size < ptr->SampleCount/2) //half byte per sample
    4647             :                 return GF_ISOM_INVALID_FILE;
    4648             : 
    4649           1 :         ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount);
    4650           1 :         if (!ptr->padbits) return GF_OUT_OF_MEM;
    4651             : 
    4652           0 :         for (i=0; i<ptr->SampleCount; i += 2) {
    4653           0 :                 gf_bs_read_int(bs, 1);
    4654           0 :                 if (i+1 < ptr->SampleCount) {
    4655           0 :                         ptr->padbits[i+1] = gf_bs_read_int(bs, 3);
    4656             :                 } else {
    4657           0 :                         gf_bs_read_int(bs, 3);
    4658             :                 }
    4659           0 :                 gf_bs_read_int(bs, 1);
    4660           0 :                 ptr->padbits[i] = gf_bs_read_int(bs, 3);
    4661             :         }
    4662             :         return GF_OK;
    4663             : }
    4664             : 
    4665           3 : GF_Box *padb_box_new()
    4666             : {
    4667           6 :         ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
    4668           3 :         return (GF_Box *)tmp;
    4669             : }
    4670             : 
    4671             : 
    4672             : 
    4673             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4674             : 
    4675           1 : GF_Err padb_box_write(GF_Box *s, GF_BitStream *bs)
    4676             : {
    4677             :         u32 i;
    4678             :         GF_Err e;
    4679             :         GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
    4680             : 
    4681           1 :         e = gf_isom_full_box_write(s, bs);
    4682           1 :         if (e) return e;
    4683           1 :         gf_bs_write_int(bs, ptr->SampleCount, 32);
    4684             : 
    4685           1 :         for (i=0 ; i<ptr->SampleCount; i += 2) {
    4686           0 :                 gf_bs_write_int(bs, 0, 1);
    4687           0 :                 if (i+1 < ptr->SampleCount) {
    4688           0 :                         gf_bs_write_int(bs, ptr->padbits[i+1], 3);
    4689             :                 } else {
    4690           0 :                         gf_bs_write_int(bs, 0, 3);
    4691             :                 }
    4692           0 :                 gf_bs_write_int(bs, 0, 1);
    4693           0 :                 gf_bs_write_int(bs, ptr->padbits[i], 3);
    4694             :         }
    4695             :         return GF_OK;
    4696             : }
    4697             : 
    4698           1 : GF_Err padb_box_size(GF_Box *s)
    4699             : {
    4700             :         GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
    4701           1 :         ptr->size += 4;
    4702           1 :         if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2;
    4703             : 
    4704           1 :         return GF_OK;
    4705             : }
    4706             : 
    4707             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4708             : 
    4709             : 
    4710           3 : void rely_box_del(GF_Box *s)
    4711             : {
    4712             :         GF_RelyHintBox *rely = (GF_RelyHintBox *)s;
    4713           3 :         gf_free(rely);
    4714           3 : }
    4715             : 
    4716           1 : GF_Err rely_box_read(GF_Box *s, GF_BitStream *bs)
    4717             : {
    4718             :         GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
    4719           1 :         ISOM_DECREASE_SIZE(ptr, 1);
    4720           1 :         ptr->reserved = gf_bs_read_int(bs, 6);
    4721           1 :         ptr->preferred = gf_bs_read_int(bs, 1);
    4722           1 :         ptr->required = gf_bs_read_int(bs, 1);
    4723           1 :         return GF_OK;
    4724             : }
    4725             : 
    4726           3 : GF_Box *rely_box_new()
    4727             : {
    4728           6 :         ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
    4729           3 :         return (GF_Box *)tmp;
    4730             : }
    4731             : 
    4732             : 
    4733             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4734           1 : GF_Err rely_box_write(GF_Box *s, GF_BitStream *bs)
    4735             : {
    4736             :         GF_Err e;
    4737             :         GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
    4738           1 :         if (ptr == NULL) return GF_BAD_PARAM;
    4739           1 :         e = gf_isom_box_write_header(s, bs);
    4740           1 :         if (e) return e;
    4741           1 :         gf_bs_write_int(bs, ptr->reserved, 6);
    4742           1 :         gf_bs_write_int(bs, ptr->preferred, 1);
    4743           1 :         gf_bs_write_int(bs, ptr->required, 1);
    4744           1 :         return GF_OK;
    4745             : }
    4746             : 
    4747           1 : GF_Err rely_box_size(GF_Box *s)
    4748             : {
    4749           1 :         s->size += 1;
    4750           1 :         return GF_OK;
    4751             : }
    4752             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4753             : 
    4754             : 
    4755        9740 : void rtpo_box_del(GF_Box *s)
    4756             : {
    4757             :         GF_RTPOBox *rtpo = (GF_RTPOBox *)s;
    4758        9740 :         gf_free(rtpo);
    4759        9740 : }
    4760             : 
    4761           1 : GF_Err rtpo_box_read(GF_Box *s, GF_BitStream *bs)
    4762             : {
    4763             :         GF_RTPOBox *ptr = (GF_RTPOBox *)s;
    4764           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    4765           1 :         ptr->timeOffset = gf_bs_read_u32(bs);
    4766           1 :         return GF_OK;
    4767             : }
    4768             : 
    4769        9740 : GF_Box *rtpo_box_new()
    4770             : {
    4771       19480 :         ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
    4772        9740 :         return (GF_Box *)tmp;
    4773             : }
    4774             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4775        9738 : GF_Err rtpo_box_write(GF_Box *s, GF_BitStream *bs)
    4776             : {
    4777             :         GF_Err e;
    4778             :         GF_RTPOBox *ptr = (GF_RTPOBox *)s;
    4779        9738 :         if (ptr == NULL) return GF_BAD_PARAM;
    4780             : 
    4781             :         //here we have no pb, just remembed that some entries will have to
    4782             :         //be 4-bytes aligned ...
    4783        9738 :         e = gf_isom_box_write_header(s, bs);
    4784        9738 :         if (e) return e;
    4785        9738 :         gf_bs_write_u32(bs, ptr->timeOffset);
    4786        9738 :         return GF_OK;
    4787             : }
    4788             : 
    4789       19475 : GF_Err rtpo_box_size(GF_Box *s)
    4790             : {
    4791       19475 :         s->size += 4;
    4792       19475 :         return GF_OK;
    4793             : }
    4794             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4795             : 
    4796         980 : void smhd_box_del(GF_Box *s)
    4797             : {
    4798             :         GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
    4799         980 :         if (ptr == NULL ) return;
    4800         980 :         gf_free(ptr);
    4801             : }
    4802             : 
    4803             : 
    4804         799 : GF_Err smhd_box_read(GF_Box *s, GF_BitStream *bs)
    4805             : {
    4806             :         GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
    4807         799 :         ISOM_DECREASE_SIZE(ptr, 4);
    4808         799 :         ptr->balance = gf_bs_read_u16(bs);
    4809         799 :         ptr->reserved = gf_bs_read_u16(bs);
    4810         799 :         return GF_OK;
    4811             : }
    4812             : 
    4813         980 : GF_Box *smhd_box_new()
    4814             : {
    4815        1960 :         ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
    4816         980 :         return (GF_Box *)tmp;
    4817             : }
    4818             : 
    4819             : 
    4820             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4821             : 
    4822         772 : GF_Err smhd_box_write(GF_Box *s, GF_BitStream *bs)
    4823             : {
    4824             :         GF_Err e;
    4825             :         GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
    4826         772 :         e = gf_isom_full_box_write(s, bs);
    4827         772 :         if (e) return e;
    4828         772 :         gf_bs_write_u16(bs, ptr->balance);
    4829         772 :         gf_bs_write_u16(bs, ptr->reserved);
    4830         772 :         return GF_OK;
    4831             : }
    4832             : 
    4833        1484 : GF_Err smhd_box_size(GF_Box *s)
    4834             : {
    4835             :         GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
    4836             : 
    4837        1484 :         ptr->reserved = 0;
    4838        1484 :         ptr->size += 4;
    4839        1484 :         return GF_OK;
    4840             : }
    4841             : 
    4842             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4843             : 
    4844             : 
    4845             : 
    4846           4 : void snro_box_del(GF_Box *s)
    4847             : {
    4848             :         GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s;
    4849           4 :         gf_free(snro);
    4850           4 : }
    4851             : 
    4852           1 : GF_Err snro_box_read(GF_Box *s, GF_BitStream *bs)
    4853             : {
    4854             :         GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
    4855           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    4856           1 :         ptr->SeqOffset = gf_bs_read_u32(bs);
    4857           1 :         return GF_OK;
    4858             : }
    4859             : 
    4860           4 : GF_Box *snro_box_new()
    4861             : {
    4862           8 :         ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
    4863           4 :         return (GF_Box *)tmp;
    4864             : }
    4865             : 
    4866             : 
    4867             : #ifndef GPAC_DISABLE_ISOM_WRITE
    4868           2 : GF_Err snro_box_write(GF_Box *s, GF_BitStream *bs)
    4869             : {
    4870             :         GF_Err e;
    4871             :         GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
    4872           2 :         if (ptr == NULL) return GF_BAD_PARAM;
    4873             : 
    4874           2 :         e = gf_isom_box_write_header(s, bs);
    4875           2 :         if (e) return e;
    4876           2 :         gf_bs_write_u32(bs, ptr->SeqOffset);
    4877           2 :         return GF_OK;
    4878             : }
    4879             : 
    4880           4 : GF_Err snro_box_size(GF_Box *s)
    4881             : {
    4882           4 :         s->size += 4;
    4883           4 :         return GF_OK;
    4884             : }
    4885             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    4886             : 
    4887             : 
    4888        5368 : void stbl_box_del(GF_Box *s)
    4889             : {
    4890             :         GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
    4891        5368 :         if (ptr == NULL) return;
    4892             : 
    4893        5368 :         if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
    4894        5368 :         if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
    4895        5368 :         if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
    4896        5368 :         if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
    4897        5368 :         if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
    4898        5368 :         if (ptr->traf_map) {
    4899          36 :                 if (ptr->traf_map->frag_starts) {
    4900             :                         u32 i;
    4901         117 :                         for (i=0; i<ptr->traf_map->nb_entries; i++) {
    4902         117 :                                 if (ptr->traf_map->frag_starts[i].moof_template)
    4903          36 :                                         gf_free(ptr->traf_map->frag_starts[i].moof_template);
    4904             :                         }
    4905          36 :                         gf_free(ptr->traf_map->frag_starts);
    4906             :                 }
    4907          36 :                 gf_free(ptr->traf_map);
    4908             :         }
    4909        5368 :         gf_free(ptr);
    4910             : }
    4911             : 
    4912       15435 : GF_Err stbl_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    4913             : {
    4914             :         GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
    4915       15435 :         if (!a) return GF_OK;
    4916       15435 :         switch (a->type) {
    4917        2385 :         case GF_ISOM_BOX_TYPE_STTS:
    4918        2385 :                 BOX_FIELD_ASSIGN(TimeToSample, GF_TimeToSampleBox)
    4919        2385 :                 break;
    4920         476 :         case GF_ISOM_BOX_TYPE_CTTS:
    4921         476 :                 BOX_FIELD_ASSIGN(CompositionOffset, GF_CompositionOffsetBox)
    4922         476 :                 break;
    4923          12 :         case GF_ISOM_BOX_TYPE_CSLG:
    4924          12 :                 BOX_FIELD_ASSIGN(CompositionToDecode, GF_CompositionToDecodeBox)
    4925          12 :                 break;
    4926        1071 :         case GF_ISOM_BOX_TYPE_STSS:
    4927        1071 :                 BOX_FIELD_ASSIGN(SyncSample, GF_SyncSampleBox)
    4928        1071 :                 break;
    4929        3105 :         case GF_ISOM_BOX_TYPE_STSD:
    4930        3105 :                 BOX_FIELD_ASSIGN(SampleDescription, GF_SampleDescriptionBox)
    4931        3105 :                 break;
    4932        2385 :         case GF_ISOM_BOX_TYPE_STZ2:
    4933             :         case GF_ISOM_BOX_TYPE_STSZ:
    4934        2385 :                 BOX_FIELD_ASSIGN(SampleSize, GF_SampleSizeBox)
    4935        2385 :                 break;
    4936        2385 :         case GF_ISOM_BOX_TYPE_STSC:
    4937        2385 :                 BOX_FIELD_ASSIGN(SampleToChunk, GF_SampleToChunkBox)
    4938        2385 :                 break;
    4939           0 :         case GF_ISOM_BOX_TYPE_PADB:
    4940           0 :                 BOX_FIELD_ASSIGN(PaddingBits, GF_PaddingBitsBox)
    4941           0 :                 break;
    4942             : 
    4943             :         //WARNING: AS THIS MAY CHANGE DYNAMICALLY DURING EDIT,
    4944        2385 :         case GF_ISOM_BOX_TYPE_CO64:
    4945             :         case GF_ISOM_BOX_TYPE_STCO:
    4946        2385 :                 BOX_FIELD_ASSIGN(ChunkOffset, GF_Box)
    4947        2385 :                 break;
    4948           0 :         case GF_ISOM_BOX_TYPE_STSH:
    4949           0 :                 BOX_FIELD_ASSIGN(ShadowSync, GF_ShadowSyncBox)
    4950           0 :                 break;
    4951           0 :         case GF_ISOM_BOX_TYPE_STDP:
    4952           0 :                 BOX_FIELD_ASSIGN(DegradationPriority, GF_DegradationPriorityBox)
    4953           0 :                 break;
    4954          15 :         case GF_ISOM_BOX_TYPE_SDTP:
    4955          15 :                 BOX_FIELD_ASSIGN(SampleDep, GF_SampleDependencyTypeBox)
    4956          15 :                 break;
    4957             : 
    4958           3 :         case GF_ISOM_BOX_TYPE_SUBS:
    4959           3 :                 BOX_FIELD_LIST_ASSIGN(sub_samples)
    4960             :                 //check subsample box
    4961           3 :                 if (!is_rem) {
    4962             :                         GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a;
    4963           3 :                         GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0);
    4964           3 :                         if (!ent) {
    4965           0 :                                 gf_list_rem(subs->Samples, 0);
    4966           0 :                                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable is invalid\n"));
    4967             :                         }
    4968           3 :                         else if (ent->sample_delta==0) {
    4969           0 :                                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable has sample_delta of 0, should be one. Fixing\n"));
    4970           0 :                                 ent->sample_delta = 1;
    4971             :                         }
    4972             :                 }
    4973             :                 break;
    4974             : 
    4975          82 :         case GF_ISOM_BOX_TYPE_SBGP:
    4976             :         case GF_ISOM_BOX_TYPE_CSGP:
    4977          82 :                 BOX_FIELD_LIST_ASSIGN(sampleGroups)
    4978             :                 break;
    4979         291 :         case GF_ISOM_BOX_TYPE_SGPD:
    4980         291 :                 BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
    4981             :                 break;
    4982         420 :         case GF_ISOM_BOX_TYPE_SAIZ:
    4983         420 :                 BOX_FIELD_LIST_ASSIGN(sai_sizes)
    4984             :                 break;
    4985         420 :         case GF_ISOM_BOX_TYPE_SAIO:
    4986         420 :                 BOX_FIELD_LIST_ASSIGN(sai_offsets)
    4987             :                 break;
    4988             :         }
    4989             :         return GF_OK;
    4990             : }
    4991             : 
    4992             : 
    4993             : 
    4994             : 
    4995        3106 : GF_Err stbl_box_read(GF_Box *s, GF_BitStream *bs)
    4996             : {
    4997             :         GF_Err e;
    4998             :         //we need to parse DegPrior in a special way
    4999             :         GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
    5000             : 
    5001        3106 :         e = gf_isom_box_array_read(s, bs);
    5002        3106 :         if (e) return e;
    5003             : 
    5004        3106 :         if (!ptr->SyncSample)
    5005        2035 :                 ptr->no_sync_found = 1;
    5006             : 
    5007        3106 :         ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription);
    5008        3106 :         ptr->nb_stbl_boxes = gf_list_count(ptr->child_boxes);
    5009             : 
    5010        3106 :         if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_CLONE_TRACK)
    5011             :                 return GF_OK;
    5012             : //      return GF_OK;
    5013             : 
    5014             :         //these boxes are mandatory !
    5015        2386 :         if (!ptr->SampleToChunk || !ptr->SampleSize || !ptr->ChunkOffset || !ptr->TimeToSample)
    5016             :                 return GF_ISOM_INVALID_FILE;
    5017             :         //sanity check
    5018        2385 :         if (ptr->SampleSize->sampleCount) {
    5019        2017 :                 if (!ptr->TimeToSample->nb_entries || !ptr->SampleToChunk->nb_entries)
    5020             :                         return GF_ISOM_INVALID_FILE;
    5021             :         }
    5022        2385 :         return GF_OK;
    5023             : }
    5024             : 
    5025        5368 : GF_Box *stbl_box_new()
    5026             : {
    5027       10736 :         ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
    5028             :         //maxSamplePer chunk is 10 by default
    5029        5368 :         tmp->MaxSamplePerChunk = 10;
    5030        5368 :         tmp->groupID = 1;
    5031        5368 :         return (GF_Box *)tmp;
    5032             : }
    5033             : 
    5034             : 
    5035             : 
    5036             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5037             : 
    5038        3176 : GF_Err stbl_box_write(GF_Box *s, GF_BitStream *bs)
    5039             : {
    5040        3176 :         return gf_isom_box_write_header(s, bs);
    5041             : }
    5042             : 
    5043        6125 : GF_Err stbl_box_size(GF_Box *s)
    5044             : {
    5045        6125 :         u32 pos=0;
    5046             :         GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
    5047             : 
    5048        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->SampleDescription, &pos);
    5049        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->TimeToSample, &pos);
    5050        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->CompositionOffset, &pos);
    5051        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->CompositionToDecode, &pos);
    5052        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->SyncSample, &pos);
    5053        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->ShadowSync, &pos);
    5054        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->SampleToChunk, &pos);
    5055        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->SampleSize, &pos);
    5056        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->ChunkOffset, &pos);
    5057        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->DegradationPriority, &pos);
    5058        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->SampleDep, &pos);
    5059        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->PaddingBits, &pos);
    5060             : 
    5061        6125 :         if (ptr->sub_samples) {
    5062          12 :                 gf_isom_check_position_list(s, ptr->sub_samples, &pos);
    5063             :         }
    5064        6125 :         if (ptr->sampleGroupsDescription) {
    5065         441 :                 gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
    5066             :         }
    5067        6125 :         if (ptr->sampleGroups) {
    5068         129 :                 gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
    5069             :         }
    5070        6125 :         if (ptr->sai_sizes) {
    5071         291 :                 gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
    5072             :         }
    5073        6125 :         if (ptr->sai_offsets) {
    5074         291 :                 gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
    5075             :         }
    5076        6125 :         return GF_OK;
    5077             : }
    5078             : 
    5079             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5080             : 
    5081             : 
    5082       24434 : void stco_box_del(GF_Box *s)
    5083             : {
    5084             :         GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
    5085       24434 :         if (ptr == NULL) return;
    5086       24434 :         if (ptr->offsets) gf_free(ptr->offsets);
    5087       24434 :         gf_free(ptr);
    5088             : }
    5089             : 
    5090             : 
    5091        2386 : GF_Err stco_box_read(GF_Box *s, GF_BitStream *bs)
    5092             : {
    5093             :         u32 entries;
    5094             :         GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
    5095             : 
    5096        2386 :         ISOM_DECREASE_SIZE(ptr, 4);
    5097        2386 :         ptr->nb_entries = gf_bs_read_u32(bs);
    5098        2386 :         if (ptr->nb_entries > ptr->size / 4) {
    5099           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stco\n", ptr->nb_entries));
    5100             :                 return GF_ISOM_INVALID_FILE;
    5101             :         }
    5102             : 
    5103        2386 :         if (ptr->nb_entries) {
    5104        2017 :                 ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) );
    5105        2017 :                 if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
    5106        2017 :                 ptr->alloc_size = ptr->nb_entries;
    5107             : 
    5108       85622 :                 for (entries = 0; entries < ptr->nb_entries; entries++) {
    5109       83605 :                         ptr->offsets[entries] = gf_bs_read_u32(bs);
    5110             :                 }
    5111             :         }
    5112             :         return GF_OK;
    5113             : }
    5114             : 
    5115       24434 : GF_Box *stco_box_new()
    5116             : {
    5117       48868 :         ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
    5118       24434 :         return (GF_Box *)tmp;
    5119             : }
    5120             : 
    5121             : 
    5122             : 
    5123             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5124             : 
    5125        1932 : GF_Err stco_box_write(GF_Box *s, GF_BitStream *bs)
    5126             : {
    5127             :         GF_Err e;
    5128             :         u32 i;
    5129             :         GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
    5130        1932 :         e = gf_isom_full_box_write(s, bs);
    5131        1932 :         if (e) return e;
    5132        1932 :         gf_bs_write_u32(bs, ptr->nb_entries);
    5133       66733 :         for (i = 0; i < ptr->nb_entries; i++) {
    5134       64801 :                 gf_bs_write_u32(bs, ptr->offsets[i]);
    5135             :         }
    5136             :         return GF_OK;
    5137             : }
    5138             : 
    5139             : 
    5140        7727 : GF_Err stco_box_size(GF_Box *s)
    5141             : {
    5142             :         GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
    5143             : 
    5144        7727 :         ptr->size += 4 + (4 * ptr->nb_entries);
    5145        7727 :         return GF_OK;
    5146             : }
    5147             : 
    5148             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5149             : 
    5150             : 
    5151             : 
    5152           6 : void stdp_box_del(GF_Box *s)
    5153             : {
    5154             :         GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
    5155           6 :         if (ptr == NULL ) return;
    5156           6 :         if (ptr->priorities) gf_free(ptr->priorities);
    5157           6 :         gf_free(ptr);
    5158             : }
    5159             : 
    5160             : //this is called through stbl_read...
    5161           1 : GF_Err stdp_box_read(GF_Box *s, GF_BitStream *bs)
    5162             : {
    5163             :         u32 entry;
    5164             :         GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
    5165             : 
    5166             :         /*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/
    5167           1 :         if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2;
    5168           0 :         else if (ptr->nb_entries > ptr->size / 2) return GF_ISOM_INVALID_FILE;
    5169             : 
    5170           1 :         ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16));
    5171           1 :         if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
    5172           0 :         for (entry = 0; entry < ptr->nb_entries; entry++) {
    5173           0 :                 ptr->priorities[entry] = gf_bs_read_u16(bs);
    5174             :         }
    5175           1 :         ISOM_DECREASE_SIZE(ptr, (2*ptr->nb_entries) );
    5176           1 :         return GF_OK;
    5177             : }
    5178             : 
    5179           6 : GF_Box *stdp_box_new()
    5180             : {
    5181          12 :         ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
    5182           6 :         return (GF_Box *)tmp;
    5183             : }
    5184             : 
    5185             : 
    5186             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5187             : 
    5188           1 : GF_Err stdp_box_write(GF_Box *s, GF_BitStream *bs)
    5189             : {
    5190             :         GF_Err e;
    5191             :         u32 i;
    5192             :         GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
    5193           1 :         e = gf_isom_full_box_write(s, bs);
    5194           1 :         if (e) return e;
    5195             : 
    5196           0 :         for (i = 0; i < ptr->nb_entries; i++) {
    5197           0 :                 gf_bs_write_u16(bs, ptr->priorities[i]);
    5198             :         }
    5199             :         return GF_OK;
    5200             : }
    5201             : 
    5202           1 : GF_Err stdp_box_size(GF_Box *s)
    5203             : {
    5204             :         GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
    5205             : 
    5206           1 :         ptr->size += (2 * ptr->nb_entries);
    5207           1 :         return GF_OK;
    5208             : }
    5209             : 
    5210             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5211             : 
    5212             : 
    5213       25851 : void stsc_box_del(GF_Box *s)
    5214             : {
    5215             :         GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
    5216       25851 :         if (ptr == NULL) return;
    5217       25851 :         if (ptr->entries) gf_free(ptr->entries);
    5218       25851 :         gf_free(ptr);
    5219             : }
    5220             : 
    5221             : 
    5222        2386 : GF_Err stsc_box_read(GF_Box *s, GF_BitStream *bs)
    5223             : {
    5224             :         u32 i;
    5225             :         GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
    5226             : 
    5227        2386 :         ISOM_DECREASE_SIZE(ptr, 4);
    5228        2386 :         ptr->nb_entries = gf_bs_read_u32(bs);
    5229             : 
    5230        2386 :         if (ptr->nb_entries > ptr->size / 12) {
    5231           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsc\n", ptr->nb_entries));
    5232             :                 return GF_ISOM_INVALID_FILE;
    5233             :         }
    5234             : 
    5235        2386 :         ptr->alloc_size = ptr->nb_entries;
    5236        2386 :         ptr->entries = NULL;
    5237        2386 :         if (ptr->nb_entries) {
    5238        2017 :                 ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size);
    5239        2017 :                 if (!ptr->entries) return GF_OUT_OF_MEM;
    5240             :         }
    5241             : 
    5242        6608 :         for (i = 0; i < ptr->nb_entries; i++) {
    5243        6608 :                 ptr->entries[i].firstChunk = gf_bs_read_u32(bs);
    5244        6608 :                 ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs);
    5245        6608 :                 ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs);
    5246        6608 :                 ptr->entries[i].isEdited = 0;
    5247        6608 :                 ptr->entries[i].nextChunk = 0;
    5248        6608 :                 if (!ptr->entries[i].firstChunk) {
    5249           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] invalid first chunk 0 in stsc entry\n", ptr->nb_entries));
    5250             :                         return GF_ISOM_INVALID_FILE;
    5251             :                 }
    5252             : 
    5253             :                 //update the next chunk in the previous entry
    5254        6608 :                 if (i) ptr->entries[i-1].nextChunk = ptr->entries[i].firstChunk;
    5255             :         }
    5256        2386 :         ptr->currentIndex = 0;
    5257        2386 :         ptr->firstSampleInCurrentChunk = 0;
    5258        2386 :         ptr->currentChunk = 0;
    5259        2386 :         ptr->ghostNumber = 0;
    5260        2386 :         return GF_OK;
    5261             : }
    5262             : 
    5263       25851 : GF_Box *stsc_box_new()
    5264             : {
    5265       51702 :         ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
    5266       25851 :         return (GF_Box *)tmp;
    5267             : }
    5268             : 
    5269             : 
    5270             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5271             : 
    5272        1933 : GF_Err stsc_box_write(GF_Box *s, GF_BitStream *bs)
    5273             : {
    5274             :         GF_Err e;
    5275             :         u32 i;
    5276             :         GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
    5277             : 
    5278        1933 :         e = gf_isom_full_box_write(s, bs);
    5279        1933 :         if (e) return e;
    5280        1933 :         gf_bs_write_u32(bs, ptr->nb_entries);
    5281        7233 :         for (i=0; i<ptr->nb_entries; i++) {
    5282        5300 :                 gf_bs_write_u32(bs, ptr->entries[i].firstChunk);
    5283        5300 :                 gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk);
    5284        5300 :                 gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex);
    5285             :         }
    5286             :         return GF_OK;
    5287             : }
    5288             : 
    5289        7730 : GF_Err stsc_box_size(GF_Box *s)
    5290             : {
    5291             :         GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
    5292             : 
    5293        7730 :         ptr->size += 4 + (12 * ptr->nb_entries);
    5294        7730 :         return GF_OK;
    5295             : }
    5296             : 
    5297             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5298             : 
    5299        5263 : void stsd_box_del(GF_Box *s)
    5300             : {
    5301             :         GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
    5302        5263 :         if (ptr == NULL) return;
    5303        5263 :         gf_free(ptr);
    5304             : }
    5305             : 
    5306        2995 : GF_Err stsd_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    5307             : {
    5308             :         GF_UnknownBox *def;
    5309        2995 :         if (!a) return GF_OK;
    5310             : 
    5311        2995 :         if (is_rem || gf_box_valid_in_parent(a, "stsd")) {
    5312             :                 return GF_OK;
    5313             :         }
    5314           6 :         switch (a->type) {
    5315             :         //unknown sample description: we need a specific box to handle the data ref index
    5316             :         //rather than a default box ...
    5317           6 :         case GF_ISOM_BOX_TYPE_UNKNOWN:
    5318             :                 def = (GF_UnknownBox *)a;
    5319             :                 /*we need at least 8 bytes for unknown sample entries*/
    5320           6 :                 if (def->dataSize < 8) {
    5321           0 :                         gf_isom_box_del_parent(&s->child_boxes, a);
    5322           0 :                         return GF_ISOM_INVALID_MEDIA;
    5323             :                 }
    5324             :                 return GF_OK;
    5325             : 
    5326           0 :         default:
    5327           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type)));
    5328             :                 return GF_ISOM_INVALID_FILE;
    5329             :         }
    5330             : }
    5331             : 
    5332             : 
    5333        3106 : GF_Err stsd_box_read(GF_Box *s, GF_BitStream *bs)
    5334             : {
    5335        3106 :         ISOM_DECREASE_SIZE(s, 4)
    5336        3106 :         gf_bs_read_u32(bs);
    5337             : 
    5338        3106 :         return gf_isom_box_array_read_ex(s, bs, GF_ISOM_BOX_TYPE_STSD);
    5339             : }
    5340             : 
    5341        5263 : GF_Box *stsd_box_new()
    5342             : {
    5343       10526 :         ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
    5344        5263 :         tmp->child_boxes = gf_list_new();
    5345        5263 :         return (GF_Box *)tmp;
    5346             : }
    5347             : 
    5348             : 
    5349             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5350             : 
    5351        3178 : GF_Err stsd_box_write(GF_Box *s, GF_BitStream *bs)
    5352             : {
    5353             :         GF_Err e;
    5354             :         u32 nb_entries;
    5355             :         GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
    5356             : 
    5357        3178 :         e = gf_isom_full_box_write(s, bs);
    5358        3178 :         if (e) return e;
    5359        3178 :         nb_entries = gf_list_count(ptr->child_boxes);
    5360        3178 :         gf_bs_write_u32(bs, nb_entries);
    5361        3178 :         return GF_OK;
    5362             : }
    5363             : 
    5364        6127 : GF_Err stsd_box_size(GF_Box *s)
    5365             : {
    5366             :         GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
    5367        6127 :         ptr->size += 4;
    5368        6127 :         return GF_OK;
    5369             : }
    5370             : 
    5371             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5372             : 
    5373             : 
    5374           9 : void stsh_box_del(GF_Box *s)
    5375             : {
    5376           9 :         u32 i = 0;
    5377             :         GF_StshEntry *ent;
    5378             :         GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
    5379           9 :         if (ptr == NULL) return;
    5380          21 :         while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) {
    5381          12 :                 gf_free(ent);
    5382             :         }
    5383           9 :         gf_list_del(ptr->entries);
    5384           9 :         gf_free(ptr);
    5385             : }
    5386             : 
    5387             : 
    5388             : 
    5389           1 : GF_Err stsh_box_read(GF_Box *s, GF_BitStream *bs)
    5390             : {
    5391             :         GF_Err e;
    5392             :         u32 count, i;
    5393             :         GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
    5394             : 
    5395           1 :         ISOM_DECREASE_SIZE(s, 4)
    5396           1 :         count = gf_bs_read_u32(bs);
    5397           1 :         if (ptr->size / 8 < count)
    5398             :                 return GF_ISOM_INVALID_FILE;
    5399             : 
    5400           0 :         for (i = 0; i < count; i++) {
    5401           0 :                 GF_StshEntry *ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry));
    5402           0 :                 if (!ent) return GF_OUT_OF_MEM;
    5403           0 :                 ent->shadowedSampleNumber = gf_bs_read_u32(bs);
    5404           0 :                 ent->syncSampleNumber = gf_bs_read_u32(bs);
    5405           0 :                 e = gf_list_add(ptr->entries, ent);
    5406           0 :                 if (e) return e;
    5407             :         }
    5408             :         return GF_OK;
    5409             : }
    5410             : 
    5411           9 : GF_Box *stsh_box_new()
    5412             : {
    5413          18 :         ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);
    5414             : 
    5415           9 :         tmp->entries = gf_list_new();
    5416           9 :         if (!tmp->entries) {
    5417           0 :                 gf_free(tmp);
    5418           0 :                 return NULL;
    5419             :         }
    5420             :         return (GF_Box *)tmp;
    5421             : }
    5422             : 
    5423             : 
    5424             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5425             : 
    5426           7 : GF_Err stsh_box_write(GF_Box *s, GF_BitStream *bs)
    5427             : {
    5428             :         GF_Err e;
    5429             :         u32 i;
    5430             :         GF_StshEntry *ent;
    5431             :         GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
    5432             : 
    5433           7 :         e = gf_isom_full_box_write(s, bs);
    5434           7 :         if (e) return e;
    5435           7 :         gf_bs_write_u32(bs, gf_list_count(ptr->entries));
    5436           7 :         i=0;
    5437          26 :         while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
    5438          12 :                 gf_bs_write_u32(bs, ent->shadowedSampleNumber);
    5439          12 :                 gf_bs_write_u32(bs, ent->syncSampleNumber);
    5440             :         }
    5441             :         return GF_OK;
    5442             : }
    5443             : 
    5444          19 : GF_Err stsh_box_size(GF_Box *s)
    5445             : {
    5446             :         GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
    5447          19 :         ptr->size += 4 + (8 * gf_list_count(ptr->entries));
    5448          19 :         return GF_OK;
    5449             : }
    5450             : 
    5451             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5452             : 
    5453             : 
    5454             : 
    5455       18498 : void stss_box_del(GF_Box *s)
    5456             : {
    5457             :         GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
    5458       18498 :         if (ptr == NULL) return;
    5459       18498 :         if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers);
    5460       18498 :         gf_free(ptr);
    5461             : }
    5462             : 
    5463        1072 : GF_Err stss_box_read(GF_Box *s, GF_BitStream *bs)
    5464             : {
    5465             :         u32 i;
    5466             :         GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
    5467             : 
    5468        1072 :         ISOM_DECREASE_SIZE(ptr, 4);
    5469        1072 :         ptr->nb_entries = gf_bs_read_u32(bs);
    5470        1072 :         if (ptr->size / 4 <  ptr->nb_entries) {
    5471           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stss\n", ptr->nb_entries));
    5472             :                 return GF_ISOM_INVALID_FILE;
    5473             :         }
    5474             : 
    5475        1072 :         ptr->alloc_size = ptr->nb_entries;
    5476        1072 :         ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32));
    5477        1072 :         if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM;
    5478             : 
    5479       19261 :         for (i = 0; i < ptr->nb_entries; i++) {
    5480       19261 :                 ptr->sampleNumbers[i] = gf_bs_read_u32(bs);
    5481             :         }
    5482             :         return GF_OK;
    5483             : }
    5484             : 
    5485       18498 : GF_Box *stss_box_new()
    5486             : {
    5487       36996 :         ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
    5488       18498 :         return (GF_Box*)tmp;
    5489             : }
    5490             : 
    5491             : 
    5492             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5493             : 
    5494         784 : GF_Err stss_box_write(GF_Box *s, GF_BitStream *bs)
    5495             : {
    5496             :         GF_Err e;
    5497             :         u32 i;
    5498             :         GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
    5499             : 
    5500         784 :         e = gf_isom_full_box_write(s, bs);
    5501         784 :         if (e) return e;
    5502         784 :         gf_bs_write_u32(bs, ptr->nb_entries);
    5503       12231 :         for (i = 0; i < ptr->nb_entries; i++) {
    5504       11447 :                 gf_bs_write_u32(bs, ptr->sampleNumbers[i]);
    5505             :         }
    5506             :         return GF_OK;
    5507             : }
    5508             : 
    5509        2288 : GF_Err stss_box_size(GF_Box *s)
    5510             : {
    5511             :         GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
    5512        2288 :         ptr->size += 4 + (4 * ptr->nb_entries);
    5513        2288 :         return GF_OK;
    5514             : }
    5515             : 
    5516             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5517             : 
    5518             : 
    5519       22569 : void stsz_box_del(GF_Box *s)
    5520             : {
    5521             :         GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
    5522       22569 :         if (ptr == NULL) return;
    5523       22569 :         if (ptr->sizes) gf_free(ptr->sizes);
    5524       22569 :         gf_free(ptr);
    5525             : }
    5526             : 
    5527             : 
    5528        2387 : GF_Err stsz_box_read(GF_Box *s, GF_BitStream *bs)
    5529             : {
    5530             :         u32 i, estSize;
    5531             :         GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
    5532        2387 :         if (ptr == NULL) return GF_BAD_PARAM;
    5533             : 
    5534             :         //support for CompactSizes
    5535        2387 :         if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
    5536        2386 :                 ISOM_DECREASE_SIZE(ptr, 8);
    5537        2386 :                 ptr->sampleSize = gf_bs_read_u32(bs);
    5538        2386 :                 ptr->sampleCount = gf_bs_read_u32(bs);
    5539             :         } else {
    5540             :                 //24-reserved
    5541           1 :                 ISOM_DECREASE_SIZE(ptr, 8);
    5542           1 :                 gf_bs_read_int(bs, 24);
    5543           1 :                 i = gf_bs_read_u8(bs);
    5544           1 :                 ptr->sampleCount = gf_bs_read_u32(bs);
    5545             :                 switch (i) {
    5546           0 :                 case 4:
    5547             :                 case 8:
    5548             :                 case 16:
    5549           0 :                         ptr->sampleSize = i;
    5550           0 :                         break;
    5551           1 :                 default:
    5552             :                         //try to fix the file
    5553             :                         //no samples, no parsing pb
    5554           1 :                         if (!ptr->sampleCount) {
    5555           1 :                                 ptr->sampleSize = 16;
    5556           1 :                                 return GF_OK;
    5557             :                         }
    5558           0 :                         estSize = (u32) (ptr->size) / ptr->sampleCount;
    5559           0 :                         if (!estSize && ((ptr->sampleCount+1)/2 == (ptr->size)) ) {
    5560           0 :                                 ptr->sampleSize = 4;
    5561           0 :                                 break;
    5562           0 :                         } else if (estSize == 1 || estSize == 2) {
    5563           0 :                                 ptr->sampleSize = 8 * estSize;
    5564             :                         } else {
    5565             :                                 return GF_ISOM_INVALID_FILE;
    5566             :                         }
    5567             :                 }
    5568             :         }
    5569        2386 :         if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
    5570        2386 :                 if (! ptr->sampleSize && ptr->sampleCount) {
    5571        1626 :                         if (ptr->sampleCount > ptr->size / 4) {
    5572           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
    5573             :                                 return GF_ISOM_INVALID_FILE;
    5574             :                         }
    5575        1626 :                         ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
    5576        1626 :                         if (! ptr->sizes) return GF_OUT_OF_MEM;
    5577        1626 :                         ptr->alloc_size = ptr->sampleCount;
    5578      880304 :                         for (i = 0; i < ptr->sampleCount; i++) {
    5579      878678 :                                 ptr->sizes[i] = gf_bs_read_u32(bs);
    5580      878678 :                                 if (ptr->max_size < ptr->sizes[i])
    5581        7825 :                                         ptr->max_size = ptr->sizes[i];
    5582      878678 :                                 ptr->total_size += ptr->sizes[i];
    5583      878678 :                                 ptr->total_samples++;
    5584             :                         }
    5585             :                 }
    5586             :         } else {
    5587           0 :                 if (ptr->sampleSize==4) {
    5588           0 :                         if (ptr->sampleCount / 2 > ptr->size) {
    5589           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
    5590             :                                 return GF_ISOM_INVALID_FILE;
    5591             :                         }
    5592             :                 } else {
    5593           0 :                         if (ptr->sampleCount > ptr->size / (ptr->sampleSize/8)) {
    5594           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
    5595             :                                 return GF_ISOM_INVALID_FILE;
    5596             :                         }
    5597             :                 }
    5598             :                 //note we could optimize the mem usage by keeping the table compact
    5599             :                 //in memory. But that would complicate both caching and editing
    5600             :                 //we therefore keep all sizes as u32 and uncompress the table
    5601           0 :                 ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
    5602           0 :                 if (! ptr->sizes) return GF_OUT_OF_MEM;
    5603           0 :                 ptr->alloc_size = ptr->sampleCount;
    5604             : 
    5605           0 :                 for (i = 0; i < ptr->sampleCount; ) {
    5606           0 :                         switch (ptr->sampleSize) {
    5607           0 :                         case 4:
    5608           0 :                                 ptr->sizes[i] = gf_bs_read_int(bs, 4);
    5609           0 :                                 if (i+1 < ptr->sampleCount) {
    5610           0 :                                         ptr->sizes[i+1] = gf_bs_read_int(bs, 4);
    5611             :                                 } else {
    5612             :                                         //0 padding in odd sample count
    5613           0 :                                         gf_bs_read_int(bs, 4);
    5614             :                                 }
    5615           0 :                                 i += 2;
    5616           0 :                                 break;
    5617           0 :                         default:
    5618           0 :                                 ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize);
    5619           0 :                                 i += 1;
    5620           0 :                                 break;
    5621             :                         }
    5622           0 :                         if (ptr->max_size < ptr->sizes[i])
    5623           0 :                                 ptr->max_size = ptr->sizes[i];
    5624           0 :                         ptr->total_size += ptr->sizes[i];
    5625           0 :                         ptr->total_samples++;
    5626             :                 }
    5627             :         }
    5628             :         return GF_OK;
    5629             : }
    5630             : 
    5631       22569 : GF_Box *stsz_box_new()
    5632             : {
    5633       45138 :         ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);
    5634             : 
    5635             :         //type is unknown here, can be regular or compact table
    5636       22569 :         return (GF_Box *)tmp;
    5637             : }
    5638             : 
    5639             : 
    5640             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5641             : 
    5642        1934 : GF_Err stsz_box_write(GF_Box *s, GF_BitStream *bs)
    5643             : {
    5644             :         GF_Err e;
    5645             :         u32 i;
    5646             :         GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
    5647             : 
    5648        1934 :         e = gf_isom_full_box_write(s, bs);
    5649        1934 :         if (e) return e;
    5650             :         //in both versions this is still valid
    5651        1934 :         if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
    5652        1932 :                 gf_bs_write_u32(bs, ptr->sampleSize);
    5653             :         } else {
    5654           2 :                 gf_bs_write_u24(bs, 0);
    5655           2 :                 gf_bs_write_u8(bs, ptr->sampleSize);
    5656             :         }
    5657        1934 :         gf_bs_write_u32(bs, ptr->sampleCount);
    5658             : 
    5659        1934 :         if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
    5660        1932 :                 if (! ptr->sampleSize) {
    5661      533854 :                         for (i = 0; i < ptr->sampleCount; i++) {
    5662      533854 :                                 gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0);
    5663             :                         }
    5664             :                 }
    5665             :         } else {
    5666          13 :                 for (i = 0; i < ptr->sampleCount; ) {
    5667          11 :                         switch (ptr->sampleSize) {
    5668           0 :                         case 4:
    5669           0 :                                 gf_bs_write_int(bs, ptr->sizes[i], 4);
    5670           0 :                                 if (i+1 < ptr->sampleCount) {
    5671           0 :                                         gf_bs_write_int(bs, ptr->sizes[i+1], 4);
    5672             :                                 } else {
    5673             :                                         //0 padding in odd sample count
    5674           0 :                                         gf_bs_write_int(bs, 0, 4);
    5675             :                                 }
    5676           0 :                                 i += 2;
    5677           0 :                                 break;
    5678          11 :                         default:
    5679          11 :                                 gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize);
    5680          11 :                                 i += 1;
    5681          11 :                                 break;
    5682             :                         }
    5683             :                 }
    5684             :         }
    5685             :         return GF_OK;
    5686             : }
    5687             : 
    5688        4883 : GF_Err stsz_box_size(GF_Box *s)
    5689             : {
    5690             :         u32 i, fieldSize, size;
    5691             :         GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
    5692             : 
    5693        4883 :         ptr->size += 8;
    5694        4883 :         if (!ptr->sampleCount) return GF_OK;
    5695             : 
    5696             :         //regular table
    5697        4419 :         if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
    5698        4416 :                 if (ptr->sampleSize) return GF_OK;
    5699        3506 :                 ptr->size += (4 * ptr->sampleCount);
    5700        3506 :                 return GF_OK;
    5701             :         }
    5702             : 
    5703             :         fieldSize = 4;
    5704           3 :         size = ptr->sizes[0];
    5705             : 
    5706          36 :         for (i=0; i < ptr->sampleCount; i++) {
    5707          33 :                 if (ptr->sizes[i] <= 0xF) continue;
    5708             :                 //switch to 8-bit table
    5709          15 :                 else if (ptr->sizes[i] <= 0xFF) {
    5710             :                         fieldSize = 8;
    5711             :                 }
    5712             :                 //switch to 16-bit table
    5713           0 :                 else if (ptr->sizes[i] <= 0xFFFF) {
    5714             :                         fieldSize = 16;
    5715             :                 }
    5716             :                 //switch to 32-bit table
    5717             :                 else {
    5718             :                         fieldSize = 32;
    5719             :                 }
    5720             : 
    5721             :                 //check the size
    5722          15 :                 if (size != ptr->sizes[i]) size = 0;
    5723             :         }
    5724             :         //if all samples are of the same size, switch to regular (more compact)
    5725           3 :         if (size) {
    5726           0 :                 ptr->type = GF_ISOM_BOX_TYPE_STSZ;
    5727           0 :                 ptr->sampleSize = size;
    5728           0 :                 gf_free(ptr->sizes);
    5729           0 :                 ptr->sizes = NULL;
    5730             :         }
    5731             : 
    5732           3 :         if (fieldSize == 32) {
    5733             :                 //oops, doesn't fit in a compact table
    5734           0 :                 ptr->type = GF_ISOM_BOX_TYPE_STSZ;
    5735           0 :                 ptr->size += (4 * ptr->sampleCount);
    5736           0 :                 return GF_OK;
    5737             :         }
    5738             : 
    5739             :         //make sure we are a compact table (no need to change the mem representation)
    5740           3 :         ptr->type = GF_ISOM_BOX_TYPE_STZ2;
    5741           3 :         ptr->sampleSize = fieldSize;
    5742           3 :         if (fieldSize == 4) {
    5743             :                 //do not forget the 0 padding field for odd count
    5744           0 :                 ptr->size += (ptr->sampleCount + 1) / 2;
    5745             :         } else {
    5746           3 :                 ptr->size += (ptr->sampleCount) * (fieldSize/8);
    5747             :         }
    5748             :         return GF_OK;
    5749             : }
    5750             : 
    5751             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5752             : 
    5753             : 
    5754       22566 : void stts_box_del(GF_Box *s)
    5755             : {
    5756             :         GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
    5757       22566 :         if (ptr->entries) gf_free(ptr->entries);
    5758       22566 :         gf_free(ptr);
    5759       22566 : }
    5760             : 
    5761             : 
    5762        2386 : GF_Err stts_box_read(GF_Box *s, GF_BitStream *bs)
    5763             : {
    5764             :         u32 i;
    5765             :         GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
    5766             : 
    5767             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5768        2386 :         ptr->w_LastDTS = 0;
    5769             : #endif
    5770             : 
    5771        2386 :         ISOM_DECREASE_SIZE(ptr, 4);
    5772        2386 :         ptr->nb_entries = gf_bs_read_u32(bs);
    5773        2386 :         if (ptr->size / 8 < ptr->nb_entries) {
    5774           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stts\n", ptr->nb_entries));
    5775             :                 return GF_ISOM_INVALID_FILE;
    5776             :         }
    5777             : 
    5778        2386 :         ptr->alloc_size = ptr->nb_entries;
    5779        2386 :         ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size);
    5780        2386 :         if (!ptr->entries) return GF_OUT_OF_MEM;
    5781             : 
    5782       18723 :         for (i=0; i<ptr->nb_entries; i++) {
    5783       18723 :                 ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
    5784       18723 :                 ptr->entries[i].sampleDelta = gf_bs_read_u32(bs);
    5785             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5786       18723 :                 ptr->w_currentSampleNum += ptr->entries[i].sampleCount;
    5787       18723 :                 ptr->w_LastDTS += (u64)ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta;
    5788             : #endif
    5789       18723 :                 if (ptr->max_ts_delta<ptr->entries[i].sampleDelta)
    5790        2181 :                         ptr->max_ts_delta = ptr->entries[i].sampleDelta;
    5791             : 
    5792       18723 :                 if (!ptr->entries[i].sampleDelta) {
    5793         166 :                         if ((i+1<ptr->nb_entries) ) {
    5794           0 :                                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stts entry with sample_delta=0 - forbidden ! Fixing to 1\n" ));
    5795           0 :                                 ptr->entries[i].sampleDelta = 1;
    5796         166 :                         } else if (ptr->entries[i].sampleCount>1) {
    5797           0 :                                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one stts entry at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n" ));
    5798           0 :                                 ptr->entries[i].sampleDelta = 1;
    5799             :                         }
    5800             :                 }
    5801             :                 //cf issue 1644: some media streams may have sample duration > 2^31 (ttml mostly), we cannot patch this
    5802             :                 //for now we disable the check, one opt could be to have the check only for some media types, or only for the first entry
    5803             : #if 0
    5804             :                 else if ((s32) ptr->entries[i].sampleDelta < 0) {
    5805             :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] stts entry %d has negative duration %d - forbidden ! Fixing to 1, sync may get lost (consider reimport raw media)\n", i, (s32) ptr->entries[i].sampleDelta ));
    5806             :                         ptr->entries[i].sampleDelta = 1;
    5807             :                 }
    5808             : #endif
    5809             : 
    5810             :         }
    5811        2386 :         ISOM_DECREASE_SIZE(ptr, ptr->nb_entries*8);
    5812             : 
    5813             :         //remove the last sample delta.
    5814             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5815        2386 :         if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta;
    5816             : #endif
    5817             :         return GF_OK;
    5818             : }
    5819             : 
    5820       22566 : GF_Box *stts_box_new()
    5821             : {
    5822       45132 :         ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
    5823       22566 :         return (GF_Box *)tmp;
    5824             : }
    5825             : 
    5826             : 
    5827             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5828             : 
    5829        1933 : GF_Err stts_box_write(GF_Box *s, GF_BitStream *bs)
    5830             : {
    5831             :         GF_Err e;
    5832             :         u32 i;
    5833             :         GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
    5834             : 
    5835        1933 :         e = gf_isom_full_box_write(s, bs);
    5836        1933 :         if (e) return e;
    5837        1933 :         gf_bs_write_u32(bs, ptr->nb_entries);
    5838       15767 :         for (i=0; i<ptr->nb_entries; i++) {
    5839       13834 :                 gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
    5840       13834 :                 gf_bs_write_u32(bs, ptr->entries[i].sampleDelta);
    5841             :         }
    5842             :         return GF_OK;
    5843             : }
    5844             : 
    5845        4882 : GF_Err stts_box_size(GF_Box *s)
    5846             : {
    5847             :         GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
    5848        4882 :         ptr->size += 4 + (8 * ptr->nb_entries);
    5849        4882 :         return GF_OK;
    5850             : }
    5851             : 
    5852             : 
    5853             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5854             : 
    5855             : 
    5856             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    5857             : 
    5858        8829 : void tfhd_box_del(GF_Box *s)
    5859             : {
    5860             :         GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
    5861        8829 :         if (ptr == NULL) return;
    5862        8829 :         gf_free(ptr);
    5863             : }
    5864             : 
    5865        4243 : GF_Err tfhd_box_read(GF_Box *s, GF_BitStream *bs)
    5866             : {
    5867             :         GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
    5868             : 
    5869        4243 :         ISOM_DECREASE_SIZE(ptr, 4);
    5870        4243 :         ptr->trackID = gf_bs_read_u32(bs);
    5871             : 
    5872             :         //The rest depends on the flags
    5873        4243 :         if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
    5874          51 :                 ISOM_DECREASE_SIZE(ptr, 8);
    5875          51 :                 ptr->base_data_offset = gf_bs_read_u64(bs);
    5876             :         }
    5877        4243 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
    5878         199 :                 ISOM_DECREASE_SIZE(ptr, 4);
    5879         199 :                 ptr->sample_desc_index = gf_bs_read_u32(bs);
    5880             :         }
    5881        4243 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
    5882         266 :                 ISOM_DECREASE_SIZE(ptr, 4);
    5883         266 :                 ptr->def_sample_duration = gf_bs_read_u32(bs);
    5884             :         }
    5885        4243 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
    5886         174 :                 ISOM_DECREASE_SIZE(ptr, 4);
    5887         174 :                 ptr->def_sample_size = gf_bs_read_u32(bs);
    5888             :         }
    5889        4243 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
    5890         421 :                 ISOM_DECREASE_SIZE(ptr, 4);
    5891         421 :                 ptr->def_sample_flags = gf_bs_read_u32(bs);
    5892             :         }
    5893             :         return GF_OK;
    5894             : }
    5895             : 
    5896        8829 : GF_Box *tfhd_box_new()
    5897             : {
    5898       17658 :         ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
    5899             :         //NO FLAGS SET BY DEFAULT
    5900        8829 :         return (GF_Box *)tmp;
    5901             : }
    5902             : 
    5903             : 
    5904             : 
    5905             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5906             : 
    5907             : 
    5908        3939 : GF_Err tfhd_box_write(GF_Box *s, GF_BitStream *bs)
    5909             : {
    5910             :         GF_Err e;
    5911             :         GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *) s;
    5912        3939 :         if (!s) return GF_BAD_PARAM;
    5913             : 
    5914        3939 :         e = gf_isom_full_box_write(s, bs);
    5915        3939 :         if (e) return e;
    5916        3939 :         gf_bs_write_u32(bs, ptr->trackID);
    5917             : 
    5918             :         //The rest depends on the flags
    5919        3939 :         if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
    5920          97 :                 gf_bs_write_u64(bs, ptr->base_data_offset);
    5921             :         }
    5922        3939 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
    5923         306 :                 gf_bs_write_u32(bs, ptr->sample_desc_index);
    5924             :         }
    5925        3939 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
    5926         374 :                 gf_bs_write_u32(bs, ptr->def_sample_duration);
    5927             :         }
    5928        3939 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
    5929         179 :                 gf_bs_write_u32(bs, ptr->def_sample_size);
    5930             :         }
    5931        3939 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
    5932         348 :                 gf_bs_write_u32(bs, ptr->def_sample_flags);
    5933             :         }
    5934             :         return GF_OK;
    5935             : }
    5936             : 
    5937       12092 : GF_Err tfhd_box_size(GF_Box *s)
    5938             : {
    5939             :         GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
    5940       12092 :         ptr->size += 4;
    5941             : 
    5942             :         //The rest depends on the flags
    5943       12092 :         if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8;
    5944       12092 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4;
    5945       12092 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4;
    5946       12092 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4;
    5947       12092 :         if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4;
    5948       12092 :         return GF_OK;
    5949             : }
    5950             : 
    5951             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5952             : 
    5953             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    5954             : 
    5955             : 
    5956         121 : void tims_box_del(GF_Box *s)
    5957             : {
    5958             :         GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
    5959         121 :         gf_free(tims);
    5960         121 : }
    5961             : 
    5962          46 : GF_Err tims_box_read(GF_Box *s, GF_BitStream *bs)
    5963             : {
    5964             :         GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
    5965          46 :         ISOM_DECREASE_SIZE(ptr, 4);
    5966          46 :         ptr->timeScale = gf_bs_read_u32(bs);
    5967          46 :         return GF_OK;
    5968             : }
    5969             : 
    5970         121 : GF_Box *tims_box_new()
    5971             : {
    5972         242 :         ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
    5973         121 :         return (GF_Box *)tmp;
    5974             : }
    5975             : 
    5976             : #ifndef GPAC_DISABLE_ISOM_WRITE
    5977             : 
    5978          74 : GF_Err tims_box_write(GF_Box *s, GF_BitStream *bs)
    5979             : {
    5980             :         GF_Err e;
    5981             :         GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
    5982          74 :         if (ptr == NULL) return GF_BAD_PARAM;
    5983          74 :         e = gf_isom_box_write_header(s, bs);
    5984          74 :         if (e) return e;
    5985          74 :         gf_bs_write_u32(bs, ptr->timeScale);
    5986          74 :         return GF_OK;
    5987             : }
    5988             : 
    5989         220 : GF_Err tims_box_size(GF_Box *s)
    5990             : {
    5991         220 :         s->size += 4;
    5992         220 :         return GF_OK;
    5993             : }
    5994             : 
    5995             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    5996             : 
    5997             : 
    5998        4126 : void tkhd_box_del(GF_Box *s)
    5999             : {
    6000             :         GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
    6001        4126 :         if (ptr == NULL) return;
    6002        4126 :         gf_free(ptr);
    6003        4126 :         return;
    6004             : }
    6005             : 
    6006             : 
    6007        3106 : GF_Err tkhd_box_read(GF_Box *s, GF_BitStream *bs)
    6008             : {
    6009             :         GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
    6010             : 
    6011        3106 :         if (ptr->version == 1) {
    6012           0 :                 ISOM_DECREASE_SIZE(ptr, 32);
    6013           0 :                 ptr->creationTime = gf_bs_read_u64(bs);
    6014           0 :                 ptr->modificationTime = gf_bs_read_u64(bs);
    6015           0 :                 ptr->trackID = gf_bs_read_u32(bs);
    6016           0 :                 ptr->reserved1 = gf_bs_read_u32(bs);
    6017           0 :                 ptr->duration = gf_bs_read_u64(bs);
    6018             :         } else {
    6019        3106 :                 ISOM_DECREASE_SIZE(ptr, 20);
    6020        3106 :                 ptr->creationTime = gf_bs_read_u32(bs);
    6021        3106 :                 ptr->modificationTime = gf_bs_read_u32(bs);
    6022        3106 :                 ptr->trackID = gf_bs_read_u32(bs);
    6023        3106 :                 ptr->reserved1 = gf_bs_read_u32(bs);
    6024        3106 :                 ptr->duration = gf_bs_read_u32(bs);
    6025             :         }
    6026        3106 :         ptr->initial_duration = ptr->duration;
    6027             : 
    6028        3106 :         ISOM_DECREASE_SIZE(ptr, 60);
    6029        3106 :         ptr->reserved2[0] = gf_bs_read_u32(bs);
    6030        3106 :         ptr->reserved2[1] = gf_bs_read_u32(bs);
    6031        3106 :         ptr->layer = gf_bs_read_u16(bs);
    6032        3106 :         ptr->alternate_group = gf_bs_read_u16(bs);
    6033        3106 :         ptr->volume = gf_bs_read_u16(bs);
    6034        3106 :         ptr->reserved3 = gf_bs_read_u16(bs);
    6035        3106 :         ptr->matrix[0] = gf_bs_read_u32(bs);
    6036        3106 :         ptr->matrix[1] = gf_bs_read_u32(bs);
    6037        3106 :         ptr->matrix[2] = gf_bs_read_u32(bs);
    6038        3106 :         ptr->matrix[3] = gf_bs_read_u32(bs);
    6039        3106 :         ptr->matrix[4] = gf_bs_read_u32(bs);
    6040        3106 :         ptr->matrix[5] = gf_bs_read_u32(bs);
    6041        3106 :         ptr->matrix[6] = gf_bs_read_u32(bs);
    6042        3106 :         ptr->matrix[7] = gf_bs_read_u32(bs);
    6043        3106 :         ptr->matrix[8] = gf_bs_read_u32(bs);
    6044        3106 :         ptr->width = gf_bs_read_u32(bs);
    6045        3106 :         ptr->height = gf_bs_read_u32(bs);
    6046        3106 :         return GF_OK;
    6047             : }
    6048             : 
    6049        4126 : GF_Box *tkhd_box_new()
    6050             : {
    6051        8252 :         ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
    6052        4126 :         tmp->matrix[0] = 0x00010000;
    6053        4126 :         tmp->matrix[4] = 0x00010000;
    6054        4126 :         tmp->matrix[8] = 0x40000000;
    6055        4126 :         return (GF_Box *)tmp;
    6056             : }
    6057             : 
    6058             : 
    6059             : 
    6060             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6061             : 
    6062        3176 : GF_Err tkhd_box_write(GF_Box *s, GF_BitStream *bs)
    6063             : {
    6064             :         GF_Err e;
    6065             :         GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
    6066             : 
    6067        3176 :         e = gf_isom_full_box_write(s, bs);
    6068        3176 :         if (e) return e;
    6069        3176 :         if (ptr->version == 1) {
    6070           0 :                 gf_bs_write_u64(bs, ptr->creationTime);
    6071           0 :                 gf_bs_write_u64(bs, ptr->modificationTime);
    6072           0 :                 gf_bs_write_u32(bs, ptr->trackID);
    6073           0 :                 gf_bs_write_u32(bs, ptr->reserved1);
    6074           0 :                 gf_bs_write_u64(bs, ptr->duration);
    6075             :         } else {
    6076        3176 :                 gf_bs_write_u32(bs, (u32) ptr->creationTime);
    6077        3176 :                 gf_bs_write_u32(bs, (u32) ptr->modificationTime);
    6078        3176 :                 gf_bs_write_u32(bs, ptr->trackID);
    6079        3176 :                 gf_bs_write_u32(bs, ptr->reserved1);
    6080        3176 :                 gf_bs_write_u32(bs, (u32) ptr->duration);
    6081             :         }
    6082        3176 :         gf_bs_write_u32(bs, ptr->reserved2[0]);
    6083        3176 :         gf_bs_write_u32(bs, ptr->reserved2[1]);
    6084        3176 :         gf_bs_write_u16(bs, ptr->layer);
    6085        3176 :         gf_bs_write_u16(bs, ptr->alternate_group);
    6086        3176 :         gf_bs_write_u16(bs, ptr->volume);
    6087        3176 :         gf_bs_write_u16(bs, ptr->reserved3);
    6088        3176 :         gf_bs_write_u32(bs, ptr->matrix[0]);
    6089        3176 :         gf_bs_write_u32(bs, ptr->matrix[1]);
    6090        3176 :         gf_bs_write_u32(bs, ptr->matrix[2]);
    6091        3176 :         gf_bs_write_u32(bs, ptr->matrix[3]);
    6092        3176 :         gf_bs_write_u32(bs, ptr->matrix[4]);
    6093        3176 :         gf_bs_write_u32(bs, ptr->matrix[5]);
    6094        3176 :         gf_bs_write_u32(bs, ptr->matrix[6]);
    6095        3176 :         gf_bs_write_u32(bs, ptr->matrix[7]);
    6096        3176 :         gf_bs_write_u32(bs, ptr->matrix[8]);
    6097        3176 :         gf_bs_write_u32(bs, ptr->width);
    6098        3176 :         gf_bs_write_u32(bs, ptr->height);
    6099        3176 :         return GF_OK;
    6100             : }
    6101             : 
    6102        6125 : GF_Err tkhd_box_size(GF_Box *s)
    6103             : {
    6104             :         GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
    6105             : 
    6106        6125 :         if (ptr->duration==(u64) -1) ptr->version = 0;
    6107        6125 :         else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
    6108        6125 :         ptr->size += (ptr->version == 1) ? 32 : 20;
    6109        6125 :         ptr->size += 60;
    6110        6125 :         return GF_OK;
    6111             : }
    6112             : 
    6113             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6114             : 
    6115             : 
    6116             : 
    6117             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    6118             : 
    6119        8829 : void traf_box_del(GF_Box *s)
    6120             : {
    6121             :         GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
    6122        8829 :         if (ptr == NULL) return;
    6123        8829 :         if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
    6124        8829 :         gf_list_del(ptr->TrackRuns);
    6125        8829 :         if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
    6126        8829 :         if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
    6127        8829 :         if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
    6128        8829 :         if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
    6129        8829 :         gf_free(ptr);
    6130             : }
    6131             : 
    6132       13778 : GF_Err traf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    6133             : {
    6134             :         GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
    6135             : 
    6136       13778 :         switch (a->type) {
    6137        4242 :         case GF_ISOM_BOX_TYPE_TFHD:
    6138        4242 :                 BOX_FIELD_ASSIGN(tfhd, GF_TrackFragmentHeaderBox)
    6139        4242 :                 return GF_OK;
    6140        4230 :         case GF_ISOM_BOX_TYPE_TRUN:
    6141        4230 :                 BOX_FIELD_LIST_ASSIGN(TrackRuns)
    6142             :                 return GF_OK;
    6143          31 :         case GF_ISOM_BOX_TYPE_SDTP:
    6144          31 :                 BOX_FIELD_ASSIGN(sdtp, GF_SampleDependencyTypeBox)
    6145          31 :                 return GF_OK;
    6146        4012 :         case GF_ISOM_BOX_TYPE_TFDT:
    6147        4012 :                 BOX_FIELD_ASSIGN(tfdt, GF_TFBaseMediaDecodeTimeBox)
    6148        4012 :                 return GF_OK;
    6149           0 :         case GF_ISOM_BOX_TYPE_SUBS:
    6150           0 :                 BOX_FIELD_LIST_ASSIGN(sub_samples)
    6151             :                 return GF_OK;
    6152          98 :         case GF_ISOM_BOX_TYPE_SBGP:
    6153             :         case GF_ISOM_BOX_TYPE_CSGP:
    6154          98 :                 BOX_FIELD_LIST_ASSIGN(sampleGroups)
    6155             :                 return GF_OK;
    6156          28 :         case GF_ISOM_BOX_TYPE_SGPD:
    6157          28 :                 BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
    6158             :                 return GF_OK;
    6159         490 :         case GF_ISOM_BOX_TYPE_SAIZ:
    6160         490 :                 BOX_FIELD_LIST_ASSIGN(sai_sizes)
    6161             :                 return GF_OK;
    6162         490 :         case GF_ISOM_BOX_TYPE_SAIO:
    6163         490 :                 BOX_FIELD_LIST_ASSIGN(sai_offsets)
    6164             :                 return GF_OK;
    6165             :         //we will throw an error if both PIFF_PSEC and SENC are found. Not such files seen yet
    6166          12 :         case GF_ISOM_BOX_TYPE_UUID:
    6167          12 :                 if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) {
    6168           3 :                         BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
    6169             :                         if (!is_rem)
    6170           3 :                                 ptr->sample_encryption->traf = ptr;
    6171           3 :                         return GF_OK;
    6172           9 :                 } else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFXD) {
    6173           9 :                         BOX_FIELD_ASSIGN(tfxd, GF_MSSTimeExtBox)
    6174           9 :                         return GF_OK;
    6175           0 :                 } else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFRF) {
    6176           0 :                         BOX_FIELD_ASSIGN(tfrf, GF_MSSTimeRefBox)
    6177           0 :                         return GF_OK;
    6178             :                 } else {
    6179             :                         return GF_OK;
    6180             :                 }
    6181         145 :         case GF_ISOM_BOX_TYPE_SENC:
    6182         145 :                 BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
    6183             :                 if (!is_rem)
    6184         145 :                         ptr->sample_encryption->traf = ptr;
    6185         145 :                 return GF_OK;
    6186             :         }
    6187             :         return GF_OK;
    6188             : }
    6189             : 
    6190             : 
    6191        4243 : GF_Err traf_box_read(GF_Box *s, GF_BitStream *bs)
    6192             : {
    6193             :         GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
    6194        4243 :         GF_Err e = gf_isom_box_array_read(s, bs);
    6195        4243 :         if (e) return e;
    6196             : 
    6197        4243 :         if (!ptr->tfhd) {
    6198           1 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackFragmentHeaderBox \n"));
    6199             :                 return GF_ISOM_INVALID_FILE;
    6200             :         }
    6201             :         return GF_OK;
    6202             : }
    6203             : 
    6204        8829 : GF_Box *traf_box_new()
    6205             : {
    6206       17658 :         ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
    6207        8829 :         tmp->TrackRuns = gf_list_new();
    6208        8829 :         return (GF_Box *)tmp;
    6209             : }
    6210             : 
    6211             : 
    6212             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6213             : 
    6214        3939 : GF_Err traf_box_write(GF_Box *s, GF_BitStream *bs)
    6215             : {
    6216        3939 :         return gf_isom_box_write_header(s, bs);
    6217             : }
    6218             : 
    6219       12092 : GF_Err traf_box_size(GF_Box *s)
    6220             : {
    6221       12092 :         u32 pos=0;
    6222             :         GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *) s;
    6223             : 
    6224             :         //Header first
    6225       12092 :         gf_isom_check_position(s, (GF_Box *)ptr->tfhd, &pos);
    6226       12092 :         gf_isom_check_position_list(s, ptr->sub_samples, &pos);
    6227             : 
    6228       12092 :         gf_isom_check_position(s, (GF_Box *)ptr->tfdt, &pos);
    6229             : 
    6230             :         //cmaf-like
    6231       12092 :         if (ptr->truns_first) {
    6232           0 :                 gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
    6233           0 :                 gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
    6234           0 :                 gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
    6235           0 :                 gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
    6236           0 :                 gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
    6237           0 :                 gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
    6238             :                 //subsamples will be last
    6239             :         } else {
    6240       12092 :                 gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
    6241       12092 :                 gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
    6242       12092 :                 gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
    6243       12092 :                 gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
    6244       12092 :                 gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
    6245       12092 :                 gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
    6246             :         }
    6247             : 
    6248             :         //when sdtp is present (smooth-like) write it after the trun box
    6249       12092 :         gf_isom_check_position(s, (GF_Box *)ptr->sdtp, &pos);
    6250             : 
    6251             :         //tfxd should be last ...
    6252       12092 :         if (ptr->tfxd)
    6253           0 :                 gf_isom_check_position(s, (GF_Box *)ptr->tfxd, &pos);
    6254       12092 :         return GF_OK;
    6255             : }
    6256             : 
    6257             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6258             : 
    6259             : 
    6260          12 : GF_Box *tfxd_box_new()
    6261             : {
    6262          24 :         ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID);
    6263          12 :         tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD;
    6264          12 :         return (GF_Box *)tmp;
    6265             : }
    6266             : 
    6267          12 : void tfxd_box_del(GF_Box *s)
    6268             : {
    6269          12 :         gf_free(s);
    6270          12 : }
    6271             : 
    6272             : 
    6273          10 : GF_Err tfxd_box_read(GF_Box *s, GF_BitStream *bs)
    6274             : {
    6275             :         GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s;
    6276          10 :         ISOM_DECREASE_SIZE(ptr, 4);
    6277          10 :         ptr->version = gf_bs_read_u8(bs);
    6278          10 :         ptr->flags = gf_bs_read_u24(bs);
    6279             : 
    6280          10 :         if (ptr->version == 0x01) {
    6281           9 :                 ISOM_DECREASE_SIZE(ptr, 16);
    6282           9 :                 ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs);
    6283           9 :                 ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
    6284             :         } else {
    6285           1 :                 ISOM_DECREASE_SIZE(ptr, 8);
    6286           1 :                 ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs);
    6287           1 :                 ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
    6288             :         }
    6289             : 
    6290             :         return GF_OK;
    6291             : }
    6292             : 
    6293             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6294             : 
    6295           1 : GF_Err tfxd_box_write(GF_Box *s, GF_BitStream *bs)
    6296             : {
    6297             :         GF_Err e;
    6298             :         GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
    6299           1 :         e = gf_isom_box_write_header(s, bs);
    6300           1 :         if (e) return e;
    6301             : 
    6302           1 :         gf_bs_write_u8(bs, ptr->version);
    6303           1 :         gf_bs_write_u24(bs, 0);
    6304           1 :         if (ptr->version) {
    6305           0 :                 gf_bs_write_u64(bs, ptr->absolute_time_in_track_timescale);
    6306           0 :                 gf_bs_write_u64(bs, ptr->fragment_duration_in_track_timescale);
    6307             :         } else {
    6308           1 :                 gf_bs_write_u32(bs, (u32) ptr->absolute_time_in_track_timescale);
    6309           1 :                 gf_bs_write_u32(bs, (u32) ptr->fragment_duration_in_track_timescale);
    6310             :         }
    6311             :         return GF_OK;
    6312             : }
    6313             : 
    6314           1 : GF_Err tfxd_box_size(GF_Box *s)
    6315             : {
    6316             :         GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
    6317           1 :         s->size += 4 + (ptr->version ? 16 : 8);
    6318           1 :         return GF_OK;
    6319             : }
    6320             : #endif //GPAC_DISABLE_ISOM_WRITE
    6321             : 
    6322             : 
    6323             : 
    6324           3 : GF_Box *tfrf_box_new()
    6325             : {
    6326           6 :         ISOM_DECL_BOX_ALLOC(GF_MSSTimeRefBox, GF_ISOM_BOX_TYPE_UUID);
    6327           3 :         tmp->internal_4cc = GF_ISOM_BOX_UUID_TFRF;
    6328           3 :         return (GF_Box *)tmp;
    6329             : }
    6330             : 
    6331           3 : void tfrf_box_del(GF_Box *s)
    6332             : {
    6333             :         GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
    6334           3 :         if (ptr->frags) gf_free(ptr->frags);
    6335           3 :         gf_free(s);
    6336           3 : }
    6337             : 
    6338             : 
    6339           0 : GF_Err tfrf_box_read(GF_Box *s, GF_BitStream *bs)
    6340             : {
    6341             :         u32 i;
    6342             :         GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
    6343           0 :         ISOM_DECREASE_SIZE(ptr, 5);
    6344           0 :         ptr->version = gf_bs_read_u8(bs);
    6345           0 :         ptr->flags = gf_bs_read_u24(bs);
    6346           0 :         ptr->frags_count = gf_bs_read_u8(bs);
    6347           0 :         ptr->frags = gf_malloc(sizeof(GF_MSSTimeEntry) * ptr->frags_count);
    6348           0 :         if (!ptr->frags) return GF_OUT_OF_MEM;
    6349             : 
    6350           0 :         for (i=0; i<ptr->frags_count; i++) {
    6351           0 :                 if (ptr->version == 0x01) {
    6352           0 :                         ISOM_DECREASE_SIZE(ptr, 16);
    6353           0 :                         ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u64(bs);
    6354           0 :                         ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
    6355             :                 } else {
    6356           0 :                         ISOM_DECREASE_SIZE(ptr, 8);
    6357           0 :                         ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u32(bs);
    6358           0 :                         ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
    6359             :                 }
    6360             :         }
    6361             :         return GF_OK;
    6362             : }
    6363             : 
    6364             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6365             : 
    6366           2 : GF_Err tfrf_box_write(GF_Box *s, GF_BitStream *bs)
    6367             : {
    6368             :         GF_Err e;
    6369             :         u32 i;
    6370             :         GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
    6371           2 :         e = gf_isom_box_write_header(s, bs);
    6372           2 :         if (e) return e;
    6373             : 
    6374           2 :         gf_bs_write_u8(bs, ptr->version);
    6375           2 :         gf_bs_write_u24(bs, 0);
    6376           2 :         gf_bs_write_u8(bs, ptr->frags_count);
    6377           2 :         for (i=0; i<ptr->frags_count; i++) {
    6378           0 :                 if (ptr->version==0x01) {
    6379           0 :                         gf_bs_write_u64(bs, ptr->frags[i].absolute_time_in_track_timescale);
    6380           0 :                         gf_bs_write_u64(bs, ptr->frags[i].fragment_duration_in_track_timescale);
    6381             :                 } else {
    6382           0 :                         gf_bs_write_u32(bs, (u32) ptr->frags[i].absolute_time_in_track_timescale);
    6383           0 :                         gf_bs_write_u32(bs, (u32) ptr->frags[i].fragment_duration_in_track_timescale);
    6384             :                 }
    6385             :         }
    6386             :         return GF_OK;
    6387             : }
    6388             : 
    6389           2 : GF_Err tfrf_box_size(GF_Box *s)
    6390             : {
    6391             :         GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
    6392           2 :         s->size += 5;
    6393           2 :         if (ptr->version) s->size += 16 * ptr->frags_count;
    6394           2 :         else s->size += 8 * ptr->frags_count;
    6395           2 :         return GF_OK;
    6396             : }
    6397             : #endif //GPAC_DISABLE_ISOM_WRITE
    6398             : 
    6399             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    6400             : 
    6401             : 
    6402        4125 : void trak_box_del(GF_Box *s)
    6403             : {
    6404             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6405             :         GF_TrackBox *ptr = (GF_TrackBox *)s;
    6406        4125 :         if (ptr->chunk_cache)
    6407           0 :                 gf_bs_del(ptr->chunk_cache);
    6408             : #endif
    6409        4125 :         gf_free(s);
    6410        4125 : }
    6411             : 
    6412        3106 : static void gf_isom_check_sample_desc(GF_TrackBox *trak)
    6413             : {
    6414             :         GF_BitStream *bs;
    6415             :         GF_UnknownBox *a;
    6416             :         u32 i;
    6417             :         GF_Err e;
    6418             :         GF_SampleTableBox *stbl;
    6419             : 
    6420        3106 :         if (!trak->Media || !trak->Media->information) {
    6421           1 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" ));
    6422           1 :                 return;
    6423             :         }
    6424        3105 :         if (!trak->Media->information->sampleTable) {
    6425           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" ));
    6426           0 :                 trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new_parent(&trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_STBL);
    6427             :         }
    6428        3105 :         stbl = trak->Media->information->sampleTable;
    6429             : 
    6430        3105 :         if (!stbl->SampleDescription) {
    6431           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" ));
    6432           0 :                 stbl->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new_parent(&stbl->child_boxes, GF_ISOM_BOX_TYPE_STSD);
    6433             :                 return;
    6434             :         }
    6435             : 
    6436        3105 :         i=0;
    6437        5605 :         while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->child_boxes, &i))) {
    6438        2500 :                 switch (a->type) {
    6439        2461 :                 case GF_ISOM_BOX_TYPE_MP4S:
    6440             :                 case GF_ISOM_BOX_TYPE_ENCS:
    6441             :                 case GF_ISOM_BOX_TYPE_MP4A:
    6442             :                 case GF_ISOM_BOX_TYPE_ENCA:
    6443             :                 case GF_ISOM_BOX_TYPE_MP4V:
    6444             :                 case GF_ISOM_BOX_TYPE_ENCV:
    6445             :                 case GF_ISOM_BOX_TYPE_RESV:
    6446             :                 case GF_ISOM_SUBTYPE_3GP_AMR:
    6447             :                 case GF_ISOM_SUBTYPE_3GP_AMR_WB:
    6448             :                 case GF_ISOM_SUBTYPE_3GP_EVRC:
    6449             :                 case GF_ISOM_SUBTYPE_3GP_QCELP:
    6450             :                 case GF_ISOM_SUBTYPE_3GP_SMV:
    6451             :                 case GF_ISOM_SUBTYPE_3GP_H263:
    6452             :                 case GF_ISOM_BOX_TYPE_GHNT:
    6453             :                 case GF_ISOM_BOX_TYPE_RTP_STSD:
    6454             :                 case GF_ISOM_BOX_TYPE_SRTP_STSD:
    6455             :                 case GF_ISOM_BOX_TYPE_FDP_STSD:
    6456             :                 case GF_ISOM_BOX_TYPE_RRTP_STSD:
    6457             :                 case GF_ISOM_BOX_TYPE_RTCP_STSD:
    6458             :                 case GF_ISOM_BOX_TYPE_METX:
    6459             :                 case GF_ISOM_BOX_TYPE_METT:
    6460             :                 case GF_ISOM_BOX_TYPE_STXT:
    6461             :                 case GF_ISOM_BOX_TYPE_AVC1:
    6462             :                 case GF_ISOM_BOX_TYPE_AVC2:
    6463             :                 case GF_ISOM_BOX_TYPE_AVC3:
    6464             :                 case GF_ISOM_BOX_TYPE_AVC4:
    6465             :                 case GF_ISOM_BOX_TYPE_SVC1:
    6466             :                 case GF_ISOM_BOX_TYPE_MVC1:
    6467             :                 case GF_ISOM_BOX_TYPE_HVC1:
    6468             :                 case GF_ISOM_BOX_TYPE_HEV1:
    6469             :                 case GF_ISOM_BOX_TYPE_HVC2:
    6470             :                 case GF_ISOM_BOX_TYPE_HEV2:
    6471             :                 case GF_ISOM_BOX_TYPE_HVT1:
    6472             :                 case GF_ISOM_BOX_TYPE_LHV1:
    6473             :                 case GF_ISOM_BOX_TYPE_LHE1:
    6474             :                 case GF_ISOM_BOX_TYPE_AV01:
    6475             :                 case GF_ISOM_BOX_TYPE_VP08:
    6476             :                 case GF_ISOM_BOX_TYPE_VP09:
    6477             :                 case GF_ISOM_BOX_TYPE_AV1C:
    6478             :                 case GF_ISOM_BOX_TYPE_TX3G:
    6479             :                 case GF_ISOM_BOX_TYPE_TEXT:
    6480             :                 case GF_ISOM_BOX_TYPE_ENCT:
    6481             :                 case GF_ISOM_BOX_TYPE_DIMS:
    6482             :                 case GF_ISOM_BOX_TYPE_OPUS:
    6483             :                 case GF_ISOM_BOX_TYPE_AC3:
    6484             :                 case GF_ISOM_BOX_TYPE_EC3:
    6485             :                 case GF_ISOM_BOX_TYPE_LSR1:
    6486             :                 case GF_ISOM_BOX_TYPE_WVTT:
    6487             :                 case GF_ISOM_BOX_TYPE_STPP:
    6488             :                 case GF_ISOM_BOX_TYPE_SBTT:
    6489             :                 case GF_ISOM_BOX_TYPE_MP3:
    6490             :                 case GF_ISOM_BOX_TYPE_JPEG:
    6491             :                 case GF_ISOM_BOX_TYPE_PNG:
    6492             :                 case GF_ISOM_BOX_TYPE_JP2K:
    6493             :                 case GF_ISOM_BOX_TYPE_MHA1:
    6494             :                 case GF_ISOM_BOX_TYPE_MHA2:
    6495             :                 case GF_ISOM_BOX_TYPE_MHM1:
    6496             :                 case GF_ISOM_BOX_TYPE_MHM2:
    6497             :                 case GF_ISOM_BOX_TYPE_MJP2:
    6498             :                 case GF_QT_SUBTYPE_RAW_AUD:
    6499             :                 case GF_QT_SUBTYPE_TWOS:
    6500             :                 case GF_QT_SUBTYPE_SOWT:
    6501             :                 case GF_QT_SUBTYPE_FL32:
    6502             :                 case GF_QT_SUBTYPE_FL64:
    6503             :                 case GF_QT_SUBTYPE_IN24:
    6504             :                 case GF_QT_SUBTYPE_IN32:
    6505             :                 case GF_QT_SUBTYPE_ULAW:
    6506             :                 case GF_QT_SUBTYPE_ALAW:
    6507             :                 case GF_QT_SUBTYPE_ADPCM:
    6508             :                 case GF_QT_SUBTYPE_IMA_ADPCM:
    6509             :                 case GF_QT_SUBTYPE_DVCA:
    6510             :                 case GF_QT_SUBTYPE_QDMC:
    6511             :                 case GF_QT_SUBTYPE_QDMC2:
    6512             :                 case GF_QT_SUBTYPE_QCELP:
    6513             :                 case GF_QT_SUBTYPE_kMP3:
    6514             :                 case GF_QT_SUBTYPE_APCH:
    6515             :                 case GF_QT_SUBTYPE_APCO:
    6516             :                 case GF_QT_SUBTYPE_APCN:
    6517             :                 case GF_QT_SUBTYPE_APCS:
    6518             :                 case GF_QT_SUBTYPE_AP4X:
    6519             :                 case GF_QT_SUBTYPE_AP4H:
    6520             :                 case GF_ISOM_BOX_TYPE_IPCM:
    6521             :                 case GF_ISOM_BOX_TYPE_FPCM:
    6522             :                 case GF_ISOM_BOX_TYPE_VVC1:
    6523             :                 case GF_ISOM_BOX_TYPE_VVI1:
    6524             :                 case GF_QT_SUBTYPE_RAW_VID:
    6525             :                 case GF_QT_SUBTYPE_YUYV:
    6526             :                 case GF_QT_SUBTYPE_UYVY:
    6527             :                 case GF_QT_SUBTYPE_YUV444:
    6528             :                 case GF_QT_SUBTYPE_YUVA444:
    6529             :                 case GF_QT_SUBTYPE_YUV422_10:
    6530             :                 case GF_QT_SUBTYPE_YUV444_10:
    6531             :                 case GF_QT_SUBTYPE_YUV422_16:
    6532             :                 case GF_QT_SUBTYPE_YUV420:
    6533             :                 case GF_QT_SUBTYPE_I420:
    6534             :                 case GF_QT_SUBTYPE_IYUV:
    6535             :                 case GF_QT_SUBTYPE_YV12:
    6536             :                 case GF_QT_SUBTYPE_YVYU:
    6537             :                 case GF_QT_SUBTYPE_RGBA:
    6538             :                 case GF_QT_SUBTYPE_ABGR:
    6539        2461 :                         continue;
    6540             : 
    6541             :                 case GF_ISOM_BOX_TYPE_UNKNOWN:
    6542             :                         break;
    6543          33 :                 default:
    6544          33 :                         if (gf_box_valid_in_parent((GF_Box *) a, "stsd")) {
    6545          33 :                                 continue;
    6546             :                         }
    6547           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type)));
    6548           0 :                         continue;
    6549             :                 }
    6550             :                 //we are sure to have an unknown box here
    6551             :                 assert(a->type==GF_ISOM_BOX_TYPE_UNKNOWN);
    6552             : 
    6553           6 :                 if (!a->data || (a->dataSize<8) ) {
    6554           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s does not have at least 8 bytes!\n", gf_4cc_to_str(a->original_4cc) ));
    6555           0 :                         continue;
    6556             :                 }
    6557           6 :                 else if (a->dataSize > a->size) {
    6558           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Sample description %s has wrong data size %d!\n", gf_4cc_to_str(a->original_4cc), a->dataSize));
    6559           0 :                         continue;
    6560             :                 }
    6561             : 
    6562             : #define STSD_SWITCH_BOX(_box) \
    6563             :                 if (gf_bs_available(bs)) { \
    6564             :                         u64 pos = gf_bs_get_position(bs); \
    6565             :                         u32 count_subb = 0; \
    6566             :                         gf_bs_set_cookie(bs, GF_ISOM_BS_COOKIE_NO_LOGS);\
    6567             :                         e = gf_isom_box_array_read((GF_Box *) _box, bs); \
    6568             :                         count_subb = _box->child_boxes ? gf_list_count(_box->child_boxes) : 0; \
    6569             :                         if (!count_subb || e) { \
    6570             :                                 gf_bs_seek(bs, pos); \
    6571             :                                 _box->data_size = (u32) gf_bs_available(bs); \
    6572             :                                 if (_box->data_size) { \
    6573             :                                         _box->data = a->data; \
    6574             :                                         a->data = NULL; \
    6575             :                                         memmove(_box->data, _box->data + pos, _box->data_size); \
    6576             :                                 } \
    6577             :                         } else { \
    6578             :                                 _box->data_size = 0; \
    6579             :                         } \
    6580             :                 } \
    6581             :                 gf_bs_del(bs); \
    6582             :                 if (!_box->data_size && _box->data) { \
    6583             :                         gf_free(_box->data); \
    6584             :                         _box->data = NULL; \
    6585             :                 } \
    6586             :                 _box->size = 0; \
    6587             :                 _box->EntryType = a->original_4cc; \
    6588             :                 gf_list_rem(trak->Media->information->sampleTable->SampleDescription->child_boxes, i-1); \
    6589             :                 gf_isom_box_del((GF_Box *)a); \
    6590             :                 gf_list_insert(trak->Media->information->sampleTable->SampleDescription->child_boxes, _box, i-1); \
    6591             : 
    6592             : 
    6593             :                 /*only process visual or audio
    6594             :                 note: no need for new_box_parent here since we always store sample descriptions in child_boxes*/
    6595           6 :                 switch (trak->Media->handler->handlerType) {
    6596           0 :         case GF_ISOM_MEDIA_VISUAL:
    6597             :                 case GF_ISOM_MEDIA_AUXV:
    6598             :                 case GF_ISOM_MEDIA_PICT:
    6599             :                 {
    6600           0 :                         GF_GenericVisualSampleEntryBox *genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
    6601           0 :                         bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
    6602           0 :                         genv->size = a->size-8;
    6603           0 :                         gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs);
    6604             : 
    6605           0 :                         STSD_SWITCH_BOX(genv)
    6606             : 
    6607             :                 }
    6608             :                 break;
    6609           0 :                 case GF_ISOM_MEDIA_AUDIO:
    6610             :                 {
    6611           0 :                         GF_GenericAudioSampleEntryBox *gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
    6612           0 :                         gena->size = a->size-8;
    6613           0 :                         bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
    6614           0 :                         gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs);
    6615             : 
    6616           0 :                         STSD_SWITCH_BOX(gena)
    6617             : 
    6618             :                 }
    6619             :                 break;
    6620             : 
    6621           6 :                 default:
    6622             :                 {
    6623           6 :                         GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
    6624           6 :                         genm->size = a->size-8;
    6625           6 :                         bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
    6626             : 
    6627           6 :                         e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)genm, bs);
    6628           6 :                         if (e) return;
    6629             : 
    6630           6 :                         STSD_SWITCH_BOX(genm)
    6631             :                 }
    6632             :                 break;
    6633             :                 }
    6634             : 
    6635             :         }
    6636             : }
    6637             : 
    6638             : 
    6639       10761 : GF_Err trak_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    6640             : {
    6641             :         GF_TrackBox *ptr = (GF_TrackBox *)s;
    6642       10761 :         if (!a) return GF_OK;
    6643       10761 :         switch(a->type) {
    6644        4116 :         case GF_ISOM_BOX_TYPE_TKHD:
    6645        4116 :                 BOX_FIELD_ASSIGN(Header, GF_TrackHeaderBox)
    6646        4116 :                 return GF_OK;
    6647        1235 :         case GF_ISOM_BOX_TYPE_EDTS:
    6648        1235 :                 BOX_FIELD_ASSIGN(editBox, GF_EditBox)
    6649        1235 :                 return GF_OK;
    6650         382 :         case GF_ISOM_BOX_TYPE_UDTA:
    6651         382 :                 BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
    6652         382 :                 return GF_OK;
    6653          89 :         case GF_ISOM_BOX_TYPE_META:
    6654          89 :                 BOX_FIELD_ASSIGN(meta, GF_MetaBox)
    6655          89 :                 return GF_OK;
    6656         538 :         case GF_ISOM_BOX_TYPE_TREF:
    6657         538 :                 BOX_FIELD_ASSIGN(References, GF_TrackReferenceBox)
    6658         538 :                 return GF_OK;
    6659        4116 :         case GF_ISOM_BOX_TYPE_MDIA:
    6660        4116 :                 BOX_FIELD_ASSIGN(Media, GF_MediaBox)
    6661             :                 if (!is_rem)
    6662        4116 :                         ((GF_MediaBox *)a)->mediaTrack = ptr;
    6663        4116 :                 return GF_OK;
    6664          19 :         case GF_ISOM_BOX_TYPE_TRGR:
    6665          19 :                 BOX_FIELD_ASSIGN(groups, GF_TrackGroupBox)
    6666          19 :                 return GF_OK;
    6667          11 :         case GF_QT_BOX_TYPE_TAPT:
    6668          11 :                 BOX_FIELD_ASSIGN(Aperture, GF_Box)
    6669          11 :                 return GF_OK;
    6670         233 :         case GF_ISOM_BOX_TYPE_SENC:
    6671         233 :                 BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
    6672         233 :                 return GF_OK;
    6673          20 :         case GF_ISOM_BOX_TYPE_UUID:
    6674          20 :                 if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
    6675          18 :                         BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
    6676          18 :                         return GF_OK;
    6677             :                 }
    6678             :         }
    6679             :         return GF_OK;
    6680             : }
    6681             : 
    6682             : 
    6683        3106 : GF_Err trak_box_read(GF_Box *s, GF_BitStream *bs)
    6684             : {
    6685             :         GF_Err e;
    6686             :         u32 i;
    6687             :         GF_TrackBox *ptr = (GF_TrackBox *)s;
    6688        3106 :         e = gf_isom_box_array_read(s, bs);
    6689        3106 :         if (e) return e;
    6690        3106 :         gf_isom_check_sample_desc(ptr);
    6691             : 
    6692        3106 :         if (!ptr->Header) {
    6693           1 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n"));
    6694             :                 return GF_ISOM_INVALID_FILE;
    6695             :         }
    6696        3105 :         if (!ptr->Media) {
    6697           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n"));
    6698             :                 return GF_ISOM_INVALID_FILE;
    6699             :         }
    6700        3105 :         if (!ptr->Media->information || !ptr->Media->information->sampleTable) {
    6701           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid MediaBox\n"));
    6702             :                 return GF_ISOM_INVALID_FILE;
    6703             :         }
    6704        3105 :         if (!ptr->Media->information->sampleTable->SampleSize || (ptr->Media->information->sampleTable->SampleSize->sampleCount==0)) {
    6705        1088 :                 if (ptr->Header->initial_duration) {
    6706         689 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Track with no samples but duration defined, ignoring duration\n"));
    6707         689 :                         ptr->Header->initial_duration = 0;
    6708             :                 }
    6709             :         }
    6710             : 
    6711       15103 :         for (i=0; i<gf_list_count(ptr->Media->information->sampleTable->child_boxes); i++) {
    6712       15103 :                 GF_Box *a = gf_list_get(ptr->Media->information->sampleTable->child_boxes, i);
    6713       15103 :                 if ((a->type ==GF_ISOM_BOX_TYPE_UUID) && (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC)) {
    6714           0 :                         ptr->sample_encryption = (struct __sample_encryption_box *) a;
    6715           0 :                         break;
    6716             :                 }
    6717       15103 :                 else if (a->type == GF_ISOM_BOX_TYPE_SENC) {
    6718           0 :                         ptr->sample_encryption = (struct __sample_encryption_box *)a;
    6719           0 :                         break;
    6720             :                 }
    6721             :         }
    6722             :         return e;
    6723             : }
    6724             : 
    6725        4125 : GF_Box *trak_box_new()
    6726             : {
    6727        8250 :         ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
    6728        4125 :         return (GF_Box *)tmp;
    6729             : }
    6730             : 
    6731             : 
    6732             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6733             : 
    6734        3176 : GF_Err trak_box_write(GF_Box *s, GF_BitStream *bs)
    6735             : {
    6736        3176 :         return gf_isom_box_write_header(s, bs);
    6737             : }
    6738             : 
    6739        6125 : GF_Err trak_box_size(GF_Box *s)
    6740             : {
    6741        6125 :         u32 pos=0;
    6742             :         GF_TrackBox *ptr = (GF_TrackBox *)s;
    6743             : 
    6744        6125 :         if (ptr->sample_encryption && ptr->sample_encryption->load_needed) {
    6745           0 :                 if (!ptr->moov || !!ptr->moov->mov || !ptr->moov->mov->movieFileMap)
    6746             :                         return GF_ISOM_INVALID_FILE;
    6747           0 :                 GF_Err e = senc_Parse(ptr->moov->mov->movieFileMap->bs, ptr, NULL, ptr->sample_encryption);
    6748           0 :                 if (e) return e;
    6749             :         }
    6750             : 
    6751        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->Header, &pos);
    6752        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->Aperture, &pos);
    6753        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->References, &pos);
    6754        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->editBox, &pos);
    6755        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->Media, &pos);
    6756        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->meta, &pos);
    6757        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->groups, &pos);
    6758        6125 :         gf_isom_check_position(s, (GF_Box *)ptr->udta, &pos);
    6759        6125 :         return GF_OK;
    6760             : }
    6761             : 
    6762             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6763             : 
    6764           3 : void stri_box_del(GF_Box *s)
    6765             : {
    6766             :         GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
    6767           3 :         if (ptr == NULL) return;
    6768           3 :         if (ptr->attribute_list) gf_free(ptr->attribute_list);
    6769           3 :         gf_free(ptr);
    6770             : }
    6771             : 
    6772           1 : GF_Err stri_box_read(GF_Box *s, GF_BitStream *bs)
    6773             : {
    6774             :         size_t i;
    6775             :         GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
    6776           1 :         ISOM_DECREASE_SIZE(ptr, 8)
    6777           1 :         ptr->switch_group = gf_bs_read_u16(bs);
    6778           1 :         ptr->alternate_group = gf_bs_read_u16(bs);
    6779           1 :         ptr->sub_track_id = gf_bs_read_u32(bs);
    6780           1 :         ptr->attribute_count = ptr->size / 4;
    6781           1 :         GF_SAFE_ALLOC_N(ptr->attribute_list, (size_t)ptr->attribute_count, u32);
    6782           1 :         if (!ptr->attribute_list) return GF_OUT_OF_MEM;
    6783           0 :         for (i = 0; i < ptr->attribute_count; i++) {
    6784           0 :                 ISOM_DECREASE_SIZE(ptr, 4)
    6785           0 :                 ptr->attribute_list[i] = gf_bs_read_u32(bs);
    6786             :         }
    6787             :         return GF_OK;
    6788             : }
    6789             : 
    6790           3 : GF_Box *stri_box_new()
    6791             : {
    6792           6 :         ISOM_DECL_BOX_ALLOC(GF_SubTrackInformationBox, GF_ISOM_BOX_TYPE_STRI);
    6793           3 :         return (GF_Box *)tmp;
    6794             : }
    6795             : 
    6796             : 
    6797             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6798             : 
    6799           1 : GF_Err stri_box_write(GF_Box *s, GF_BitStream *bs)
    6800             : {
    6801             :         GF_Err e;
    6802             :         u32 i;
    6803             :         GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
    6804           1 :         e = gf_isom_full_box_write(s, bs);
    6805           1 :         if (e) return e;
    6806             : 
    6807           1 :         gf_bs_write_u16(bs, ptr->switch_group);
    6808           1 :         gf_bs_write_u16(bs, ptr->alternate_group);
    6809           1 :         gf_bs_write_u32(bs, ptr->sub_track_id);
    6810           1 :         for (i = 0; i < ptr->attribute_count; i++) {
    6811           0 :                 gf_bs_write_u32(bs, ptr->attribute_list[i]);
    6812             :         }
    6813             :         return GF_OK;
    6814             : }
    6815             : 
    6816           1 : GF_Err stri_box_size(GF_Box *s)
    6817             : {
    6818             :         GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
    6819             : 
    6820           1 :         ptr->size += 8 + 4 * ptr->attribute_count;
    6821           1 :         return GF_OK;
    6822             : }
    6823             : 
    6824             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6825             : 
    6826           3 : void stsg_box_del(GF_Box *s)
    6827             : {
    6828             :         GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
    6829           3 :         if (ptr == NULL) return;
    6830           3 :         if (ptr->group_description_index) gf_free(ptr->group_description_index);
    6831           3 :         gf_free(ptr);
    6832             : }
    6833             : 
    6834           1 : GF_Err stsg_box_read(GF_Box *s, GF_BitStream *bs)
    6835             : {
    6836             :         u32 i;
    6837             :         GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
    6838           1 :         ISOM_DECREASE_SIZE(s, 6);
    6839           1 :         ptr->grouping_type = gf_bs_read_u32(bs);
    6840           1 :         ptr->nb_groups = gf_bs_read_u16(bs);
    6841           1 :         ISOM_DECREASE_SIZE(s, ptr->nb_groups*4);
    6842           1 :         GF_SAFE_ALLOC_N(ptr->group_description_index, ptr->nb_groups, u32);
    6843           1 :         if (!ptr->group_description_index) return GF_OUT_OF_MEM;
    6844           0 :         for (i = 0; i < ptr->nb_groups; i++) {
    6845           0 :                 ptr->group_description_index[i] = gf_bs_read_u32(bs);
    6846             :         }
    6847             :         return GF_OK;
    6848             : }
    6849             : 
    6850           3 : GF_Box *stsg_box_new()
    6851             : {
    6852           6 :         ISOM_DECL_BOX_ALLOC(GF_SubTrackSampleGroupBox, GF_ISOM_BOX_TYPE_STSG);
    6853           3 :         return (GF_Box *)tmp;
    6854             : }
    6855             : 
    6856             : 
    6857             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6858             : 
    6859           1 : GF_Err stsg_box_write(GF_Box *s, GF_BitStream *bs)
    6860             : {
    6861             :         GF_Err e;
    6862             :         u32 i;
    6863             :         GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
    6864           1 :         e = gf_isom_full_box_write(s, bs);
    6865           1 :         if (e) return e;
    6866             : 
    6867           1 :         gf_bs_write_u32(bs, ptr->grouping_type);
    6868           1 :         gf_bs_write_u16(bs, ptr->nb_groups);
    6869           1 :         for (i = 0; i < ptr->nb_groups; i++) {
    6870           0 :                 gf_bs_write_u32(bs, ptr->group_description_index[i]);
    6871             :         }
    6872             :         return GF_OK;
    6873             : }
    6874             : 
    6875           1 : GF_Err stsg_box_size(GF_Box *s)
    6876             : {
    6877             :         GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
    6878           1 :         ptr->size += 6 + 4 * ptr->nb_groups;
    6879           1 :         return GF_OK;
    6880             : }
    6881             : 
    6882             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6883             : 
    6884             : 
    6885           3 : void strk_box_del(GF_Box *s)
    6886             : {
    6887           3 :         gf_free(s);
    6888           3 : }
    6889             : 
    6890           0 : GF_Err strk_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    6891             : {
    6892             :         GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
    6893           0 :         if (!a) return GF_OK;
    6894           0 :         switch (a->type) {
    6895           0 :         case GF_ISOM_BOX_TYPE_STRI:
    6896           0 :                 BOX_FIELD_ASSIGN(info, GF_SubTrackInformationBox)
    6897           0 :                 return GF_OK;
    6898           0 :         case GF_ISOM_BOX_TYPE_STRD:
    6899           0 :                 BOX_FIELD_ASSIGN(strd, GF_Box)
    6900           0 :                 return GF_OK;
    6901             :         }
    6902             :         return GF_OK;
    6903             : }
    6904             : 
    6905             : 
    6906           1 : GF_Err strk_box_read(GF_Box *s, GF_BitStream *bs)
    6907             : {
    6908             :         GF_Err e;
    6909             :         GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
    6910           1 :         e = gf_isom_box_array_read(s, bs);
    6911           1 :         if (e) return e;
    6912             : 
    6913           1 :         if (!ptr->info) {
    6914           1 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing SubTrackInformationBox\n"));
    6915             :                 return GF_ISOM_INVALID_FILE;
    6916             :         }
    6917             :         return GF_OK;
    6918             : }
    6919             : 
    6920           3 : GF_Box *strk_box_new()
    6921             : {
    6922           6 :         ISOM_DECL_BOX_ALLOC(GF_SubTrackBox, GF_ISOM_BOX_TYPE_STRK);
    6923           3 :         return (GF_Box *)tmp;
    6924             : }
    6925             : 
    6926             : 
    6927             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6928             : 
    6929           1 : GF_Err strk_box_write(GF_Box *s, GF_BitStream *bs)
    6930             : {
    6931           1 :         return gf_isom_box_write_header(s, bs);
    6932             : }
    6933             : 
    6934           1 : GF_Err strk_box_size(GF_Box *s)
    6935             : {
    6936           1 :         return GF_OK;
    6937             : }
    6938             : 
    6939             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6940             : 
    6941         541 : void tref_box_del(GF_Box *s)
    6942             : {
    6943             :         GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
    6944         541 :         if (ptr == NULL) return;
    6945         541 :         gf_free(ptr);
    6946             : }
    6947             : 
    6948             : 
    6949         326 : GF_Err tref_box_read(GF_Box *s, GF_BitStream *bs)
    6950             : {
    6951         326 :         return gf_isom_box_array_read_ex(s, bs, s->type);
    6952             : }
    6953             : 
    6954         541 : GF_Box *tref_box_new()
    6955             : {
    6956        1082 :         ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
    6957         541 :         return (GF_Box *)tmp;
    6958             : }
    6959             : 
    6960             : #ifndef GPAC_DISABLE_ISOM_WRITE
    6961             : 
    6962         430 : GF_Err tref_box_write(GF_Box *s, GF_BitStream *bs)
    6963             : {
    6964             : //      GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
    6965         430 :         return gf_isom_box_write_header(s, bs);
    6966             : }
    6967             : 
    6968         845 : GF_Err tref_box_size(GF_Box *s)
    6969             : {
    6970         845 :         return GF_OK;
    6971             : }
    6972             : 
    6973             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    6974             : 
    6975         702 : void reftype_box_del(GF_Box *s)
    6976             : {
    6977             :         GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
    6978         702 :         if (!ptr) return;
    6979         702 :         if (ptr->trackIDs) gf_free(ptr->trackIDs);
    6980         702 :         gf_free(ptr);
    6981             : }
    6982             : 
    6983             : 
    6984         354 : GF_Err reftype_box_read(GF_Box *s, GF_BitStream *bs)
    6985             : {
    6986             :         u32 bytesToRead;
    6987             :         u32 i;
    6988             :         GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
    6989             : 
    6990         354 :         bytesToRead = (u32) (ptr->size);
    6991         354 :         if (!bytesToRead) return GF_OK;
    6992             : 
    6993         351 :         ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32);
    6994         351 :         ptr->trackIDs = (GF_ISOTrackID *) gf_malloc(ptr->trackIDCount * sizeof(GF_ISOTrackID));
    6995         351 :         if (!ptr->trackIDs) return GF_OUT_OF_MEM;
    6996             : 
    6997         539 :         for (i = 0; i < ptr->trackIDCount; i++) {
    6998         539 :                 ptr->trackIDs[i] = gf_bs_read_u32(bs);
    6999             :         }
    7000             :         return GF_OK;
    7001             : }
    7002             : 
    7003         702 : GF_Box *reftype_box_new()
    7004             : {
    7005        1404 :         ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
    7006         702 :         return (GF_Box *)tmp;
    7007             : }
    7008             : 
    7009             : 
    7010       75730 : GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, GF_ISOTrackID trackID, u16 *outRefIndex)
    7011             : {
    7012             :         u32 i;
    7013       75730 :         if (!ref || !trackID) return GF_BAD_PARAM;
    7014             : 
    7015       75730 :         if (outRefIndex) *outRefIndex = 0;
    7016             :         //don't add a dep if already here !!
    7017       76587 :         for (i = 0; i < ref->trackIDCount; i++) {
    7018       76181 :                 if (ref->trackIDs[i] == trackID) {
    7019       75324 :                         if (outRefIndex) *outRefIndex = i+1;
    7020             :                         return GF_OK;
    7021             :                 }
    7022             :         }
    7023             : 
    7024         406 :         ref->trackIDs = (GF_ISOTrackID *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(GF_ISOTrackID) );
    7025         406 :         if (!ref->trackIDs) return GF_OUT_OF_MEM;
    7026         406 :         ref->trackIDs[ref->trackIDCount] = trackID;
    7027         406 :         ref->trackIDCount++;
    7028         406 :         if (outRefIndex) *outRefIndex = ref->trackIDCount;
    7029             :         return GF_OK;
    7030             : }
    7031             : 
    7032             : 
    7033             : 
    7034             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7035             : 
    7036         502 : GF_Err reftype_box_write(GF_Box *s, GF_BitStream *bs)
    7037             : {
    7038             :         GF_Err e;
    7039             :         u32 i;
    7040             :         GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
    7041         502 :         ptr->type = ptr->reference_type;
    7042         502 :         e = gf_isom_box_write_header(s, bs);
    7043         502 :         ptr->type = GF_ISOM_BOX_TYPE_REFT;
    7044         502 :         if (e) return e;
    7045         696 :         for (i = 0; i < ptr->trackIDCount; i++) {
    7046         696 :                 gf_bs_write_u32(bs, ptr->trackIDs[i]);
    7047             :         }
    7048             :         return GF_OK;
    7049             : }
    7050             : 
    7051             : 
    7052         977 : GF_Err reftype_box_size(GF_Box *s)
    7053             : {
    7054             :         GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
    7055         977 :         if (ptr->trackIDCount)
    7056         935 :                 ptr->size += (ptr->trackIDCount * sizeof(u32));
    7057         977 :         return GF_OK;
    7058             : }
    7059             : 
    7060             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7061             : 
    7062             : 
    7063             : 
    7064             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    7065             : 
    7066         731 : void trex_box_del(GF_Box *s)
    7067             : {
    7068             :         GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
    7069         731 :         if (ptr == NULL) return;
    7070         731 :         gf_free(ptr);
    7071             : }
    7072             : 
    7073             : 
    7074         334 : GF_Err trex_box_read(GF_Box *s, GF_BitStream *bs)
    7075             : {
    7076             :         GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
    7077             : 
    7078         334 :         ISOM_DECREASE_SIZE(ptr, 20);
    7079         334 :         ptr->trackID = gf_bs_read_u32(bs);
    7080         334 :         ptr->def_sample_desc_index = gf_bs_read_u32(bs);
    7081         334 :         ptr->def_sample_duration = gf_bs_read_u32(bs);
    7082         334 :         ptr->def_sample_size = gf_bs_read_u32(bs);
    7083         334 :         ptr->def_sample_flags = gf_bs_read_u32(bs);
    7084         334 :         return GF_OK;
    7085             : }
    7086             : 
    7087         731 : GF_Box *trex_box_new()
    7088             : {
    7089        1462 :         ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
    7090         731 :         return (GF_Box *)tmp;
    7091             : }
    7092             : 
    7093             : 
    7094             : 
    7095             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7096             : 
    7097             : 
    7098         656 : GF_Err trex_box_write(GF_Box *s, GF_BitStream *bs)
    7099             : {
    7100             :         GF_Err e;
    7101             :         GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s;
    7102         656 :         if (!s) return GF_BAD_PARAM;
    7103         656 :         e = gf_isom_full_box_write(s, bs);
    7104         656 :         if (e) return e;
    7105             : 
    7106         656 :         gf_bs_write_u32(bs, ptr->trackID);
    7107             :         //we always write 1 in trex default sample desc as using 0 breaks chrome/opera/...
    7108         656 :         gf_bs_write_u32(bs, ptr->def_sample_desc_index ? ptr->def_sample_desc_index : 1);
    7109         656 :         gf_bs_write_u32(bs, ptr->def_sample_duration);
    7110         656 :         gf_bs_write_u32(bs, ptr->def_sample_size);
    7111         656 :         gf_bs_write_u32(bs, ptr->def_sample_flags);
    7112         656 :         return GF_OK;
    7113             : }
    7114             : 
    7115         661 : GF_Err trex_box_size(GF_Box *s)
    7116             : {
    7117             :         GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
    7118         661 :         ptr->size += 20;
    7119         661 :         return GF_OK;
    7120             : }
    7121             : 
    7122             : 
    7123             : 
    7124             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7125             : 
    7126             : 
    7127             : 
    7128           3 : void trep_box_del(GF_Box *s)
    7129             : {
    7130             :         GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
    7131           3 :         if (ptr == NULL) return;
    7132           3 :         gf_free(ptr);
    7133             : }
    7134             : 
    7135             : 
    7136           1 : GF_Err trep_box_read(GF_Box *s, GF_BitStream *bs)
    7137             : {
    7138             :         GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
    7139             : 
    7140           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    7141           1 :         ptr->trackID = gf_bs_read_u32(bs);
    7142             : 
    7143           1 :         return gf_isom_box_array_read(s, bs);
    7144             : }
    7145             : 
    7146           3 : GF_Box *trep_box_new()
    7147             : {
    7148           6 :         ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP);
    7149           3 :         tmp->child_boxes = gf_list_new();
    7150           3 :         return (GF_Box *)tmp;
    7151             : }
    7152             : 
    7153             : 
    7154             : 
    7155             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7156             : 
    7157             : 
    7158           1 : GF_Err trep_box_write(GF_Box *s, GF_BitStream *bs)
    7159             : {
    7160             :         GF_Err e;
    7161             :         GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *) s;
    7162           1 :         if (!s) return GF_BAD_PARAM;
    7163           1 :         e = gf_isom_full_box_write(s, bs);
    7164           1 :         if (e) return e;
    7165             : 
    7166           1 :         gf_bs_write_u32(bs, ptr->trackID);
    7167           1 :         return GF_OK;
    7168             : }
    7169             : 
    7170           1 : GF_Err trep_box_size(GF_Box *s)
    7171             : {
    7172             :         GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
    7173           1 :         ptr->size += 4;
    7174           1 :         return GF_OK;
    7175             : }
    7176             : 
    7177             : 
    7178             : 
    7179             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7180             : 
    7181             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    7182             : 
    7183             : 
    7184             : 
    7185             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    7186             : 
    7187        8008 : void trun_box_del(GF_Box *s)
    7188             : {
    7189             :         GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
    7190        8008 :         if (ptr == NULL) return;
    7191             : 
    7192        8008 :         if (ptr->samples) gf_free(ptr->samples);
    7193        8008 :         if (ptr->cache) gf_bs_del(ptr->cache);
    7194        8008 :         if (ptr->sample_order) gf_free(ptr->sample_order);
    7195        8008 :         gf_free(ptr);
    7196             : }
    7197             : 
    7198             : #ifdef GF_ENABLE_CTRN
    7199             : 
    7200             : static u32 ctrn_field_size(u32 field_idx)
    7201             : {
    7202             :         if (field_idx==3) return 4;
    7203             :         return field_idx;
    7204             : }
    7205             : 
    7206             : u32 gf_isom_ctrn_field_size_bits(u32 field_idx)
    7207             : {
    7208             :         if (field_idx==3) return 32;
    7209             :         return field_idx*8;
    7210             : }
    7211             : static u32 ctrn_read_flags(GF_BitStream *bs, u32 nbbits)
    7212             : {
    7213             :         u32 val = gf_bs_read_int(bs, nbbits);
    7214             :         if (nbbits==16) val <<= 16;
    7215             :         else if (nbbits==8) val <<= 24;
    7216             :         return val;
    7217             : }
    7218             : 
    7219             : static GF_Err ctrn_box_read(GF_Box *s, GF_BitStream *bs)
    7220             : {
    7221             :         u32 i, count, flags, first_idx=0;
    7222             :         Bool inherit_dur, inherit_size, inherit_flags, inherit_ctso;
    7223             :         GF_TrunEntry *ent;
    7224             :         GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
    7225             :         flags = ptr->flags;
    7226             :         ptr->ctrn_flags = flags;
    7227             :         ptr->flags = 0;
    7228             : 
    7229             :         ptr->sample_count = gf_bs_read_u16(bs);
    7230             :         ISOM_DECREASE_SIZE(ptr, 2);
    7231             : 
    7232             :         if (flags & GF_ISOM_TRUN_DATA_OFFSET) {
    7233             :                 if (flags & GF_ISOM_CTRN_DATAOFFSET_16) {
    7234             :                         ptr->data_offset = gf_bs_read_u16(bs);
    7235             :                         ISOM_DECREASE_SIZE(ptr, 2);
    7236             :                 } else {
    7237             :                         ptr->data_offset = gf_bs_read_u32(bs);
    7238             :                         ISOM_DECREASE_SIZE(ptr, 4);
    7239             :                 }
    7240             :                 ptr->flags |= GF_ISOM_TRUN_DATA_OFFSET;
    7241             :         }
    7242             :         if (flags & GF_ISOM_CTRN_CTSO_MULTIPLIER) {
    7243             :                 ptr->ctso_multiplier = gf_bs_read_u16(bs);
    7244             :                 ISOM_DECREASE_SIZE(ptr, 2);
    7245             :         }
    7246             :         /*no sample dur/sample_flag/size/ctso for first or following, create a pack sample */
    7247             :         if (! (flags & 0x00FFFF00)) {
    7248             :                 GF_SAFEALLOC(ent, GF_TrunEntry);
    7249             :                 if (!ent) return GF_OUT_OF_MEM;
    7250             :                 ent->nb_pack = ptr->sample_count;
    7251             :                 gf_list_add(ptr->entries, ent);
    7252             :                 return GF_OK;
    7253             :         }
    7254             :         /*allocate all entries*/
    7255             :         for (i=0; i<ptr->sample_count; i++) {
    7256             :                 GF_SAFEALLOC(ent, GF_TrunEntry);
    7257             :                 if (!ent) return GF_OUT_OF_MEM;
    7258             :                 gf_list_add(ptr->entries, ent);
    7259             :         }
    7260             :         //unpack flags
    7261             :         ptr->ctrn_first_dur = (flags>>22) & 0x3;
    7262             :         ptr->ctrn_first_size = (flags>>20) & 0x3;
    7263             :         ptr->ctrn_first_sample_flags = (flags>>18) & 0x3;
    7264             :         ptr->ctrn_first_ctts = (flags>>16) & 0x3;
    7265             :         ptr->ctrn_dur = (flags>>14) & 0x3;
    7266             :         ptr->ctrn_size = (flags>>12) & 0x3;
    7267             :         ptr->ctrn_sample_flags = (flags>>10) & 0x3;
    7268             :         ptr->ctrn_ctts = (flags>>8) & 0x3;
    7269             : 
    7270             :         inherit_dur = flags & GF_ISOM_CTRN_INHERIT_DUR;
    7271             :         inherit_size = flags & GF_ISOM_CTRN_INHERIT_SIZE;
    7272             :         inherit_flags = flags & GF_ISOM_CTRN_INHERIT_FLAGS;
    7273             :         inherit_ctso = flags & GF_ISOM_CTRN_INHERIT_CTSO;
    7274             : 
    7275             :         if (flags & GF_ISOM_CTRN_FIRST_SAMPLE) {
    7276             :                 ent = gf_list_get(ptr->entries, 0);
    7277             :                 first_idx = 1;
    7278             :                 if (!inherit_dur && ptr->ctrn_first_dur) {
    7279             :                         ent->Duration = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_dur) );
    7280             :                         ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_dur) );
    7281             :                 }
    7282             :                 if (!inherit_size && ptr->ctrn_first_size) {
    7283             :                         ent->size = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_size) );
    7284             :                         ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_size) );
    7285             :                 }
    7286             :                 if (!inherit_flags && ptr->ctrn_first_sample_flags) {
    7287             :                         ent->flags = ctrn_read_flags(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_sample_flags) );
    7288             :                         ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_sample_flags) );
    7289             :                 }
    7290             :                 if (!inherit_ctso && ptr->ctrn_first_ctts) {
    7291             :                         ent->CTS_Offset = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_ctts) );
    7292             :                         ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_ctts) );
    7293             :                         if (ptr->ctso_multiplier)
    7294             :                                 ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
    7295             :                 }
    7296             :         }
    7297             :         count = ptr->sample_count - first_idx;
    7298             :         if (!inherit_dur && ptr->ctrn_dur) {
    7299             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_dur);
    7300             :                 ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
    7301             :                 for (i=first_idx; i<ptr->sample_count; i++) {
    7302             :                         ent = gf_list_get(ptr->entries, i);
    7303             :                         ent->Duration = gf_bs_read_int(bs, nbbits);
    7304             :                 }
    7305             :         }
    7306             :         if (!inherit_size && ptr->ctrn_size) {
    7307             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_size);
    7308             :                 ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
    7309             :                 for (i=first_idx; i<ptr->sample_count; i++) {
    7310             :                         ent = gf_list_get(ptr->entries, i);
    7311             :                         ent->size = gf_bs_read_int(bs, nbbits);
    7312             :                 }
    7313             :         }
    7314             :         if (!inherit_flags && ptr->ctrn_sample_flags) {
    7315             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_sample_flags);
    7316             :                 ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
    7317             :                 for (i=first_idx; i<ptr->sample_count; i++) {
    7318             :                         ent = gf_list_get(ptr->entries, i);
    7319             :                         ent->flags = ctrn_read_flags(bs, nbbits);
    7320             :                 }
    7321             :         }
    7322             :         if (!inherit_ctso && ptr->ctrn_ctts) {
    7323             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_ctts);
    7324             :                 ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
    7325             :                 for (i=first_idx; i<ptr->sample_count; i++) {
    7326             :                         ent = gf_list_get(ptr->entries, i);
    7327             :                         ent->CTS_Offset = gf_bs_read_int(bs, nbbits);
    7328             :                         if (ptr->ctso_multiplier)
    7329             :                                 ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
    7330             :                 }
    7331             :         }
    7332             : 
    7333             :         return GF_OK;
    7334             : }
    7335             : #endif
    7336             : 
    7337        4231 : GF_Err trun_box_read(GF_Box *s, GF_BitStream *bs)
    7338             : {
    7339             :         u32 i;
    7340             :         GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
    7341             : 
    7342             : #ifdef GF_ENABLE_CTRN
    7343             :         if (ptr->type == GF_ISOM_BOX_TYPE_CTRN) {
    7344             :                 ptr->type = GF_ISOM_BOX_TYPE_TRUN;
    7345             :                 ptr->use_ctrn = GF_TRUE;
    7346             :                 return ctrn_box_read(s, bs);
    7347             :         }
    7348             : #endif
    7349             : 
    7350             :         //check this is a good file
    7351        4231 :         if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS))
    7352             :                 return GF_ISOM_INVALID_FILE;
    7353             : 
    7354        4231 :         ISOM_DECREASE_SIZE(ptr, 4);
    7355        4231 :         ptr->sample_count = gf_bs_read_u32(bs);
    7356             : 
    7357             :         //The rest depends on the flags
    7358        4231 :         if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
    7359        4189 :                 ISOM_DECREASE_SIZE(ptr, 4);
    7360        4189 :                 ptr->data_offset = gf_bs_read_u32(bs);
    7361             :         }
    7362        4231 :         if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
    7363        3208 :                 ISOM_DECREASE_SIZE(ptr, 4);
    7364        3208 :                 ptr->first_sample_flags = gf_bs_read_u32(bs);
    7365             :         }
    7366        4231 :         if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
    7367         188 :                 ptr->samples = gf_malloc(sizeof(GF_TrunEntry));
    7368         188 :                 if (!ptr->samples) return GF_OUT_OF_MEM;
    7369             :                 //memset to 0 !!
    7370             :                 memset(ptr->samples, 0, sizeof(GF_TrunEntry));
    7371         188 :                 ptr->sample_alloc = ptr->nb_samples = 1;
    7372         188 :                 ptr->samples[0].nb_pack = ptr->sample_count;
    7373             :         } else {
    7374             :                 //if we get here, at least one flag (so at least 4 bytes) is set, check size
    7375        4043 :                 if (ptr->sample_count * 4 > ptr->size) {
    7376           0 :                         ISOM_DECREASE_SIZE(ptr, ptr->sample_count*4);
    7377             :                 }
    7378        4043 :                 ptr->samples = gf_malloc(sizeof(GF_TrunEntry) * ptr->sample_count);
    7379        4043 :                 if (!ptr->samples) return GF_OUT_OF_MEM;
    7380        4043 :                 ptr->sample_alloc = ptr->nb_samples = ptr->sample_count;
    7381             :                 //memset to 0 upfront
    7382        4043 :                 memset(ptr->samples, 0, ptr->sample_count * sizeof(GF_TrunEntry));
    7383             : 
    7384             :                 //read each entry (even though nothing may be written)
    7385      116893 :                 for (i=0; i<ptr->sample_count; i++) {
    7386             :                         u32 trun_size = 0;
    7387      112850 :                         GF_TrunEntry *p = &ptr->samples[i];
    7388             : 
    7389      112850 :                         if (ptr->flags & GF_ISOM_TRUN_DURATION) {
    7390        5361 :                                 p->Duration = gf_bs_read_u32(bs);
    7391             :                                 trun_size += 4;
    7392             :                         }
    7393      112850 :                         if (ptr->flags & GF_ISOM_TRUN_SIZE) {
    7394      112850 :                                 p->size = gf_bs_read_u32(bs);
    7395      112850 :                                 trun_size += 4;
    7396             :                         }
    7397             :                         //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
    7398      112850 :                         if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
    7399        6550 :                                 p->flags = gf_bs_read_u32(bs);
    7400        6550 :                                 trun_size += 4;
    7401             :                         }
    7402      112850 :                         if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
    7403        5385 :                                 if (ptr->version==0) {
    7404        4422 :                                         p->CTS_Offset = (u32) gf_bs_read_u32(bs);
    7405             :                                 } else {
    7406         963 :                                         p->CTS_Offset = (s32) gf_bs_read_u32(bs);
    7407             :                                 }
    7408        5385 :                                 trun_size += 4;
    7409             :                         }
    7410      112850 :                         ISOM_DECREASE_SIZE(ptr, trun_size);
    7411             :                 }
    7412             :         }
    7413             :         /*todo parse sample reorder*/
    7414        4231 :         if (ptr->size) {
    7415           0 :                 gf_bs_skip_bytes(bs, ptr->size);
    7416           0 :                 ptr->size = 0;
    7417             :         }
    7418             :         return GF_OK;
    7419             : }
    7420             : 
    7421        8008 : GF_Box *trun_box_new()
    7422             : {
    7423       16016 :         ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
    7424             :         //NO FLAGS SET BY DEFAULT
    7425        8008 :         return (GF_Box *)tmp;
    7426             : }
    7427             : 
    7428             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7429             : 
    7430             : #ifdef GF_ENABLE_CTRN
    7431             : static void ctrn_write_sample_flags(GF_BitStream *bs, u32 flags, u32 field_size)
    7432             : {
    7433             :         if (!field_size) return;
    7434             : 
    7435             :         if (field_size==8) flags = flags>>24;
    7436             :         else if (field_size==16) flags = flags>>16;
    7437             :         gf_bs_write_int(bs, flags, field_size);
    7438             : }
    7439             : 
    7440             : 
    7441             : static void ctrn_write_ctso(GF_TrackFragmentRunBox *ctrn, GF_BitStream *bs, u32 ctso, u32 field_size)
    7442             : {
    7443             :         if (!field_size) return;
    7444             : 
    7445             :         if (ctrn->ctso_multiplier) {
    7446             :                 gf_bs_write_int(bs, ctso / ctrn->ctso_multiplier, field_size);
    7447             :         } else {
    7448             :                 gf_bs_write_int(bs, ctso, field_size);
    7449             :         }
    7450             : }
    7451             : 
    7452             : GF_Err ctrn_box_write(GF_Box *s, GF_BitStream *bs)
    7453             : {
    7454             :         GF_Err e;
    7455             :         u32 i, count, flags;
    7456             :         GF_TrunEntry *ent;
    7457             :         GF_TrackFragmentRunBox *ctrn = (GF_TrackFragmentRunBox *) s;
    7458             :         if (!s) return GF_BAD_PARAM;
    7459             :         flags = ctrn->flags;
    7460             :         ctrn->flags = ctrn->ctrn_flags;
    7461             :         ctrn->type = GF_ISOM_BOX_TYPE_CTRN;
    7462             : 
    7463             :         e = gf_isom_full_box_write(s, bs);
    7464             :         if (e) return e;
    7465             :         ctrn->flags = flags;
    7466             :         ctrn->type = GF_ISOM_BOX_TYPE_TRUN;
    7467             : 
    7468             :         gf_bs_write_u16(bs, ctrn->sample_count);
    7469             :         if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
    7470             :                 if (ctrn->ctrn_flags & GF_ISOM_CTRN_DATAOFFSET_16) {
    7471             :                         gf_bs_write_u16(bs, ctrn->data_offset);
    7472             :                 } else {
    7473             :                         gf_bs_write_u32(bs, ctrn->data_offset);
    7474             :                 }
    7475             :         }
    7476             :         if (ctrn->ctso_multiplier) {
    7477             :                 gf_bs_write_u16(bs, ctrn->ctso_multiplier);
    7478             :         }
    7479             :         /*we always write first sample using first flags*/
    7480             :         ent = gf_list_get(ctrn->entries, 0);
    7481             :         gf_bs_write_int(bs, ent->Duration, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_dur) );
    7482             :         gf_bs_write_int(bs, ent->size, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_size) );
    7483             :         ctrn_write_sample_flags(bs, ent->flags, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_sample_flags) );
    7484             :         ctrn_write_ctso(ctrn,bs, ent->CTS_Offset, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_ctts) );
    7485             : 
    7486             :         count = gf_list_count(ctrn->entries);
    7487             :         if (ctrn->ctrn_dur) {
    7488             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_dur);
    7489             :                 for (i=1; i<count; i++) {
    7490             :                         GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7491             :                         gf_bs_write_int(bs, a_ent->Duration, nbbits);
    7492             :                 }
    7493             :         }
    7494             :         if (ctrn->ctrn_size) {
    7495             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_size);
    7496             :                 for (i=1; i<count; i++) {
    7497             :                         GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7498             :                         gf_bs_write_int(bs, a_ent->size, nbbits);
    7499             :                 }
    7500             :         }
    7501             :         if (ctrn->ctrn_sample_flags) {
    7502             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_sample_flags);
    7503             :                 for (i=1; i<count; i++) {
    7504             :                         GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7505             :                         ctrn_write_sample_flags(bs, a_ent->flags, nbbits);
    7506             :                 }
    7507             :         }
    7508             :         if (ctrn->ctrn_ctts) {
    7509             :                 u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_ctts);
    7510             :                 for (i=1; i<count; i++) {
    7511             :                         GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7512             :                         ctrn_write_ctso(ctrn, bs, a_ent->CTS_Offset, nbbits);
    7513             :                 }
    7514             :         }
    7515             : 
    7516             :         return GF_OK;
    7517             : }
    7518             : #endif
    7519             : 
    7520        3863 : GF_Err trun_box_write(GF_Box *s, GF_BitStream *bs)
    7521             : {
    7522             :         GF_Err e;
    7523             :         u32 i;
    7524             :         GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *) s;
    7525        3863 :         if (!s) return GF_BAD_PARAM;
    7526             : 
    7527             : #ifdef GF_ENABLE_CTRN
    7528             :         if (ptr->use_ctrn)
    7529             :                 return ctrn_box_write(s, bs);
    7530             : #endif
    7531             : 
    7532        3863 :         e = gf_isom_full_box_write(s, bs);
    7533        3863 :         if (e) return e;
    7534             : 
    7535        3863 :         gf_bs_write_u32(bs, ptr->sample_count);
    7536             : 
    7537             :         //The rest depends on the flags
    7538        3863 :         if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
    7539        3796 :                 gf_bs_write_u32(bs, ptr->data_offset);
    7540             :         }
    7541        3863 :         if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
    7542        2425 :                 gf_bs_write_u32(bs, ptr->first_sample_flags);
    7543             :         }
    7544             : 
    7545        3863 :         if (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) )  {
    7546      112658 :                 for (i=0; i<ptr->nb_samples; i++) {
    7547      112658 :                         GF_TrunEntry *p = &ptr->samples[i];
    7548             : 
    7549      112658 :                         if (ptr->flags & GF_ISOM_TRUN_DURATION) {
    7550        3477 :                                 gf_bs_write_u32(bs, p->Duration);
    7551             :                         }
    7552      112658 :                         if (ptr->flags & GF_ISOM_TRUN_SIZE) {
    7553      112518 :                                 gf_bs_write_u32(bs, p->size);
    7554             :                         }
    7555             :                         //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
    7556      112658 :                         if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
    7557       10242 :                                 gf_bs_write_u32(bs, p->flags);
    7558             :                         }
    7559      112658 :                         if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
    7560       16490 :                                 if (ptr->version==0) {
    7561       12411 :                                         gf_bs_write_u32(bs, p->CTS_Offset);
    7562             :                                 } else {
    7563        4079 :                                         gf_bs_write_u32(bs, (u32) p->CTS_Offset);
    7564             :                                 }
    7565             :                         }
    7566             :                 }
    7567             :         }
    7568             : 
    7569        3863 :         if (ptr->sample_order) {
    7570             :                 u32 nb_bits = 8;
    7571           0 :                 if (ptr->sample_count>0xFFFFFF) nb_bits = 32;
    7572           0 :                 else if (ptr->sample_count>0xFFFF) nb_bits = 24;
    7573           0 :                 else if (ptr->sample_count>0xFF) nb_bits = 16;
    7574             : 
    7575           0 :                 for (i=0; i<ptr->sample_count; i++) {
    7576           0 :                         gf_bs_write_int(bs, ptr->sample_order[i], nb_bits);
    7577             :                 }
    7578             :         }
    7579             :         return GF_OK;
    7580             : }
    7581             : 
    7582             : #ifdef GF_ENABLE_CTRN
    7583             : static u32 ctrn_sample_flags_to_index(u32 val)
    7584             : {
    7585             :         if (!val) return 0;
    7586             :         if (val & 0x0000FFFF)
    7587             :                 return 3;
    7588             :         if (val & 0x00FF0000)
    7589             :                 return 2;
    7590             :         return 1;
    7591             : }
    7592             : static u32 ctrn_u32_to_index(u32 val)
    7593             : {
    7594             :         if (!val) return 0;
    7595             :         if (val<=255) return 1;
    7596             :         if (val<=65535) return 2;
    7597             :         return 3;
    7598             : }
    7599             : static u32 ctrn_s32_to_index(s32 val)
    7600             : {
    7601             :         if (!val) return 0;
    7602             :         if (ABS(val)<=127) return 1;
    7603             :         if (ABS(val)<=32767) return 2;
    7604             :         return 3;
    7605             : }
    7606             : static u32 ctrn_ctts_to_index(GF_TrackFragmentRunBox *ctrn, s32 ctts)
    7607             : {
    7608             :         if (!(ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET))
    7609             :                 return 0;
    7610             : 
    7611             :         if (!ctts) return 0;
    7612             : 
    7613             :         if (ctrn->version) {
    7614             :                 if (ctrn->ctso_multiplier) return ctrn_s32_to_index(ctts / ctrn->ctso_multiplier);
    7615             :                 return ctrn_s32_to_index(ctts);
    7616             :         }
    7617             :         assert(ctts>0);
    7618             :         if (ctrn->ctso_multiplier) return ctrn_u32_to_index((u32)ctts / ctrn->ctso_multiplier);
    7619             :         return ctrn_s32_to_index((u32)ctts);
    7620             : }
    7621             : 
    7622             : static GF_Err ctrn_box_size(GF_TrackFragmentRunBox *ctrn)
    7623             : {
    7624             :         Bool use_ctso_multi = GF_TRUE;
    7625             :         u32 i, count;
    7626             :         GF_TrunEntry *ent;
    7627             : 
    7628             :         ctrn->ctrn_flags = 0;
    7629             :         ctrn->ctrn_first_dur = ctrn->ctrn_first_size = ctrn->ctrn_first_sample_flags = ctrn->ctrn_first_ctts = 0;
    7630             :         ctrn->ctrn_dur = ctrn->ctrn_size = ctrn->ctrn_sample_flags = ctrn->ctrn_ctts = 0;
    7631             : 
    7632             :         ctrn->size += 2; //16 bits for sample count
    7633             :         if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
    7634             :                 ctrn->ctrn_flags |= GF_ISOM_TRUN_DATA_OFFSET;
    7635             :                 if (ABS(ctrn->data_offset) < 32767) {
    7636             :                         ctrn->size += 2;
    7637             :                         ctrn->ctrn_flags |= GF_ISOM_CTRN_DATAOFFSET_16;
    7638             :                 } else
    7639             :                         ctrn->size += 4;
    7640             :         }
    7641             : 
    7642             :         count = gf_list_count(ctrn->entries);
    7643             :         if (ctrn->ctso_multiplier && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET) && (ctrn->ctso_multiplier<=0xFFFF) ) {
    7644             :                 for (i=0; i<count; i++) {
    7645             :                         GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7646             :                         if (a_ent->CTS_Offset % ctrn->ctso_multiplier) {
    7647             :                                 use_ctso_multi = GF_FALSE;
    7648             :                                 break;
    7649             :                         }
    7650             :                 }
    7651             :         } else {
    7652             :                 use_ctso_multi = GF_FALSE;
    7653             :         }
    7654             :         if (ctrn->use_inherit) {
    7655             :                 use_ctso_multi = GF_FALSE;
    7656             :                 ctrn->ctrn_flags |= 0xB0; //duration=1,size=0,flags=1,cts=1 << 4
    7657             :         }
    7658             : 
    7659             :         if (use_ctso_multi) {
    7660             :                 ctrn->size += 2;
    7661             :                 ctrn->ctrn_flags |= GF_ISOM_CTRN_CTSO_MULTIPLIER;
    7662             :         } else {
    7663             :                 ctrn->ctso_multiplier = 0;
    7664             :         }
    7665             : 
    7666             :         /*we always write first sample using first flags*/
    7667             :         ent = gf_list_get(ctrn->entries, 0);
    7668             :         ctrn->ctrn_flags |= GF_ISOM_CTRN_FIRST_SAMPLE;
    7669             : 
    7670             :         if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
    7671             :                 ctrn->ctrn_first_dur = ctrn_u32_to_index(ent->Duration);
    7672             :                 if (ctrn->ctrn_first_dur) {
    7673             :                         ctrn->size += ctrn_field_size(ctrn->ctrn_first_dur);
    7674             :                         ctrn->ctrn_flags |= ctrn->ctrn_first_dur<<22;
    7675             :                 }
    7676             :         }
    7677             : 
    7678             :         if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
    7679             :                 ctrn->ctrn_first_size = ctrn_u32_to_index(ent->size);
    7680             :                 if (ctrn->ctrn_first_size) {
    7681             :                         ctrn->size += ctrn_field_size(ctrn->ctrn_first_size);
    7682             :                         ctrn->ctrn_flags |= ctrn->ctrn_first_size<<20;
    7683             :                 }
    7684             :         }
    7685             : 
    7686             :         if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
    7687             :                 ctrn->ctrn_first_sample_flags = ctrn_sample_flags_to_index(ent->flags);
    7688             :                 if (ctrn->ctrn_first_sample_flags) {
    7689             :                         ctrn->size += ctrn_field_size(ctrn->ctrn_first_sample_flags);
    7690             :                         ctrn->ctrn_flags |= ctrn->ctrn_first_sample_flags<<18;
    7691             :                 }
    7692             :         }
    7693             :         if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET)) {
    7694             :                 ctrn->ctrn_first_ctts = ctrn_ctts_to_index(ctrn, ent->CTS_Offset);
    7695             :                 if (ctrn->ctrn_first_ctts) {
    7696             :                         ctrn->size += ctrn_field_size(ctrn->ctrn_first_ctts);
    7697             :                         ctrn->ctrn_flags |= ctrn->ctrn_first_ctts<<16;
    7698             :                 }
    7699             :         }
    7700             : 
    7701             :         for (i=1; i<count; i++) {
    7702             :                 u8 field_idx;
    7703             :                 GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
    7704             : 
    7705             :                 if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
    7706             :                         field_idx = ctrn_u32_to_index(a_ent->Duration);
    7707             :                         if (ctrn->ctrn_dur < field_idx)
    7708             :                                 ctrn->ctrn_dur = field_idx;
    7709             :                 }
    7710             :                 if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
    7711             :                         field_idx = ctrn_u32_to_index(a_ent->size);
    7712             :                         if (ctrn->ctrn_size < field_idx)
    7713             :                                 ctrn->ctrn_size = field_idx;
    7714             :                 }
    7715             :                 if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
    7716             :                         field_idx = ctrn_sample_flags_to_index(a_ent->flags);
    7717             :                         if (ctrn->ctrn_sample_flags < field_idx)
    7718             :                                 ctrn->ctrn_sample_flags = field_idx;
    7719             :                 }
    7720             :                 if (!ctrn->use_inherit) {
    7721             :                         field_idx = ctrn_ctts_to_index(ctrn, a_ent->CTS_Offset);
    7722             :                         if (ctrn->ctrn_ctts < field_idx)
    7723             :                                 ctrn->ctrn_ctts = field_idx;
    7724             :                 }
    7725             :         }
    7726             :         count-=1;
    7727             :         if (ctrn->ctrn_dur) {
    7728             :                 ctrn->size += count * ctrn_field_size(ctrn->ctrn_dur);
    7729             :                 ctrn->ctrn_flags |= ctrn->ctrn_dur<<14;
    7730             :         }
    7731             :         if (ctrn->ctrn_size) {
    7732             :                 ctrn->size += count * ctrn_field_size(ctrn->ctrn_size);
    7733             :                 ctrn->ctrn_flags |= ctrn->ctrn_size<<12;
    7734             :         }
    7735             :         if (ctrn->ctrn_sample_flags) {
    7736             :                 ctrn->size += count * ctrn_field_size(ctrn->ctrn_sample_flags);
    7737             :                 ctrn->ctrn_flags |= ctrn->ctrn_sample_flags<<10;
    7738             :         }
    7739             :         if (ctrn->ctrn_ctts) {
    7740             :                 ctrn->size += count * ctrn_field_size(ctrn->ctrn_ctts);
    7741             :                 ctrn->ctrn_flags |= ctrn->ctrn_ctts<<8;
    7742             :         }
    7743             :         return GF_OK;
    7744             : }
    7745             : #endif
    7746             : 
    7747       11217 : GF_Err trun_box_size(GF_Box *s)
    7748             : {
    7749             :         GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
    7750             : 
    7751             : #ifdef GF_ENABLE_CTRN
    7752             :         if (ptr->use_ctrn)
    7753             :                 return ctrn_box_size(ptr);
    7754             : #endif
    7755             : 
    7756       11217 :         ptr->size += 4;
    7757             :         //The rest depends on the flags
    7758       11217 :         if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
    7759       11217 :         if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;
    7760             : 
    7761       11217 :         if (ptr->sample_order) {
    7762             :                 u32 nb_bytes = 1;
    7763           0 :                 if (ptr->sample_count>0xFFFFFF) nb_bytes = 4;
    7764           0 :                 else if (ptr->sample_count>0xFFFF) nb_bytes = 3;
    7765           0 :                 else if (ptr->sample_count>0xFF) nb_bytes = 2;
    7766           0 :                 ptr->size += ptr->sample_count*nb_bytes;
    7767             :         }
    7768             : 
    7769       11217 :         if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
    7770             :                 return GF_OK;
    7771             :         }
    7772             : 
    7773             :         //if nothing to do, this will be skipped automatically
    7774        7208 :         if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4*ptr->nb_samples;
    7775        7208 :         if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4*ptr->nb_samples;
    7776             :         //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
    7777        7208 :         if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4*ptr->nb_samples;
    7778        7208 :         if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4*ptr->nb_samples;
    7779             : 
    7780             :         return GF_OK;
    7781             : }
    7782             : 
    7783             : 
    7784             : 
    7785             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7786             : 
    7787             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    7788             : 
    7789             : 
    7790           4 : void tsro_box_del(GF_Box *s)
    7791             : {
    7792             :         GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s;
    7793           4 :         gf_free(tsro);
    7794           4 : }
    7795             : 
    7796           1 : GF_Err tsro_box_read(GF_Box *s, GF_BitStream *bs)
    7797             : {
    7798             :         GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
    7799           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    7800           1 :         ptr->TimeOffset = gf_bs_read_u32(bs);
    7801           1 :         return GF_OK;
    7802             : }
    7803             : 
    7804           4 : GF_Box *tsro_box_new()
    7805             : {
    7806           8 :         ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
    7807           4 :         return (GF_Box *)tmp;
    7808             : }
    7809             : 
    7810             : 
    7811             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7812           2 : GF_Err tsro_box_write(GF_Box *s, GF_BitStream *bs)
    7813             : {
    7814             :         GF_Err e;
    7815             :         GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
    7816           2 :         if (ptr == NULL) return GF_BAD_PARAM;
    7817             : 
    7818           2 :         e = gf_isom_box_write_header(s, bs);
    7819           2 :         if (e) return e;
    7820           2 :         gf_bs_write_u32(bs, ptr->TimeOffset);
    7821           2 :         return GF_OK;
    7822             : }
    7823             : 
    7824           4 : GF_Err tsro_box_size(GF_Box *s)
    7825             : {
    7826           4 :         s->size += 4;
    7827           4 :         return GF_OK;
    7828             : }
    7829             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7830             : 
    7831             : 
    7832         527 : void udta_box_del(GF_Box *s)
    7833             : {
    7834             :         u32 i;
    7835             :         GF_UserDataMap *map;
    7836             :         GF_UserDataBox *ptr = (GF_UserDataBox *)s;
    7837         527 :         if (ptr == NULL) return;
    7838         527 :         i=0;
    7839        1540 :         while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
    7840         486 :                 gf_isom_box_array_del(map->boxes);
    7841         486 :                 gf_free(map);
    7842             :         }
    7843         527 :         gf_list_del(ptr->recordList);
    7844         527 :         gf_free(ptr);
    7845             : }
    7846             : 
    7847        1350 : GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid)
    7848             : {
    7849             :         u32 i;
    7850             :         GF_UserDataMap *map;
    7851        1350 :         if (ptr == NULL) return NULL;
    7852        1350 :         i=0;
    7853        2736 :         while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
    7854         750 :                 if (map->boxType == box_type) {
    7855         714 :                         if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map;
    7856           0 :                         if (!memcmp(map->uuid, *uuid, 16)) return map;
    7857             :                 }
    7858             :         }
    7859             :         return NULL;
    7860             : }
    7861             : 
    7862         533 : GF_Err udta_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    7863             : {
    7864             :         GF_Err e;
    7865             :         u32 box_type;
    7866             :         GF_UserDataMap *map;
    7867             :         GF_UserDataBox *ptr = (GF_UserDataBox *)s;
    7868         533 :         if (!ptr) return GF_BAD_PARAM;
    7869         533 :         if (!a) return GF_OK;
    7870             : 
    7871             :         //detach from parent list if any
    7872         533 :         gf_list_del_item(ptr->child_boxes, a);
    7873             : 
    7874             :         /* for unknown udta boxes, we reference them by their original box type */
    7875         533 :         box_type = a->type;
    7876         533 :         if (box_type == GF_ISOM_BOX_TYPE_UNKNOWN) {
    7877             :                 GF_UnknownBox* unkn = (GF_UnknownBox *)a;
    7878         121 :                 box_type = unkn->original_4cc;
    7879             :         }
    7880             : 
    7881         533 :         map = udta_getEntry(ptr, box_type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL);
    7882         533 :         if (map == NULL) {
    7883         491 :                 if (is_rem) return GF_OK;
    7884             : 
    7885         491 :                 map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap));
    7886         491 :                 if (map == NULL) return GF_OUT_OF_MEM;
    7887             :                 memset(map, 0, sizeof(GF_UserDataMap));
    7888             : 
    7889         491 :                 map->boxType = box_type;
    7890         491 :                 if (a->type == GF_ISOM_BOX_TYPE_UUID)
    7891           0 :                         memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
    7892         491 :                 map->boxes = gf_list_new();
    7893         491 :                 if (!map->boxes) {
    7894           0 :                         gf_free(map);
    7895           0 :                         return GF_OUT_OF_MEM;
    7896             :                 }
    7897         491 :                 e = gf_list_add(ptr->recordList, map);
    7898         491 :                 if (e) return e;
    7899             :         }
    7900         533 :         if (is_rem) {
    7901           0 :                 gf_list_del_item(map->boxes, a);
    7902           0 :                 return GF_OK;
    7903             :         }
    7904         533 :         return gf_list_add(map->boxes, a);
    7905             : }
    7906             : 
    7907             : 
    7908         343 : GF_Err udta_box_read(GF_Box *s, GF_BitStream *bs)
    7909             : {
    7910         343 :         GF_Err e = gf_isom_box_array_read(s, bs);
    7911         343 :         if (e) return e;
    7912         343 :         if (s->size==4) {
    7913           7 :                 u32 val = gf_bs_read_u32(bs);
    7914           7 :                 s->size = 0;
    7915           7 :                 if (val) {
    7916           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] udta has 4 remaining bytes set to %08X but they should be 0\n", val));
    7917             :                 }
    7918             :         }
    7919             :         return GF_OK;
    7920             : }
    7921             : 
    7922         527 : GF_Box *udta_box_new()
    7923             : {
    7924        1054 :         ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
    7925         527 :         tmp->recordList = gf_list_new();
    7926         527 :         if (!tmp->recordList) {
    7927           0 :                 gf_free(tmp);
    7928           0 :                 return NULL;
    7929             :         }
    7930             :         return (GF_Box *)tmp;
    7931             : }
    7932             : 
    7933             : 
    7934             : #ifndef GPAC_DISABLE_ISOM_WRITE
    7935             : 
    7936         414 : GF_Err udta_box_write(GF_Box *s, GF_BitStream *bs)
    7937             : {
    7938             :         GF_Err e;
    7939             :         u32 i;
    7940             :         GF_UserDataMap *map;
    7941             :         GF_UserDataBox *ptr = (GF_UserDataBox *)s;
    7942             : 
    7943         414 :         e = gf_isom_box_write_header(s, bs);
    7944         414 :         if (e) return e;
    7945         414 :         i=0;
    7946        1213 :         while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
    7947             :                 //warning: here we are not passing the actual "parent" of the list
    7948             :                 //but the UDTA box. The parent itself is not an box, we don't care about it
    7949         385 :                 e = gf_isom_box_array_write(s, map->boxes, bs);
    7950         385 :                 if (e) return e;
    7951             :         }
    7952             :         return GF_OK;
    7953             : }
    7954             : 
    7955         986 : GF_Err udta_box_size(GF_Box *s)
    7956             : {
    7957             :         GF_Err e;
    7958             :         u32 i;
    7959             :         GF_UserDataMap *map;
    7960             :         GF_UserDataBox *ptr = (GF_UserDataBox *)s;
    7961             : 
    7962         986 :         i=0;
    7963        2923 :         while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
    7964             :                 //warning: here we are not passing the actual "parent" of the list
    7965             :                 //but the UDTA box. The parent itself is not an box, we don't care about it
    7966         951 :                 e = gf_isom_box_array_size(s, map->boxes);
    7967         951 :                 if (e) return e;
    7968             :         }
    7969             :         return GF_OK;
    7970             : }
    7971             : 
    7972             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    7973             : 
    7974             : 
    7975        2349 : void vmhd_box_del(GF_Box *s)
    7976             : {
    7977             :         GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
    7978        2349 :         if (ptr == NULL) return;
    7979        2349 :         gf_free(ptr);
    7980             : }
    7981             : 
    7982             : 
    7983        1810 : GF_Err vmhd_box_read(GF_Box *s, GF_BitStream *bs)
    7984             : {
    7985             :         GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
    7986             : 
    7987        1810 :         ISOM_DECREASE_SIZE(ptr, 8);
    7988        1810 :         ptr->reserved = gf_bs_read_u64(bs);
    7989        1810 :         return GF_OK;
    7990             : }
    7991             : 
    7992        2349 : GF_Box *vmhd_box_new()
    7993             : {
    7994        4698 :         ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
    7995        2349 :         tmp->flags = 1;
    7996        2349 :         return (GF_Box *)tmp;
    7997             : }
    7998             : 
    7999             : 
    8000             : 
    8001             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8002             : 
    8003        1888 : GF_Err vmhd_box_write(GF_Box *s, GF_BitStream *bs)
    8004             : {
    8005             :         GF_Err e;
    8006             :         GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
    8007             : 
    8008        1888 :         e = gf_isom_full_box_write(s, bs);
    8009        1888 :         if (e) return e;
    8010        1888 :         gf_bs_write_u64(bs, ptr->reserved);
    8011        1888 :         return GF_OK;
    8012             : }
    8013             : 
    8014        3375 : GF_Err vmhd_box_size(GF_Box *s)
    8015             : {
    8016             :         GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
    8017        3375 :         ptr->size += 8;
    8018        3375 :         return GF_OK;
    8019             : }
    8020             : 
    8021             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8022             : 
    8023           2 : void void_box_del(GF_Box *s)
    8024             : {
    8025           2 :         gf_free(s);
    8026           2 : }
    8027             : 
    8028             : 
    8029           0 : GF_Err void_box_read(GF_Box *s, GF_BitStream *bs)
    8030             : {
    8031           0 :         if (s->size) return GF_ISOM_INVALID_FILE;
    8032           0 :         return GF_OK;
    8033             : }
    8034             : 
    8035           2 : GF_Box *void_box_new()
    8036             : {
    8037           4 :         ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
    8038           2 :         return tmp;
    8039             : }
    8040             : 
    8041             : 
    8042             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8043             : 
    8044           1 : GF_Err void_box_write(GF_Box *s, GF_BitStream *bs)
    8045             : {
    8046           1 :         gf_bs_write_u32(bs, 0);
    8047           1 :         return GF_OK;
    8048             : }
    8049             : 
    8050           1 : GF_Err void_box_size(GF_Box *s)
    8051             : {
    8052           1 :         s->size = 4;
    8053           1 :         return GF_OK;
    8054             : }
    8055             : 
    8056             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8057             : 
    8058             : 
    8059             : 
    8060           3 : GF_Box *pdin_box_new()
    8061             : {
    8062           6 :         ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
    8063           3 :         return (GF_Box *)tmp;
    8064             : }
    8065             : 
    8066             : 
    8067           3 : void pdin_box_del(GF_Box *s)
    8068             : {
    8069             :         GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
    8070           3 :         if (ptr == NULL) return;
    8071           3 :         if (ptr->rates) gf_free(ptr->rates);
    8072           3 :         if (ptr->times) gf_free(ptr->times);
    8073           3 :         gf_free(ptr);
    8074             : }
    8075             : 
    8076             : 
    8077           1 : GF_Err pdin_box_read(GF_Box *s, GF_BitStream *bs)
    8078             : {
    8079             :         u32 i;
    8080             :         GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
    8081             : 
    8082           1 :         ptr->count = (u32) (ptr->size) / 8;
    8083           1 :         ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count);
    8084           1 :         if (!ptr->rates) return GF_OUT_OF_MEM;
    8085           1 :         ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count);
    8086           1 :         if (!ptr->times) return GF_OUT_OF_MEM;
    8087           0 :         for (i=0; i<ptr->count; i++) {
    8088           0 :                 ptr->rates[i] = gf_bs_read_u32(bs);
    8089           0 :                 ptr->times[i] = gf_bs_read_u32(bs);
    8090             :         }
    8091             :         return GF_OK;
    8092             : }
    8093             : 
    8094             : 
    8095             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8096             : 
    8097           1 : GF_Err pdin_box_write(GF_Box *s, GF_BitStream *bs)
    8098             : {
    8099             :         GF_Err e;
    8100             :         u32 i;
    8101             :         GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
    8102           1 :         e = gf_isom_full_box_write(s, bs);
    8103           1 :         if (e) return e;
    8104           0 :         for (i=0; i<ptr->count; i++) {
    8105           0 :                 gf_bs_write_u32(bs, ptr->rates[i]);
    8106           0 :                 gf_bs_write_u32(bs, ptr->times[i]);
    8107             :         }
    8108             :         return GF_OK;
    8109             : }
    8110             : 
    8111           1 : GF_Err pdin_box_size(GF_Box *s)
    8112             : {
    8113             :         GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
    8114           1 :         ptr->size += 8*ptr->count;
    8115           1 :         return GF_OK;
    8116             : }
    8117             : 
    8118             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8119             : 
    8120             : 
    8121             : 
    8122             : 
    8123       17308 : GF_Box *sdtp_box_new()
    8124             : {
    8125       34616 :         ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
    8126       17308 :         return (GF_Box *)tmp;
    8127             : }
    8128             : 
    8129             : 
    8130       17308 : void sdtp_box_del(GF_Box *s)
    8131             : {
    8132             :         GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
    8133       17308 :         if (ptr == NULL) return;
    8134       17308 :         if (ptr->sample_info) gf_free(ptr->sample_info);
    8135       17308 :         gf_free(ptr);
    8136             : }
    8137             : 
    8138             : 
    8139          47 : GF_Err sdtp_box_read(GF_Box *s, GF_BitStream *bs)
    8140             : {
    8141             :         GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
    8142             : 
    8143             :         /*out-of-order sdtp, assume no padding at the end*/
    8144          47 :         if (!ptr->sampleCount) ptr->sampleCount = (u32) ptr->size;
    8145           0 :         else if (ptr->sampleCount > (u32) ptr->size) return GF_ISOM_INVALID_FILE;
    8146             : 
    8147          47 :         ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount);
    8148          47 :         if (!ptr->sample_info) return GF_OUT_OF_MEM;
    8149          47 :         ptr->sample_alloc = ptr->sampleCount;
    8150          47 :         gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
    8151          47 :         ISOM_DECREASE_SIZE(ptr, ptr->sampleCount);
    8152          47 :         return GF_OK;
    8153             : }
    8154             : 
    8155             : 
    8156             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8157             : 
    8158          13 : GF_Err sdtp_box_write(GF_Box *s, GF_BitStream *bs)
    8159             : {
    8160             :         GF_Err e;
    8161             :         GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
    8162          13 :         e = gf_isom_full_box_write(s, bs);
    8163          13 :         if (e) return e;
    8164          13 :         gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
    8165          13 :         return GF_OK;
    8166             : }
    8167             : 
    8168          37 : GF_Err sdtp_box_size(GF_Box *s)
    8169             : {
    8170             :         GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
    8171          37 :         ptr->size += ptr->sampleCount;
    8172          37 :         return GF_OK;
    8173             : }
    8174             : 
    8175             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8176             : 
    8177             : 
    8178         271 : GF_Box *pasp_box_new()
    8179             : {
    8180         542 :         ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
    8181         271 :         return (GF_Box *)tmp;
    8182             : }
    8183             : 
    8184             : 
    8185         271 : void pasp_box_del(GF_Box *s)
    8186             : {
    8187             :         GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
    8188         271 :         if (ptr == NULL) return;
    8189         271 :         gf_free(ptr);
    8190             : }
    8191             : 
    8192             : 
    8193         116 : GF_Err pasp_box_read(GF_Box *s, GF_BitStream *bs)
    8194             : {
    8195             :         GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
    8196         116 :         ISOM_DECREASE_SIZE(ptr, 8);
    8197         116 :         ptr->hSpacing = gf_bs_read_u32(bs);
    8198         116 :         ptr->vSpacing = gf_bs_read_u32(bs);
    8199         116 :         return GF_OK;
    8200             : }
    8201             : 
    8202             : 
    8203             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8204             : 
    8205         198 : GF_Err pasp_box_write(GF_Box *s, GF_BitStream *bs)
    8206             : {
    8207             :         GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s;
    8208         198 :         GF_Err e = gf_isom_box_write_header(s, bs);
    8209         198 :         if (e) return e;
    8210         198 :         gf_bs_write_u32(bs, ptr->hSpacing);
    8211         198 :         gf_bs_write_u32(bs, ptr->vSpacing);
    8212         198 :         return GF_OK;
    8213             : }
    8214             : 
    8215         500 : GF_Err pasp_box_size(GF_Box *s)
    8216             : {
    8217         500 :         s->size += 8;
    8218         500 :         return GF_OK;
    8219             : }
    8220             : 
    8221             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8222             : 
    8223             : 
    8224             : 
    8225          14 : GF_Box *clap_box_new()
    8226             : {
    8227          28 :         ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP);
    8228          14 :         return (GF_Box *)tmp;
    8229             : }
    8230             : 
    8231             : 
    8232          14 : void clap_box_del(GF_Box *s)
    8233             : {
    8234             :         GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
    8235          14 :         if (ptr == NULL) return;
    8236          14 :         gf_free(ptr);
    8237             : }
    8238             : 
    8239             : 
    8240           1 : GF_Err clap_box_read(GF_Box *s, GF_BitStream *bs)
    8241             : {
    8242             :         GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
    8243           1 :         ISOM_DECREASE_SIZE(ptr, 32);
    8244           1 :         ptr->cleanApertureWidthN = gf_bs_read_u32(bs);
    8245           1 :         ptr->cleanApertureWidthD = gf_bs_read_u32(bs);
    8246           1 :         ptr->cleanApertureHeightN = gf_bs_read_u32(bs);
    8247           1 :         ptr->cleanApertureHeightD = gf_bs_read_u32(bs);
    8248           1 :         ptr->horizOffN = gf_bs_read_u32(bs);
    8249           1 :         ptr->horizOffD = gf_bs_read_u32(bs);
    8250           1 :         ptr->vertOffN = gf_bs_read_u32(bs);
    8251           1 :         ptr->vertOffD = gf_bs_read_u32(bs);
    8252           1 :         return GF_OK;
    8253             : }
    8254             : 
    8255             : 
    8256             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8257             : 
    8258          12 : GF_Err clap_box_write(GF_Box *s, GF_BitStream *bs)
    8259             : {
    8260             :         GF_CleanApertureBox *ptr = (GF_CleanApertureBox *)s;
    8261          12 :         GF_Err e = gf_isom_box_write_header(s, bs);
    8262          12 :         if (e) return e;
    8263          12 :         gf_bs_write_u32(bs, ptr->cleanApertureWidthN);
    8264          12 :         gf_bs_write_u32(bs, ptr->cleanApertureWidthD);
    8265          12 :         gf_bs_write_u32(bs, ptr->cleanApertureHeightN);
    8266          12 :         gf_bs_write_u32(bs, ptr->cleanApertureHeightD);
    8267          12 :         gf_bs_write_u32(bs, ptr->horizOffN);
    8268          12 :         gf_bs_write_u32(bs, ptr->horizOffD);
    8269          12 :         gf_bs_write_u32(bs, ptr->vertOffN);
    8270          12 :         gf_bs_write_u32(bs, ptr->vertOffD);
    8271          12 :         return GF_OK;
    8272             : }
    8273             : 
    8274          34 : GF_Err clap_box_size(GF_Box *s)
    8275             : {
    8276          34 :         s->size += 32;
    8277          34 :         return GF_OK;
    8278             : }
    8279             : 
    8280             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8281             : 
    8282             : 
    8283             : 
    8284             : 
    8285         137 : GF_Box *metx_box_new()
    8286             : {
    8287             :         //type is overridden by the box constructor
    8288         274 :         ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, GF_ISOM_BOX_TYPE_METX);
    8289         137 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    8290         137 :         return (GF_Box *)tmp;
    8291             : }
    8292             : 
    8293             : 
    8294         137 : void metx_box_del(GF_Box *s)
    8295             : {
    8296             :         GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
    8297         137 :         if (ptr == NULL) return;
    8298         137 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    8299             : 
    8300         137 :         if (ptr->content_encoding) gf_free(ptr->content_encoding);
    8301         137 :         if (ptr->xml_namespace) gf_free(ptr->xml_namespace);
    8302         137 :         if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
    8303         137 :         if (ptr->mime_type) gf_free(ptr->mime_type);
    8304         137 :         gf_free(ptr);
    8305             : }
    8306             : 
    8307             : 
    8308          71 : GF_Err metx_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    8309             : {
    8310             :         GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
    8311          71 :         switch (a->type) {
    8312           8 :         case GF_ISOM_BOX_TYPE_TXTC:
    8313             :                 //we allow the config box on metx
    8314           8 :                 BOX_FIELD_ASSIGN(config, GF_TextConfigBox)
    8315           8 :                 break;
    8316             :         }
    8317             :         return GF_OK;
    8318             : }
    8319             : 
    8320          80 : GF_Err metx_box_read(GF_Box *s, GF_BitStream *bs)
    8321             : {
    8322             :         u32 size, i;
    8323             :         GF_Err e;
    8324             :         char *str;
    8325             :         GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
    8326             : 
    8327          80 :         e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
    8328          80 :         if (e) return e;
    8329          80 :         ISOM_DECREASE_SIZE(ptr, 8);
    8330             : 
    8331          80 :         size = (u32) ptr->size;
    8332          80 :         str = gf_malloc(sizeof(char)*size);
    8333          80 :         if (!str) return GF_OUT_OF_MEM;
    8334             : 
    8335             :         i=0;
    8336             : 
    8337        1091 :         while (size) {
    8338        1091 :                 str[i] = gf_bs_read_u8(bs);
    8339        1091 :                 size--;
    8340        1091 :                 if (!str[i]) {
    8341          80 :                         i++;
    8342          80 :                         break;
    8343             :                 }
    8344        1011 :                 i++;
    8345             :         }
    8346          80 :         if (!size && i>1 && str[i-1]) {
    8347           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
    8348           0 :                 gf_free(str);
    8349           0 :                 return GF_ISOM_INVALID_FILE;
    8350             :         }
    8351          80 :         if (i>1) {
    8352          55 :                 if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
    8353          35 :                         ptr->xml_namespace = gf_strdup(str);
    8354             :                 } else {
    8355          20 :                         ptr->content_encoding = gf_strdup(str);
    8356             :                 }
    8357             :         }
    8358             : 
    8359             :         i=0;
    8360         672 :         while (size) {
    8361         672 :                 str[i] = gf_bs_read_u8(bs);
    8362         672 :                 size--;
    8363         672 :                 if (!str[i]) {
    8364          80 :                         i++;
    8365          80 :                         break;
    8366             :                 }
    8367         592 :                 i++;
    8368             :         }
    8369          80 :         if (!size && i>1 && str[i-1]) {
    8370           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
    8371           0 :                 gf_free(str);
    8372           0 :                 return GF_ISOM_INVALID_FILE;
    8373             :         }
    8374          80 :         if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
    8375          41 :                 if (i>1) {
    8376           8 :                         if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
    8377           4 :                                 ptr->xml_schema_loc = gf_strdup(str);
    8378             :                         } else {
    8379           4 :                                 ptr->xml_namespace = gf_strdup(str);
    8380             :                         }
    8381             :                 }
    8382             : 
    8383             :                 i=0;
    8384         137 :                 while (size) {
    8385         137 :                         str[i] = gf_bs_read_u8(bs);
    8386         137 :                         size--;
    8387         137 :                         if (!str[i]) {
    8388          41 :                                 i++;
    8389          41 :                                 break;
    8390             :                         }
    8391          96 :                         i++;
    8392             :                 }
    8393          41 :                 if (!size && i>1 && str[i-1]) {
    8394           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
    8395           0 :                         gf_free(str);
    8396           0 :                         return GF_ISOM_INVALID_FILE;
    8397             :                 }
    8398          41 :                 if (i>1) {
    8399           4 :                         if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
    8400           0 :                                 ptr->mime_type = gf_strdup(str);
    8401             :                         } else {
    8402           4 :                                 ptr->xml_schema_loc = gf_strdup(str);
    8403             :                         }
    8404             :                 }
    8405             :         }
    8406             :         //mett, sbtt, stxt, stpp
    8407             :         else {
    8408          39 :                 if (i>1) ptr->mime_type = gf_strdup(str);
    8409             :         }
    8410          80 :         ptr->size = size;
    8411          80 :         gf_free(str);
    8412          80 :         return gf_isom_box_array_read(s, bs);
    8413             : }
    8414             : 
    8415             : 
    8416             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8417             : 
    8418         101 : GF_Err metx_box_write(GF_Box *s, GF_BitStream *bs)
    8419             : {
    8420             :         GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
    8421         101 :         GF_Err e = gf_isom_box_write_header(s, bs);
    8422         101 :         if (e) return e;
    8423             : 
    8424         101 :         gf_bs_write_data(bs, ptr->reserved, 6);
    8425         101 :         gf_bs_write_u16(bs, ptr->dataReferenceIndex);
    8426             : 
    8427         101 :         if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
    8428          61 :                 if (ptr->content_encoding)
    8429          25 :                         gf_bs_write_data(bs, ptr->content_encoding, (u32) strlen(ptr->content_encoding));
    8430          61 :                 gf_bs_write_u8(bs, 0);
    8431             :         }
    8432             : 
    8433         101 :         if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
    8434          46 :                 if (ptr->xml_namespace)
    8435          44 :                         gf_bs_write_data(bs, ptr->xml_namespace, (u32) strlen(ptr->xml_namespace));
    8436             : 
    8437          46 :                 gf_bs_write_u8(bs, 0);
    8438             : 
    8439          46 :                 if (ptr->xml_schema_loc)
    8440          10 :                         gf_bs_write_data(bs, ptr->xml_schema_loc, (u32) strlen(ptr->xml_schema_loc));
    8441          46 :                 gf_bs_write_u8(bs, 0);
    8442             : 
    8443          46 :                 if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
    8444          40 :                         if (ptr->mime_type)
    8445           1 :                                 gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
    8446             : 
    8447          40 :                         gf_bs_write_u8(bs, 0);
    8448             :                 }
    8449             :         }
    8450             :         //mett, sbtt, stxt
    8451             :         else {
    8452          55 :                 if (ptr->mime_type)
    8453          52 :                         gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
    8454             : 
    8455          55 :                 gf_bs_write_u8(bs, 0);
    8456             :         }
    8457             : 
    8458             :         return GF_OK;
    8459             : }
    8460             : 
    8461         202 : GF_Err metx_box_size(GF_Box *s)
    8462             : {
    8463             :         GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
    8464         202 :         ptr->size += 8;
    8465             : 
    8466         202 :         if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
    8467         116 :                 if (ptr->content_encoding)
    8468          45 :                         ptr->size += strlen(ptr->content_encoding);
    8469         116 :                 ptr->size++;
    8470             :         }
    8471             : 
    8472         202 :         if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
    8473             : 
    8474          96 :                 if (ptr->xml_namespace)
    8475          94 :                         ptr->size += strlen(ptr->xml_namespace);
    8476          96 :                 ptr->size++;
    8477             : 
    8478          96 :                 if (ptr->xml_schema_loc)
    8479          18 :                         ptr->size += strlen(ptr->xml_schema_loc);
    8480          96 :                 ptr->size++;
    8481             : 
    8482          96 :                 if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
    8483          86 :                         if (ptr->mime_type)
    8484           3 :                                 ptr->size += strlen(ptr->mime_type);
    8485          86 :                         ptr->size++;
    8486             :                 }
    8487             : 
    8488             :         }
    8489             :         //mett, sbtt, stxt
    8490             :         else {
    8491         106 :                 if (ptr->mime_type)
    8492         103 :                         ptr->size += strlen(ptr->mime_type);
    8493         106 :                 ptr->size++;
    8494             :         }
    8495         202 :         return GF_OK;
    8496             : }
    8497             : 
    8498             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8499             : 
    8500             : 
    8501             : /* SimpleTextSampleEntry */
    8502          24 : GF_Box *txtc_box_new()
    8503             : {
    8504          48 :         ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC);
    8505          24 :         return (GF_Box *)tmp;
    8506             : }
    8507             : 
    8508             : 
    8509          24 : void txtc_box_del(GF_Box *s)
    8510             : {
    8511             :         GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
    8512          24 :         if (ptr == NULL) return;
    8513             : 
    8514          24 :         if (ptr->config) gf_free(ptr->config);
    8515          24 :         gf_free(ptr);
    8516             : }
    8517             : 
    8518          10 : GF_Err txtc_box_read(GF_Box *s, GF_BitStream *bs)
    8519             : {
    8520             :         GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
    8521          10 :         ptr->config = (char *)gf_malloc(sizeof(char)*((u32) ptr->size+1));
    8522          10 :         if (!ptr->config) return GF_OUT_OF_MEM;
    8523          10 :         gf_bs_read_data(bs, ptr->config, (u32) ptr->size);
    8524          10 :         ptr->config[ptr->size] = 0;
    8525          10 :         return GF_OK;
    8526             : }
    8527             : 
    8528             : 
    8529             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8530             : 
    8531          18 : GF_Err txtc_box_write(GF_Box *s, GF_BitStream *bs)
    8532             : {
    8533             :         GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
    8534          18 :         GF_Err e = gf_isom_full_box_write(s, bs);
    8535          18 :         if (e) return e;
    8536             : 
    8537          18 :         if (ptr->config)
    8538          16 :                 gf_bs_write_data(bs, ptr->config, (u32) strlen(ptr->config));
    8539          18 :         gf_bs_write_u8(bs, 0);
    8540          18 :         return GF_OK;
    8541             : }
    8542             : 
    8543          39 : GF_Err txtc_box_size(GF_Box *s)
    8544             : {
    8545             :         GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
    8546          39 :         if (ptr->config)
    8547          37 :                 ptr->size += strlen(ptr->config);
    8548          39 :         ptr->size++;
    8549          39 :         return GF_OK;
    8550             : }
    8551             : 
    8552             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8553             : 
    8554          27 : GF_Box *dac3_box_new()
    8555             : {
    8556          54 :         ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
    8557          27 :         return (GF_Box *)tmp;
    8558             : }
    8559             : 
    8560          10 : GF_Box *dec3_box_new()
    8561             : {
    8562          20 :         ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
    8563          10 :         tmp->cfg.is_ec3 = 1;
    8564          10 :         return (GF_Box *)tmp;
    8565             : }
    8566             : 
    8567          37 : void dac3_box_del(GF_Box *s)
    8568             : {
    8569             :         GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
    8570          37 :         gf_free(ptr);
    8571          37 : }
    8572             : 
    8573             : 
    8574          22 : GF_Err dac3_box_read(GF_Box *s, GF_BitStream *bs)
    8575             : {
    8576             :         GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
    8577          22 :         if (ptr == NULL) return GF_BAD_PARAM;
    8578          22 :         return gf_odf_ac3_config_parse_bs(bs, ptr->cfg.is_ec3, &ptr->cfg);
    8579             : }
    8580             : 
    8581             : 
    8582             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8583             : 
    8584          23 : GF_Err dac3_box_write(GF_Box *s, GF_BitStream *bs)
    8585             : {
    8586             :         GF_Err e;
    8587             :         GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
    8588             : 
    8589          23 :         if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
    8590          23 :         e = gf_isom_box_write_header(s, bs);
    8591          23 :         if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
    8592          23 :         if (e) return e;
    8593             :         
    8594          23 :         return gf_odf_ac3_cfg_write_bs(&ptr->cfg, bs);
    8595             : }
    8596             : 
    8597          45 : GF_Err dac3_box_size(GF_Box *s)
    8598             : {
    8599             :         GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
    8600             : 
    8601          45 :         if (ptr->cfg.is_ec3) {
    8602             :                 u32 i;
    8603           9 :                 s->size += 2;
    8604          17 :                 for (i=0; i<ptr->cfg.nb_streams; i++) {
    8605           8 :                         s->size += 3;
    8606           8 :                         if (ptr->cfg.streams[i].nb_dep_sub)
    8607           0 :                                 s->size += 1;
    8608             :                 }
    8609             :         } else {
    8610          36 :                 s->size += 3;
    8611             :         }
    8612          45 :         return GF_OK;
    8613             : }
    8614             : 
    8615             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8616             : 
    8617             : 
    8618             : 
    8619           9 : void lsrc_box_del(GF_Box *s)
    8620             : {
    8621             :         GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
    8622           9 :         if (ptr == NULL) return;
    8623           9 :         if (ptr->hdr) gf_free(ptr->hdr);
    8624           9 :         gf_free(ptr);
    8625             : }
    8626             : 
    8627             : 
    8628           4 : GF_Err lsrc_box_read(GF_Box *s, GF_BitStream *bs)
    8629             : {
    8630             :         GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
    8631           4 :         ptr->hdr_size = (u32) ptr->size;
    8632           4 :         ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size);
    8633           4 :         if (!ptr->hdr) return GF_OUT_OF_MEM;
    8634           4 :         gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size);
    8635           4 :         return GF_OK;
    8636             : }
    8637             : 
    8638           9 : GF_Box *lsrc_box_new()
    8639             : {
    8640          18 :         ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
    8641           9 :         return (GF_Box *)tmp;
    8642             : }
    8643             : 
    8644             : 
    8645             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8646             : 
    8647           3 : GF_Err lsrc_box_write(GF_Box *s, GF_BitStream *bs)
    8648             : {
    8649             :         GF_Err e;
    8650             :         GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
    8651           3 :         e = gf_isom_box_write_header(s, bs);
    8652           3 :         if (e) return e;
    8653           3 :         gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size);
    8654           3 :         return GF_OK;
    8655             : }
    8656             : 
    8657           5 : GF_Err lsrc_box_size(GF_Box *s)
    8658             : {
    8659             :         GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
    8660           5 :         ptr->size += ptr->hdr_size;
    8661           5 :         return GF_OK;
    8662             : }
    8663             : 
    8664             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8665             : 
    8666             : 
    8667           9 : void lsr1_box_del(GF_Box *s)
    8668             : {
    8669             :         GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
    8670           9 :         if (ptr == NULL) return;
    8671           9 :         gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
    8672           9 :         if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
    8673           9 :         gf_free(ptr);
    8674             : }
    8675             : 
    8676           6 : GF_Err lsr1_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
    8677             : {
    8678             :         GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
    8679           6 :         switch (a->type) {
    8680           3 :         case GF_ISOM_BOX_TYPE_LSRC:
    8681           3 :                 BOX_FIELD_ASSIGN(lsr_config, GF_LASERConfigurationBox)
    8682           3 :                 break;
    8683           0 :         case GF_ISOM_BOX_TYPE_M4DS:
    8684           0 :                 BOX_FIELD_ASSIGN(descr, GF_MPEG4ExtensionDescriptorsBox)
    8685           0 :                 break;
    8686             :         }
    8687             :         return GF_OK;
    8688             : }
    8689             : 
    8690           4 : GF_Err lsr1_box_read(GF_Box *s, GF_BitStream *bs)
    8691             : {
    8692             :         GF_Err e;
    8693             :         GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s;
    8694             : 
    8695           4 :         e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
    8696           4 :         if (e) return e;
    8697             : 
    8698           4 :         ISOM_DECREASE_SIZE(ptr, 8);
    8699             : 
    8700           4 :         return gf_isom_box_array_read(s, bs);
    8701             : }
    8702             : 
    8703           9 : GF_Box *lsr1_box_new()
    8704             : {
    8705          18 :         ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
    8706           9 :         gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
    8707           9 :         return (GF_Box *)tmp;
    8708             : }
    8709             : 
    8710             : 
    8711             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8712             : 
    8713             : 
    8714           3 : GF_Err lsr1_box_write(GF_Box *s, GF_BitStream *bs)
    8715             : {
    8716             :         GF_Err e;
    8717             :         GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
    8718           3 :         e = gf_isom_box_write_header(s, bs);
    8719           3 :         if (e) return e;
    8720             : 
    8721           3 :         gf_bs_write_data(bs, ptr->reserved, 6);
    8722           3 :         gf_bs_write_u16(bs, ptr->dataReferenceIndex);
    8723           3 :         return GF_OK;
    8724             : }
    8725             : 
    8726           5 : GF_Err lsr1_box_size(GF_Box *s)
    8727             : {
    8728           5 :         u32 pos=0;
    8729             :         GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
    8730           5 :         s->size += 8;
    8731           5 :         gf_isom_check_position(s, (GF_Box *)ptr->lsr_config, &pos);
    8732           5 :         return GF_OK;
    8733             : }
    8734             : 
    8735             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8736             : 
    8737             : 
    8738        4557 : void sidx_box_del(GF_Box *s)
    8739             : {
    8740             :         GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s;
    8741        4557 :         if (ptr == NULL) return;
    8742        4557 :         if (ptr->refs) gf_free(ptr->refs);
    8743        4557 :         gf_free(ptr);
    8744             : }
    8745             : 
    8746        2462 : GF_Err sidx_box_read(GF_Box *s,GF_BitStream *bs)
    8747             : {
    8748             :         u32 i;
    8749             :         GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
    8750             : 
    8751        2462 :         ISOM_DECREASE_SIZE(ptr, 8);
    8752        2462 :         ptr->reference_ID = gf_bs_read_u32(bs);
    8753        2462 :         ptr->timescale = gf_bs_read_u32(bs);
    8754             : 
    8755        2462 :         if (ptr->version==0) {
    8756        2462 :                 ISOM_DECREASE_SIZE(ptr, 8);
    8757        2462 :                 ptr->earliest_presentation_time = gf_bs_read_u32(bs);
    8758        2462 :                 ptr->first_offset = gf_bs_read_u32(bs);
    8759             :         } else {
    8760           0 :                 ISOM_DECREASE_SIZE(ptr, 16);
    8761           0 :                 ptr->earliest_presentation_time = gf_bs_read_u64(bs);
    8762           0 :                 ptr->first_offset = gf_bs_read_u64(bs);
    8763             :         }
    8764        2462 :         ISOM_DECREASE_SIZE(ptr, 4);
    8765        2462 :         gf_bs_read_u16(bs); /* reserved */
    8766        2462 :         ptr->nb_refs = gf_bs_read_u16(bs);
    8767             : 
    8768        2462 :         ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs);
    8769        2462 :         if (!ptr->refs) return GF_OUT_OF_MEM;
    8770        3340 :         for (i=0; i<ptr->nb_refs; i++) {
    8771        3340 :                 ptr->refs[i].reference_type = gf_bs_read_int(bs, 1);
    8772        3340 :                 ptr->refs[i].reference_size = gf_bs_read_int(bs, 31);
    8773        3340 :                 ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs);
    8774        3340 :                 ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1);
    8775        3340 :                 ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3);
    8776        3340 :                 ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28);
    8777             : 
    8778        3340 :                 ISOM_DECREASE_SIZE(ptr, 12);
    8779             :         }
    8780             :         return GF_OK;
    8781             : }
    8782             : 
    8783        4557 : GF_Box *sidx_box_new()
    8784             : {
    8785        9114 :         ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
    8786        4557 :         return (GF_Box *)tmp;
    8787             : }
    8788             : 
    8789             : 
    8790             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8791             : 
    8792        4253 : GF_Err sidx_box_write(GF_Box *s, GF_BitStream *bs)
    8793             : {
    8794             :         GF_Err e;
    8795             :         u32 i;
    8796             :         GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
    8797             : 
    8798        4253 :         e = gf_isom_full_box_write(s, bs);
    8799        4253 :         if (e) return e;
    8800             : 
    8801        4253 :         gf_bs_write_u32(bs, ptr->reference_ID);
    8802        4253 :         gf_bs_write_u32(bs, ptr->timescale);
    8803        4253 :         if (ptr->version==0) {
    8804        4253 :                 gf_bs_write_u32(bs, (u32) ptr->earliest_presentation_time);
    8805        4253 :                 gf_bs_write_u32(bs, (u32) ptr->first_offset);
    8806             :         } else {
    8807           0 :                 gf_bs_write_u64(bs, ptr->earliest_presentation_time);
    8808           0 :                 gf_bs_write_u64(bs, ptr->first_offset);
    8809             :         }
    8810        4253 :         gf_bs_write_u16(bs, 0);
    8811        4253 :         gf_bs_write_u16(bs, ptr->nb_refs);
    8812        9056 :         for (i=0; i<ptr->nb_refs; i++ ) {
    8813        4803 :                 gf_bs_write_int(bs, ptr->refs[i].reference_type, 1);
    8814        4803 :                 gf_bs_write_int(bs, ptr->refs[i].reference_size, 31);
    8815        4803 :                 gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration);
    8816        4803 :                 gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1);
    8817        4803 :                 gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3);
    8818        4803 :                 gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28);
    8819             :         }
    8820             :         return GF_OK;
    8821             : }
    8822             : 
    8823        2179 : GF_Err sidx_box_size(GF_Box *s)
    8824             : {
    8825             :         GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
    8826             : 
    8827        2179 :         ptr->size += 12;
    8828        2179 :         if (ptr->version==0) {
    8829        2179 :                 ptr->size += 8;
    8830             :         } else {
    8831           0 :                 ptr->size += 16;
    8832             :         }
    8833        2179 :         ptr->size += ptr->nb_refs * 12;
    8834        2179 :         return GF_OK;
    8835             : }
    8836             : 
    8837             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8838             : 
    8839           4 : void ssix_box_del(GF_Box *s)
    8840             : {
    8841             :         u32 i;
    8842             :         GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s;
    8843           4 :         if (ptr == NULL) return;
    8844           4 :         if (ptr->subsegments) {
    8845          30 :                 for (i = 0; i < ptr->subsegment_alloc; i++) {
    8846          30 :                         GF_SubsegmentInfo *subsegment = &ptr->subsegments[i];
    8847          30 :                         if (subsegment->ranges) gf_free(subsegment->ranges);
    8848             :                 }
    8849           2 :                 gf_free(ptr->subsegments);
    8850             :         }
    8851           4 :         gf_free(ptr);
    8852             : }
    8853             : 
    8854           1 : GF_Err ssix_box_read(GF_Box *s, GF_BitStream *bs)
    8855             : {
    8856             :         u32 i,j;
    8857             :         GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
    8858             : 
    8859           1 :         ISOM_DECREASE_SIZE(ptr, 4)
    8860           1 :         ptr->subsegment_count = gf_bs_read_u32(bs);
    8861             :         //each subseg has at least one range_count (4 bytes), abort if not enough bytes (broken box)
    8862           1 :         if (ptr->size / 4 < ptr->subsegment_count)
    8863             :                 return GF_ISOM_INVALID_FILE;
    8864             : 
    8865           1 :         ptr->subsegment_alloc = ptr->subsegment_count;
    8866           1 :         GF_SAFE_ALLOC_N(ptr->subsegments, ptr->subsegment_count, GF_SubsegmentInfo);
    8867           1 :         if (!ptr->subsegments)
    8868             :             return GF_OUT_OF_MEM;
    8869           0 :         for (i = 0; i < ptr->subsegment_count; i++) {
    8870           0 :                 GF_SubsegmentInfo *subseg = &ptr->subsegments[i];
    8871           0 :                 ISOM_DECREASE_SIZE(ptr, 4)
    8872           0 :                 subseg->range_count = gf_bs_read_u32(bs);
    8873             :                 //each range is 4 bytes, abort if not enough bytes
    8874           0 :                 if (ptr->size / 4 < subseg->range_count)
    8875             :                         return GF_ISOM_INVALID_FILE;
    8876           0 :                 subseg->ranges = (GF_SubsegmentRangeInfo*) gf_malloc(sizeof(GF_SubsegmentRangeInfo) * subseg->range_count);
    8877           0 :                 if (!subseg->ranges) return GF_OUT_OF_MEM;
    8878           0 :                 for (j = 0; j < subseg->range_count; j++) {
    8879           0 :                         ISOM_DECREASE_SIZE(ptr, 4)
    8880           0 :                         subseg->ranges[j].level = gf_bs_read_u8(bs);
    8881           0 :                         subseg->ranges[j].range_size = gf_bs_read_u24(bs);
    8882             :                 }
    8883             :         }
    8884             :         return GF_OK;
    8885             : }
    8886             : 
    8887           4 : GF_Box *ssix_box_new()
    8888             : {
    8889           8 :         ISOM_DECL_BOX_ALLOC(GF_SubsegmentIndexBox, GF_ISOM_BOX_TYPE_SSIX);
    8890           4 :         return (GF_Box *)tmp;
    8891             : }
    8892             : 
    8893             : 
    8894             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8895             : 
    8896           2 : GF_Err ssix_box_write(GF_Box *s, GF_BitStream *bs)
    8897             : {
    8898             :         GF_Err e;
    8899             :         u32 i, j;
    8900             :         GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
    8901             : 
    8902           2 :         e = gf_isom_full_box_write(s, bs);
    8903           2 :         if (e) return e;
    8904             : 
    8905           2 :         gf_bs_write_u32(bs, ptr->subsegment_count);
    8906          32 :         for (i = 0; i<ptr->subsegment_count; i++) {
    8907          30 :                 gf_bs_write_u32(bs, ptr->subsegments[i].range_count);
    8908          90 :                 for (j = 0; j < ptr->subsegments[i].range_count; j++) {
    8909          60 :                         gf_bs_write_u8(bs, ptr->subsegments[i].ranges[j].level);
    8910          60 :                         gf_bs_write_u24(bs, ptr->subsegments[i].ranges[j].range_size);
    8911             :                 }
    8912             :         }
    8913             :         return GF_OK;
    8914             : }
    8915             : 
    8916           3 : GF_Err ssix_box_size(GF_Box *s)
    8917             : {
    8918             :         u32 i;
    8919             :         GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
    8920             : 
    8921           3 :         ptr->size += 4;
    8922          63 :         for (i = 0; i < ptr->subsegment_count; i++) {
    8923          60 :                 ptr->size += 4 + 4 * ptr->subsegments[i].range_count;
    8924             :         }
    8925           3 :         return GF_OK;
    8926             : }
    8927             : 
    8928             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    8929             : 
    8930           3 : void leva_box_del(GF_Box *s)
    8931             : {
    8932             :         GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox *)s;
    8933           3 :         if (ptr == NULL) return;
    8934           3 :         if (ptr->levels) gf_free(ptr->levels);
    8935           3 :         gf_free(ptr);
    8936             : }
    8937             : 
    8938           1 : GF_Err leva_box_read(GF_Box *s, GF_BitStream *bs)
    8939             : {
    8940             :         u32 i;
    8941             :         GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
    8942             : 
    8943           1 :         ISOM_DECREASE_SIZE(ptr, 1)
    8944           1 :         ptr->level_count = gf_bs_read_u8(bs);
    8945             :         //each level is at least 5 bytes
    8946           1 :         if (ptr->size / 5 < ptr->level_count)
    8947             :                 return GF_ISOM_INVALID_FILE;
    8948             : 
    8949           1 :         GF_SAFE_ALLOC_N(ptr->levels, ptr->level_count, GF_LevelAssignment);
    8950           1 :         if (!ptr->levels) return GF_OUT_OF_MEM;
    8951             : 
    8952           0 :         for (i = 0; i < ptr->level_count; i++) {
    8953           0 :                 GF_LevelAssignment *level = &ptr->levels[i];
    8954             :                 u8 tmp;
    8955           0 :                 if (!level || ptr->size < 5) return GF_BAD_PARAM;
    8956           0 :                 ISOM_DECREASE_SIZE(ptr, 5)
    8957             : 
    8958           0 :                 level->track_id = gf_bs_read_u32(bs);
    8959           0 :                 tmp = gf_bs_read_u8(bs);
    8960           0 :                 level->padding_flag = tmp >> 7;
    8961           0 :                 level->type = tmp & 0x7F;
    8962           0 :                 if (level->type == 0) {
    8963           0 :                         ISOM_DECREASE_SIZE(ptr, 4)
    8964           0 :                         level->grouping_type = gf_bs_read_u32(bs);
    8965             :                 }
    8966           0 :                 else if (level->type == 1) {
    8967           0 :                         ISOM_DECREASE_SIZE(ptr, 8)
    8968           0 :                         level->grouping_type = gf_bs_read_u32(bs);
    8969           0 :                         level->grouping_type_parameter = gf_bs_read_u32(bs);
    8970             :                 }
    8971           0 :                 else if (level->type == 4) {
    8972           0 :                         ISOM_DECREASE_SIZE(ptr, 4)
    8973           0 :                         level->sub_track_id = gf_bs_read_u32(bs);
    8974             :                 }
    8975             :         }
    8976             :         return GF_OK;
    8977             : }
    8978             : 
    8979           3 : GF_Box *leva_box_new()
    8980             : {
    8981           6 :         ISOM_DECL_BOX_ALLOC(GF_LevelAssignmentBox, GF_ISOM_BOX_TYPE_LEVA);
    8982           3 :         return (GF_Box *)tmp;
    8983             : }
    8984             : 
    8985             : 
    8986             : #ifndef GPAC_DISABLE_ISOM_WRITE
    8987             : 
    8988           1 : GF_Err leva_box_write(GF_Box *s, GF_BitStream *bs)
    8989             : {
    8990             :         GF_Err e;
    8991             :         u32 i;
    8992             :         GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
    8993             : 
    8994           1 :         e = gf_isom_full_box_write(s, bs);
    8995           1 :         if (e) return e;
    8996             : 
    8997           1 :         gf_bs_write_u8(bs, ptr->level_count);
    8998           1 :         for (i = 0; i<ptr->level_count; i++) {
    8999           0 :                 gf_bs_write_u32(bs, ptr->levels[i].track_id);
    9000           0 :                 gf_bs_write_u8(bs, ptr->levels[i].padding_flag << 7 | (ptr->levels[i].type & 0x7F));
    9001           0 :                 if (ptr->levels[i].type == 0) {
    9002           0 :                         gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
    9003             :                 }
    9004           0 :                 else if (ptr->levels[i].type == 1) {
    9005           0 :                         gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
    9006           0 :                         gf_bs_write_u32(bs, ptr->levels[i].grouping_type_parameter);
    9007             :                 }
    9008           0 :                 else if (ptr->levels[i].type == 4) {
    9009           0 :                         gf_bs_write_u32(bs, ptr->levels[i].sub_track_id);
    9010             :                 }
    9011             :         }
    9012             :         return GF_OK;
    9013             : }
    9014             : 
    9015           1 : GF_Err leva_box_size(GF_Box *s)
    9016             : {
    9017             :         u32 i;
    9018             :         GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
    9019             : 
    9020           1 :         ptr->size += 1;
    9021           1 :         for (i = 0; i < ptr->level_count; i++) {
    9022           0 :                 ptr->size += 5;
    9023           0 :                 if (ptr->levels[i].type == 0 || ptr->levels[i].type == 4) {
    9024           0 :                         ptr->size += 4;
    9025             :                 }
    9026           0 :                 else if (ptr->levels[i].type == 1) {
    9027           0 :                         ptr->size += 8;
    9028             :                 }
    9029             :         }
    9030           1 :         return GF_OK;
    9031             : }
    9032             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9033             : 
    9034           3 : GF_Box *pcrb_box_new()
    9035             : {
    9036           6 :         ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
    9037           3 :         return (GF_Box *)tmp;
    9038             : }
    9039             : 
    9040           3 : void pcrb_box_del(GF_Box *s)
    9041             : {
    9042             :         GF_PcrInfoBox *ptr = (GF_PcrInfoBox *) s;
    9043           3 :         if (ptr == NULL) return;
    9044           3 :         if (ptr->pcr_values) gf_free(ptr->pcr_values);
    9045           3 :         gf_free(ptr);
    9046             : }
    9047             : 
    9048           1 : GF_Err pcrb_box_read(GF_Box *s,GF_BitStream *bs)
    9049             : {
    9050             :         u32 i;
    9051             :         GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
    9052             : 
    9053           1 :         ISOM_DECREASE_SIZE(ptr, 4);
    9054           1 :         ptr->subsegment_count = gf_bs_read_u32(bs);
    9055             : 
    9056           1 :         ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count);
    9057           1 :         if (!ptr->pcr_values) return GF_OUT_OF_MEM;
    9058           0 :         for (i=0; i<ptr->subsegment_count; i++) {
    9059           0 :                 u64 data1 = gf_bs_read_u32(bs);
    9060           0 :                 u64 data2 = gf_bs_read_u16(bs);
    9061           0 :                 ISOM_DECREASE_SIZE(ptr, 6);
    9062           0 :                 ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6);
    9063             : 
    9064             :         }
    9065             :         return GF_OK;
    9066             : }
    9067             : 
    9068             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9069             : 
    9070           1 : GF_Err pcrb_box_write(GF_Box *s, GF_BitStream *bs)
    9071             : {
    9072             :         GF_Err e;
    9073             :         u32 i;
    9074             :         GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
    9075             : 
    9076           1 :         e = gf_isom_box_write_header(s, bs);
    9077           1 :         if (e) return e;
    9078             : 
    9079           1 :         gf_bs_write_u32(bs, ptr->subsegment_count);
    9080             : 
    9081           1 :         for (i=0; i<ptr->subsegment_count; i++ ) {
    9082           0 :                 u32 data1 = (u32) (ptr->pcr_values[i] >> 10);
    9083           0 :                 u16 data2 = (u16) (ptr->pcr_values[i] << 6);
    9084             : 
    9085           0 :                 gf_bs_write_u32(bs, data1);
    9086           0 :                 gf_bs_write_u16(bs, data2);
    9087             :         }
    9088             :         return GF_OK;
    9089             : }
    9090             : 
    9091           1 : GF_Err pcrb_box_size(GF_Box *s)
    9092             : {
    9093             :         GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
    9094             : 
    9095           1 :         ptr->size += 4;
    9096           1 :         ptr->size += ptr->subsegment_count * 6;
    9097             : 
    9098           1 :         return GF_OK;
    9099             : }
    9100             : 
    9101             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9102             : 
    9103             : 
    9104          25 : GF_Box *subs_box_new()
    9105             : {
    9106          50 :         ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
    9107          25 :         tmp->Samples = gf_list_new();
    9108          25 :         return (GF_Box *)tmp;
    9109             : }
    9110             : 
    9111          25 : void subs_box_del(GF_Box *s)
    9112             : {
    9113             :         GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
    9114          25 :         if (ptr == NULL) return;
    9115             : 
    9116        2325 :         while (gf_list_count(ptr->Samples)) {
    9117             :                 GF_SubSampleInfoEntry *pSamp;
    9118        2300 :                 pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
    9119        9203 :                 while (gf_list_count(pSamp->SubSamples)) {
    9120             :                         GF_SubSampleEntry *pSubSamp;
    9121        4603 :                         pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0);
    9122        4603 :                         gf_free(pSubSamp);
    9123        4603 :                         gf_list_rem(pSamp->SubSamples, 0);
    9124             :                 }
    9125        2300 :                 gf_list_del(pSamp->SubSamples);
    9126        2300 :                 gf_free(pSamp);
    9127        2300 :                 gf_list_rem(ptr->Samples, 0);
    9128             :         }
    9129          25 :         gf_list_del(ptr->Samples);
    9130          25 :         gf_free(ptr);
    9131             : }
    9132             : 
    9133             : 
    9134             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9135             : 
    9136          20 : GF_Err subs_box_write(GF_Box *s, GF_BitStream *bs)
    9137             : {
    9138             :         GF_Err e;
    9139             :         u32 i, j, entry_count;
    9140             :         u16 subsample_count;
    9141             :         GF_SubSampleEntry *pSubSamp;
    9142             :         GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
    9143             : 
    9144          20 :         if (!s) return GF_BAD_PARAM;
    9145          20 :         e = gf_isom_full_box_write(s, bs);
    9146          20 :         if (e) return e;
    9147          20 :         entry_count = gf_list_count(ptr->Samples);
    9148          20 :         gf_bs_write_u32(bs, entry_count);
    9149             : 
    9150        1552 :         for (i=0; i<entry_count; i++) {
    9151        1532 :                 GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
    9152        1532 :                 subsample_count = gf_list_count(pSamp->SubSamples);
    9153        1532 :                 gf_bs_write_u32(bs, pSamp->sample_delta);
    9154        1532 :                 gf_bs_write_u16(bs, subsample_count);
    9155             : 
    9156        4598 :                 for (j=0; j<subsample_count; j++) {
    9157        3066 :                         pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, j);
    9158        3066 :                         if (ptr->version == 1) {
    9159        2355 :                                 gf_bs_write_u32(bs, pSubSamp->subsample_size);
    9160             :                         } else {
    9161         711 :                                 gf_bs_write_u16(bs, pSubSamp->subsample_size);
    9162             :                         }
    9163        3066 :                         gf_bs_write_u8(bs, pSubSamp->subsample_priority);
    9164        3066 :                         gf_bs_write_u8(bs, pSubSamp->discardable);
    9165        3066 :                         gf_bs_write_u32(bs, pSubSamp->reserved);
    9166             :                 }
    9167             :         }
    9168             :         return e;
    9169             : }
    9170             : 
    9171          58 : GF_Err subs_box_size(GF_Box *s)
    9172             : {
    9173             :         GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
    9174             :         u32 entry_count, i;
    9175             :         u16 subsample_count;
    9176             : 
    9177             :         // add 4 byte for entry_count
    9178          58 :         ptr->size += 4;
    9179          58 :         entry_count = gf_list_count(ptr->Samples);
    9180        4654 :         for (i=0; i<entry_count; i++) {
    9181        4596 :                 GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
    9182        4596 :                 subsample_count = gf_list_count(pSamp->SubSamples);
    9183             :                 // 4 byte for sample_delta, 2 byte for subsample_count
    9184             :                 // and 6 + (4 or 2) bytes for each subsample
    9185        4596 :                 ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version==1 ? 4 : 2));
    9186             :         }
    9187          58 :         return GF_OK;
    9188             : }
    9189             : 
    9190             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9191             : 
    9192           4 : GF_Err subs_box_read(GF_Box *s, GF_BitStream *bs)
    9193             : {
    9194             :         GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
    9195             :         u32 entry_count, i, j;
    9196             :         u16 subsample_count;
    9197             : 
    9198           4 :         ISOM_DECREASE_SIZE(ptr, 4);
    9199           4 :         entry_count = gf_bs_read_u32(bs);
    9200             : 
    9201         772 :         for (i=0; i<entry_count; i++) {
    9202             :                 u32 subs_size=0;
    9203         768 :                 GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_malloc(sizeof(GF_SubSampleInfoEntry));
    9204         768 :                 if (!pSamp) return GF_OUT_OF_MEM;
    9205             : 
    9206             :                 memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
    9207         768 :                 pSamp->SubSamples = gf_list_new();
    9208         768 :                 pSamp->sample_delta = gf_bs_read_u32(bs);
    9209         768 :                 subsample_count = gf_bs_read_u16(bs);
    9210             :                 subs_size=6;
    9211             : 
    9212        2305 :                 for (j=0; j<subsample_count; j++) {
    9213        1537 :                         GF_SubSampleEntry *pSubSamp = (GF_SubSampleEntry*) gf_malloc(sizeof(GF_SubSampleEntry));
    9214        1537 :                         if (!pSubSamp) return GF_OUT_OF_MEM;
    9215             : 
    9216             :                         memset(pSubSamp, 0, sizeof(GF_SubSampleEntry));
    9217        1537 :                         if (ptr->version==1) {
    9218        1523 :                                 pSubSamp->subsample_size = gf_bs_read_u32(bs);
    9219        1523 :                                 subs_size+=4;
    9220             :                         } else {
    9221          14 :                                 pSubSamp->subsample_size = gf_bs_read_u16(bs);
    9222          14 :                                 subs_size+=2;
    9223             :                         }
    9224        1537 :                         pSubSamp->subsample_priority = gf_bs_read_u8(bs);
    9225        1537 :                         pSubSamp->discardable = gf_bs_read_u8(bs);
    9226        1537 :                         pSubSamp->reserved = gf_bs_read_u32(bs);
    9227        1537 :                         subs_size+=6;
    9228             : 
    9229        1537 :                         gf_list_add(pSamp->SubSamples, pSubSamp);
    9230             :                 }
    9231         768 :                 gf_list_add(ptr->Samples, pSamp);
    9232         768 :                 ISOM_DECREASE_SIZE(ptr, subs_size);
    9233             :         }
    9234             :         return GF_OK;
    9235             : }
    9236             : 
    9237             : 
    9238             : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
    9239             : 
    9240        7397 : GF_Box *tfdt_box_new()
    9241             : {
    9242       14794 :         ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
    9243        7397 :         return (GF_Box *)tmp;
    9244             : }
    9245             : 
    9246        7397 : void tfdt_box_del(GF_Box *s)
    9247             : {
    9248        7397 :         gf_free(s);
    9249        7397 : }
    9250             : 
    9251             : /*this is using chpl format according to some NeroRecode samples*/
    9252        4013 : GF_Err tfdt_box_read(GF_Box *s,GF_BitStream *bs)
    9253             : {
    9254             :         GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
    9255             : 
    9256        4013 :         if (ptr->version==1) {
    9257          25 :                 ISOM_DECREASE_SIZE(ptr, 8);
    9258          25 :                 ptr->baseMediaDecodeTime = gf_bs_read_u64(bs);
    9259             :         } else {
    9260        3988 :                 ISOM_DECREASE_SIZE(ptr, 4);
    9261        3988 :                 ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs);
    9262             :         }
    9263             :         return GF_OK;
    9264             : }
    9265             : 
    9266             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9267             : 
    9268        3613 : GF_Err tfdt_box_write(GF_Box *s, GF_BitStream *bs)
    9269             : {
    9270             :         GF_Err e;
    9271             :         GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s;
    9272        3613 :         e = gf_isom_full_box_write(s, bs);
    9273        3613 :         if (e) return e;
    9274             : 
    9275        3613 :         if (ptr->version==1) {
    9276           0 :                 gf_bs_write_u64(bs, ptr->baseMediaDecodeTime);
    9277             :         } else {
    9278        3613 :                 gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime);
    9279             :         }
    9280             :         return GF_OK;
    9281             : }
    9282             : 
    9283       10491 : GF_Err tfdt_box_size(GF_Box *s)
    9284             : {
    9285             :         GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
    9286             : 
    9287       10491 :         if (!ptr->version && (ptr->baseMediaDecodeTime<=0xFFFFFFFF)) {
    9288             :                 //ptr->version = 0;
    9289       10491 :                 ptr->size += 4;
    9290             :         } else {
    9291           0 :                 ptr->version = 1;
    9292           0 :                 ptr->size += 8;
    9293             :         }
    9294       10491 :         return GF_OK;
    9295             : }
    9296             : 
    9297             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9298             : 
    9299             : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
    9300             : 
    9301             : 
    9302           5 : GF_Box *rvcc_box_new()
    9303             : {
    9304          10 :         ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
    9305           5 :         return (GF_Box *)tmp;
    9306             : }
    9307             : 
    9308           5 : void rvcc_box_del(GF_Box *s)
    9309             : {
    9310           5 :         gf_free(s);
    9311           5 : }
    9312             : 
    9313           2 : GF_Err rvcc_box_read(GF_Box *s,GF_BitStream *bs)
    9314             : {
    9315             :         GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
    9316           2 :         ISOM_DECREASE_SIZE(ptr, 2);
    9317           2 :         ptr->predefined_rvc_config = gf_bs_read_u16(bs);
    9318           2 :         if (!ptr->predefined_rvc_config) {
    9319           2 :                 ISOM_DECREASE_SIZE(ptr, 2);
    9320           2 :                 ptr->rvc_meta_idx = gf_bs_read_u16(bs);
    9321             :         }
    9322             :         return GF_OK;
    9323             : }
    9324             : 
    9325             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9326             : 
    9327           2 : GF_Err rvcc_box_write(GF_Box *s, GF_BitStream *bs)
    9328             : {
    9329             :         GF_Err e;
    9330             :         GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s;
    9331             : 
    9332           2 :         e = gf_isom_box_write_header(s, bs);
    9333           2 :         if (e) return e;
    9334             : 
    9335           2 :         gf_bs_write_u16(bs, ptr->predefined_rvc_config);
    9336           2 :         if (!ptr->predefined_rvc_config) {
    9337           2 :                 gf_bs_write_u16(bs, ptr->rvc_meta_idx);
    9338             :         }
    9339             :         return GF_OK;
    9340             : }
    9341             : 
    9342           4 : GF_Err rvcc_box_size(GF_Box *s)
    9343             : {
    9344             :         GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s;
    9345           4 :         ptr->size += 2;
    9346           4 :         if (! ptr->predefined_rvc_config) ptr->size += 2;
    9347           4 :         return GF_OK;
    9348             : }
    9349             : 
    9350             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9351             : 
    9352             : 
    9353             : 
    9354         554 : GF_Box *sbgp_box_new()
    9355             : {
    9356        1108 :         ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
    9357         554 :         return (GF_Box *)tmp;
    9358             : }
    9359         554 : void sbgp_box_del(GF_Box *a)
    9360             : {
    9361             :         GF_SampleGroupBox *p = (GF_SampleGroupBox *)a;
    9362         554 :         if (p->sample_entries) gf_free(p->sample_entries);
    9363         554 :         gf_free(p);
    9364         554 : }
    9365             : 
    9366         181 : GF_Err sbgp_box_read(GF_Box *s, GF_BitStream *bs)
    9367             : {
    9368             :         u32 i;
    9369             :         GF_SampleGroupBox *ptr = (GF_SampleGroupBox *)s;
    9370             : 
    9371         181 :         ISOM_DECREASE_SIZE(ptr, 8);
    9372         181 :         ptr->grouping_type = gf_bs_read_u32(bs);
    9373             : 
    9374         181 :         if (ptr->version==1) {
    9375           0 :                 ISOM_DECREASE_SIZE(ptr, 4);
    9376           0 :                 ptr->grouping_type_parameter = gf_bs_read_u32(bs);
    9377             :         }
    9378         181 :         ptr->entry_count = gf_bs_read_u32(bs);
    9379             : 
    9380         181 :         if (ptr->size < sizeof(GF_SampleGroupEntry)*ptr->entry_count)
    9381             :             return GF_ISOM_INVALID_FILE;
    9382             : 
    9383         181 :         ptr->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*ptr->entry_count);
    9384         181 :         if (!ptr->sample_entries) return GF_OUT_OF_MEM;
    9385             : 
    9386        2622 :         for (i=0; i<ptr->entry_count; i++) {
    9387        2622 :                 ISOM_DECREASE_SIZE(ptr, 8);
    9388        2622 :                 ptr->sample_entries[i].sample_count = gf_bs_read_u32(bs);
    9389        2622 :                 ptr->sample_entries[i].group_description_index = gf_bs_read_u32(bs);
    9390             :         }
    9391             :         return GF_OK;
    9392             : }
    9393             : 
    9394             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9395         273 : GF_Err sbgp_box_write(GF_Box *s, GF_BitStream *bs)
    9396             : {
    9397             :         u32 i;
    9398             :         GF_Err e;
    9399             :         GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
    9400             : 
    9401         273 :         e = gf_isom_full_box_write(s, bs);
    9402         273 :         if (e) return e;
    9403         273 :         gf_bs_write_u32(bs, p->grouping_type);
    9404         273 :         if (p->version==1)
    9405           1 :                 gf_bs_write_u32(bs, p->grouping_type_parameter);
    9406             : 
    9407         273 :         gf_bs_write_u32(bs, p->entry_count);
    9408        2979 :         for (i = 0; i<p->entry_count; i++ ) {
    9409        2706 :                 gf_bs_write_u32(bs, p->sample_entries[i].sample_count);
    9410        2706 :                 gf_bs_write_u32(bs, p->sample_entries[i].group_description_index);
    9411             :         }
    9412             :         return GF_OK;
    9413             : }
    9414             : 
    9415         817 : GF_Err sbgp_box_size(GF_Box *s)
    9416             : {
    9417             :         GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
    9418             : 
    9419         817 :         p->size += 8;
    9420         817 :         if (p->grouping_type_parameter) p->version=1;
    9421             : 
    9422         817 :         if (p->version==1) p->size += 4;
    9423         817 :         p->size += 8*p->entry_count;
    9424         817 :         return GF_OK;
    9425             : }
    9426             : 
    9427             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9428             : 
    9429         355 : static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, s32 bytes_in_box, u32 entry_size, u32 *total_bytes)
    9430             : {
    9431             :         Bool null_size_ok = GF_FALSE;
    9432             :         GF_DefaultSampleGroupDescriptionEntry *def_ptr;
    9433             : 
    9434         355 :         switch (grouping_type) {
    9435           2 :         case GF_ISOM_SAMPLE_GROUP_ROLL:
    9436             :         case GF_ISOM_SAMPLE_GROUP_PROL:
    9437             :         {
    9438             :                 GF_RollRecoveryEntry *ptr;
    9439           2 :                 GF_SAFEALLOC(ptr, GF_RollRecoveryEntry);
    9440           2 :                 if (!ptr) return NULL;
    9441           2 :                 ptr->roll_distance = gf_bs_read_int(bs, 16);
    9442           2 :                 *total_bytes = 2;
    9443           2 :                 return ptr;
    9444             :         }
    9445          54 :         case GF_ISOM_SAMPLE_GROUP_RAP:
    9446             :         {
    9447             :                 GF_VisualRandomAccessEntry *ptr;
    9448          54 :                 GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry);
    9449          54 :                 if (!ptr) return NULL;
    9450          54 :                 ptr->num_leading_samples_known = gf_bs_read_int(bs, 1);
    9451          54 :                 ptr->num_leading_samples = gf_bs_read_int(bs, 7);
    9452          54 :                 *total_bytes = 1;
    9453          54 :                 return ptr;
    9454             :         }
    9455           0 :         case GF_ISOM_SAMPLE_GROUP_SAP:
    9456             :         {
    9457             :                 GF_SAPEntry *ptr;
    9458           0 :                 GF_SAFEALLOC(ptr, GF_SAPEntry);
    9459           0 :                 if (!ptr) return NULL;
    9460           0 :                 ptr->dependent_flag = gf_bs_read_int(bs, 1);
    9461           0 :                 gf_bs_read_int(bs, 3);
    9462           0 :                 ptr->SAP_type = gf_bs_read_int(bs, 4);
    9463           0 :                 *total_bytes = 1;
    9464           0 :                 return ptr;
    9465             :         }
    9466           0 :         case GF_ISOM_SAMPLE_GROUP_SYNC:
    9467             :         {
    9468             :                 GF_SYNCEntry *ptr;
    9469           0 :                 GF_SAFEALLOC(ptr, GF_SYNCEntry);
    9470           0 :                 if (!ptr) return NULL;
    9471           0 :                 gf_bs_read_int(bs, 2);
    9472           0 :                 ptr->NALU_type = gf_bs_read_int(bs, 6);
    9473           0 :                 *total_bytes = 1;
    9474           0 :                 return ptr;
    9475             :         }
    9476           9 :         case GF_ISOM_SAMPLE_GROUP_TELE:
    9477             :         {
    9478             :                 GF_TemporalLevelEntry *ptr;
    9479           9 :                 GF_SAFEALLOC(ptr, GF_TemporalLevelEntry);
    9480           9 :                 if (!ptr) return NULL;
    9481           9 :                 ptr->level_independently_decodable = gf_bs_read_int(bs, 1);
    9482           9 :                 gf_bs_read_int(bs, 7);
    9483           9 :                 *total_bytes = 1;
    9484           9 :                 return ptr;
    9485             :         }
    9486         134 :         case GF_ISOM_SAMPLE_GROUP_SEIG:
    9487             :         {
    9488             :                 GF_CENCSampleEncryptionGroupEntry *ptr;
    9489         134 :                 if (bytes_in_box<3) return NULL;
    9490         134 :                 GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry);
    9491         134 :                 if (!ptr) return NULL;
    9492         134 :                 Bool use_mkey = gf_bs_read_int(bs, 1);
    9493         134 :                 gf_bs_read_int(bs, 7); //reserved
    9494         134 :                 ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
    9495         134 :                 ptr->skip_byte_block = gf_bs_read_int(bs, 4);
    9496         134 :                 ptr->IsProtected = gf_bs_read_u8(bs);
    9497             :                 bytes_in_box -= 3;
    9498         134 :                 if (use_mkey) {
    9499           9 :                         u64 pos = gf_bs_get_position(bs);
    9500           9 :                         u32 i, count = gf_bs_read_u16(bs);
    9501           9 :                         bytes_in_box -= 2;
    9502           9 :                         if (bytes_in_box<0) {
    9503           0 :                                 gf_free(ptr);
    9504           0 :                                 return NULL;
    9505             :                         }
    9506          18 :                         for (i=0; i<count; i++) {
    9507          18 :                                 u8 ivsize = gf_bs_read_u8(bs);
    9508          18 :                                 gf_bs_skip_bytes(bs, 16);
    9509          18 :                                 bytes_in_box -= 17;
    9510          18 :                                 if (!ivsize) {
    9511             :                                         //const IV
    9512           0 :                                         ivsize = gf_bs_read_u8(bs);
    9513           0 :                                         gf_bs_skip_bytes(bs, ivsize);
    9514           0 :                                         bytes_in_box -= 1 + ivsize;
    9515             :                                 }
    9516          18 :                                 if (bytes_in_box<0) {
    9517           0 :                                         gf_free(ptr);
    9518           0 :                                         return NULL;
    9519             :                                 }
    9520             :                         }
    9521           9 :                         ptr->key_info_size = 1 + (u32) (gf_bs_get_position(bs) - pos);
    9522           9 :                         ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
    9523           9 :                         if (!ptr->key_info) {
    9524           0 :                                 gf_free(ptr);
    9525           0 :                                 return NULL;
    9526             :                         }
    9527           9 :                         gf_bs_seek(bs, pos);
    9528           9 :                         ptr->key_info[0] = 1;
    9529           9 :                         gf_bs_read_data(bs, ptr->key_info + 1, ptr->key_info_size - 1);
    9530           9 :                         *total_bytes = 3 + ptr->key_info_size - 1;
    9531             : 
    9532           9 :                         if (!gf_cenc_validate_key_info(ptr->key_info, ptr->key_info_size)) {
    9533           0 :                                 gf_free(ptr->key_info);
    9534           0 :                                 gf_free(ptr);
    9535           0 :                                 return NULL;
    9536             :                         }
    9537             :                 } else {
    9538             :                         bin128 kid;
    9539             :                         u8 const_iv_size = 0;
    9540         125 :                         u8 iv_size = gf_bs_read_u8(bs);
    9541         125 :                         gf_bs_read_data(bs, kid, 16);
    9542             :                         bytes_in_box -= 17;
    9543         125 :                         if (bytes_in_box<0) {
    9544           0 :                                 gf_free(ptr);
    9545           0 :                                 return NULL;
    9546             :                         }
    9547             : 
    9548         125 :                         *total_bytes = 20;
    9549         125 :                         if ((ptr->IsProtected == 1) && !iv_size) {
    9550           0 :                                 const_iv_size = gf_bs_read_u8(bs);
    9551           0 :                                 if ((const_iv_size != 8) && (const_iv_size != 16)) {
    9552           0 :                                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group have invalid constant_IV size\n"));
    9553           0 :                                         gf_free(ptr);
    9554           0 :                                         return NULL;
    9555             :                                 }
    9556             :                         }
    9557         125 :                         ptr->key_info_size = 20;
    9558         125 :                         if (!iv_size && ptr->IsProtected) {
    9559           0 :                                 ptr->key_info_size += 1 + const_iv_size;
    9560             :                         }
    9561         125 :                         ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
    9562         125 :                         if (!ptr->key_info) {
    9563           0 :                                 gf_free(ptr);
    9564           0 :                                 return NULL;
    9565             :                         }
    9566         125 :                         ptr->key_info[0] = 0;
    9567         125 :                         ptr->key_info[1] = 0;
    9568         125 :                         ptr->key_info[2] = 0;
    9569         125 :                         ptr->key_info[3] = iv_size;
    9570         125 :                         memcpy(ptr->key_info+4, kid, 16);
    9571         125 :                         if (!iv_size && ptr->IsProtected) {
    9572           0 :                                 ptr->key_info[20] = const_iv_size;
    9573           0 :                                 gf_bs_read_data(bs, (char *)ptr->key_info+21, const_iv_size);
    9574           0 :                                 *total_bytes += 1 + const_iv_size;
    9575             :                         }
    9576             :                 }
    9577             : 
    9578         134 :                 if (!entry_size) {
    9579           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n"));
    9580             :                 }
    9581             :                 return ptr;
    9582             :         }
    9583          12 :         case GF_ISOM_SAMPLE_GROUP_OINF:
    9584             :         {
    9585          12 :                 GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry();
    9586          12 :                 u32 s = (u32) gf_bs_get_position(bs);
    9587          12 :                 gf_isom_oinf_read_entry(ptr, bs);
    9588          12 :                 *total_bytes = (u32) gf_bs_get_position(bs) - s;
    9589          12 :                 if (!entry_size) {
    9590           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n"));
    9591             :                 }
    9592             :                 return ptr;
    9593             :         }
    9594          18 :         case GF_ISOM_SAMPLE_GROUP_LINF:
    9595             :         {
    9596          18 :                 GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry();
    9597          18 :                 u32 s = (u32) gf_bs_get_position(bs);
    9598          18 :                 gf_isom_linf_read_entry(ptr, bs);
    9599          18 :                 *total_bytes = (u32) gf_bs_get_position(bs) - s;
    9600          18 :                 if (!entry_size) {
    9601           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n"));
    9602             :                 }
    9603             :                 return ptr;
    9604             :         }
    9605             : 
    9606         126 :         case GF_ISOM_SAMPLE_GROUP_TRIF:
    9607         126 :                 if (! entry_size) {
    9608           0 :                         u32 flags = gf_bs_peek_bits(bs, 24, 0);
    9609           0 :                         if (flags & 0x10000) entry_size=3;
    9610             :                         else {
    9611           0 :                                 if (flags & 0x80000) entry_size=7;
    9612             :                                 else entry_size=11;
    9613             :                                 //have dependency list
    9614           0 :                                 if (flags & 0x200000) {
    9615           0 :                                         u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size);
    9616           0 :                                         entry_size += 2 + 2*nb_entries;
    9617             :                                 }
    9618             :                         }
    9619           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n"));
    9620             :                 }
    9621             :                 break;
    9622           0 :         case GF_ISOM_SAMPLE_GROUP_NALM:
    9623           0 :                 if (! entry_size) {
    9624           0 :                         u64 start = gf_bs_get_position(bs);
    9625             :                         Bool rle, large_size;
    9626             :                         u32 entry_count;
    9627           0 :                         gf_bs_read_int(bs, 6);
    9628           0 :                         large_size = gf_bs_read_int(bs, 1);
    9629           0 :                         rle = gf_bs_read_int(bs, 1);
    9630           0 :                         entry_count = gf_bs_read_int(bs, large_size ? 16 : 8);
    9631           0 :                         gf_bs_seek(bs, start);
    9632           0 :                         entry_size = 1 + (large_size ? 2 : 1);
    9633           0 :                         entry_size += entry_count * 2;
    9634           0 :                         if (rle) entry_size += entry_count * (large_size ? 2 : 1);
    9635           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n"));
    9636             :                 }
    9637             :                 break;
    9638             : 
    9639           0 :         case GF_ISOM_SAMPLE_GROUP_TSAS:
    9640             :         case GF_ISOM_SAMPLE_GROUP_STSA:
    9641             :                 null_size_ok = GF_TRUE;
    9642           0 :                 break;
    9643             :         //TODO, add support for these ones ?
    9644           0 :         case GF_ISOM_SAMPLE_GROUP_TSCL:
    9645             :                 entry_size = 20;
    9646           0 :                 break;
    9647           0 :         case GF_ISOM_SAMPLE_GROUP_LBLI:
    9648             :                 entry_size = 2;
    9649           0 :                 break;
    9650             :         default:
    9651             :                 break;
    9652             :         }
    9653             : 
    9654         126 :         if (!entry_size && !null_size_ok) {
    9655           0 :                 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %s sample group does not indicate entry size and is not implemented, cannot parse!\n", gf_4cc_to_str( grouping_type) ));
    9656             :                 return NULL;
    9657             :         }
    9658         126 :         GF_SAFEALLOC(def_ptr, GF_DefaultSampleGroupDescriptionEntry);
    9659         126 :         if (!def_ptr) return NULL;
    9660         126 :         if (entry_size) {
    9661         126 :                 def_ptr->length = entry_size;
    9662         126 :                 def_ptr->data = (u8 *) gf_malloc(sizeof(u8)*def_ptr->length);
    9663         126 :                 if (!def_ptr->data) {
    9664           0 :                         gf_free(def_ptr);
    9665           0 :                         return NULL;
    9666             :                 }
    9667         126 :                 gf_bs_read_data(bs, (char *) def_ptr->data, def_ptr->length);
    9668         126 :                 *total_bytes = entry_size;
    9669             :         }
    9670             :         return def_ptr;
    9671             : }
    9672             : 
    9673         497 : static void     sgpd_del_entry(u32 grouping_type, void *entry)
    9674             : {
    9675         497 :         switch (grouping_type) {
    9676         113 :         case GF_ISOM_SAMPLE_GROUP_SYNC:
    9677             :         case GF_ISOM_SAMPLE_GROUP_ROLL:
    9678             :         case GF_ISOM_SAMPLE_GROUP_PROL:
    9679             :         case GF_ISOM_SAMPLE_GROUP_RAP:
    9680             :         case GF_ISOM_SAMPLE_GROUP_TELE:
    9681             :         case GF_ISOM_SAMPLE_GROUP_SAP:
    9682         113 :                 gf_free(entry);
    9683         113 :                 return;
    9684         167 :         case GF_ISOM_SAMPLE_GROUP_SEIG:
    9685             :         {
    9686             :                 GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
    9687         167 :                 if (seig->key_info) gf_free(seig->key_info);
    9688         167 :                 gf_free(entry);
    9689             :         }
    9690         167 :                 return;
    9691          18 :         case GF_ISOM_SAMPLE_GROUP_OINF:
    9692          18 :                 gf_isom_oinf_del_entry(entry);
    9693          18 :                 return;
    9694          26 :         case GF_ISOM_SAMPLE_GROUP_LINF:
    9695          26 :                 gf_isom_linf_del_entry(entry);
    9696          26 :                 return;
    9697         173 :         default:
    9698             :         {
    9699             :                 GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
    9700         173 :                 if (ptr->data) gf_free(ptr->data);
    9701         173 :                 gf_free(ptr);
    9702             :         }
    9703             :         }
    9704             : }
    9705             : 
    9706         455 : void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs)
    9707             : {
    9708         455 :         switch (grouping_type) {
    9709          17 :         case GF_ISOM_SAMPLE_GROUP_ROLL:
    9710             :         case GF_ISOM_SAMPLE_GROUP_PROL:
    9711          17 :                 gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16);
    9712          17 :                 return;
    9713         119 :         case GF_ISOM_SAMPLE_GROUP_RAP:
    9714         119 :                 gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1);
    9715         119 :                 gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7);
    9716         119 :                 return;
    9717           0 :         case GF_ISOM_SAMPLE_GROUP_SAP:
    9718           0 :                 gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->dependent_flag, 1);
    9719           0 :                 gf_bs_write_int(bs, 0, 3);
    9720           0 :                 gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->SAP_type, 4);
    9721           0 :                 return;
    9722           0 :         case GF_ISOM_SAMPLE_GROUP_SYNC:
    9723           0 :                 gf_bs_write_int(bs, 0, 2);
    9724           0 :                 gf_bs_write_int(bs, ((GF_SYNCEntry*)entry)->NALU_type, 6);
    9725           0 :                 return;
    9726           6 :         case GF_ISOM_SAMPLE_GROUP_TELE:
    9727           6 :                 gf_bs_write_int(bs, ((GF_TemporalLevelEntry*)entry)->level_independently_decodable, 1);
    9728           6 :                 gf_bs_write_int(bs, 0, 7);
    9729           6 :                 return;
    9730         111 :         case GF_ISOM_SAMPLE_GROUP_SEIG:
    9731             :         {
    9732             :                 GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
    9733         111 :                 Bool use_mkey = seig->key_info[0];
    9734             :                 u32 nb_keys = 1;
    9735         111 :                 if (use_mkey) {
    9736           6 :                         nb_keys = seig->key_info[1];
    9737           6 :                         nb_keys<<=8;
    9738           6 :                         nb_keys |= seig->key_info[2];
    9739             :                 }
    9740         111 :                 gf_bs_write_int(bs, use_mkey ? 1 : 0, 1);
    9741         111 :                 gf_bs_write_int(bs, 0, 7);
    9742         111 :                 gf_bs_write_int(bs, seig->crypt_byte_block, 4);
    9743         111 :                 gf_bs_write_int(bs, seig->skip_byte_block, 4);
    9744         111 :                 gf_bs_write_u8(bs, seig->IsProtected);
    9745         111 :                 if (nb_keys>1) {
    9746           6 :                         gf_bs_write_data(bs, seig->key_info+1, seig->key_info_size-1);
    9747             :                 } else {
    9748         105 :                         gf_bs_write_data(bs, seig->key_info+3, seig->key_info_size - 3);
    9749             :                 }
    9750             :         }
    9751             :                 return;
    9752          16 :         case GF_ISOM_SAMPLE_GROUP_OINF:
    9753          16 :                 gf_isom_oinf_write_entry(entry, bs);
    9754          16 :                 return;
    9755          22 :         case GF_ISOM_SAMPLE_GROUP_LINF:
    9756          22 :                 gf_isom_linf_write_entry(entry, bs);
    9757          22 :                 return;
    9758         164 :         default:
    9759             :         {
    9760             :                 GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
    9761         164 :                 if (ptr->length)
    9762         164 :                         gf_bs_write_data(bs, (char *) ptr->data, ptr->length);
    9763             :         }
    9764             :         }
    9765             : }
    9766             : 
    9767             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9768         691 : static u32 sgpd_size_entry(u32 grouping_type, void *entry)
    9769             : {
    9770         691 :         switch (grouping_type) {
    9771             :         case GF_ISOM_SAMPLE_GROUP_ROLL:
    9772             :         case GF_ISOM_SAMPLE_GROUP_PROL:
    9773             :                 return 2;
    9774         153 :         case GF_ISOM_SAMPLE_GROUP_TELE:
    9775             :         case GF_ISOM_SAMPLE_GROUP_RAP:
    9776             :         case GF_ISOM_SAMPLE_GROUP_SAP:
    9777             :         case GF_ISOM_SAMPLE_GROUP_SYNC:
    9778         153 :                 return 1;
    9779           0 :         case GF_ISOM_SAMPLE_GROUP_TSCL:
    9780           0 :                 return 20;
    9781             :         case GF_ISOM_SAMPLE_GROUP_LBLI:
    9782             :                 return 2;
    9783           0 :         case GF_ISOM_SAMPLE_GROUP_TSAS:
    9784             :         case GF_ISOM_SAMPLE_GROUP_STSA:
    9785           0 :                 return 0;
    9786         177 :         case GF_ISOM_SAMPLE_GROUP_SEIG:
    9787             :         {
    9788             :                 GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
    9789         177 :                 Bool use_mkey = seig->key_info[0] ? GF_TRUE : GF_FALSE;
    9790         177 :                 if (use_mkey) {
    9791          12 :                         return 3 + seig->key_info_size-1;
    9792             :                 }
    9793         165 :                 return seig->key_info_size; //== 3 + (seig->key_info_size-3);
    9794             :         }
    9795          30 :         case GF_ISOM_SAMPLE_GROUP_OINF:
    9796          30 :                 return gf_isom_oinf_size_entry(entry);
    9797          40 :         case GF_ISOM_SAMPLE_GROUP_LINF:
    9798          40 :                 return gf_isom_linf_size_entry(entry);
    9799         242 :         default:
    9800         242 :                 return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length;
    9801             :         }
    9802             : }
    9803             : #endif
    9804             : 
    9805         555 : GF_Box *sgpd_box_new()
    9806             : {
    9807        1110 :         ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
    9808             :         /*version 0 is deprecated, use v1 by default*/
    9809         555 :         tmp->version = 1;
    9810         555 :         tmp->group_descriptions = gf_list_new();
    9811         555 :         return (GF_Box *)tmp;
    9812             : }
    9813             : 
    9814         555 : void sgpd_box_del(GF_Box *a)
    9815             : {
    9816             :         GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a;
    9817        1607 :         while (gf_list_count(p->group_descriptions)) {
    9818         497 :                 void *ptr = gf_list_last(p->group_descriptions);
    9819         497 :                 sgpd_del_entry(p->grouping_type, ptr);
    9820         497 :                 gf_list_rem_last(p->group_descriptions);
    9821             :         }
    9822         555 :         gf_list_del(p->group_descriptions);
    9823         555 :         gf_free(p);
    9824         555 : }
    9825             : 
    9826         346 : GF_Err sgpd_box_read(GF_Box *s, GF_BitStream *bs)
    9827             : {
    9828             :         u32 entry_count;
    9829             :         GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
    9830             : 
    9831         346 :         ISOM_DECREASE_SIZE(p, 8);
    9832         346 :         p->grouping_type = gf_bs_read_u32(bs);
    9833             : 
    9834         346 :         if (p->version>=1) {
    9835         346 :                 ISOM_DECREASE_SIZE(p, 4);
    9836         346 :                 p->default_length = gf_bs_read_u32(bs);
    9837             :         }
    9838         346 :         if (p->version>=2) {
    9839         156 :                 ISOM_DECREASE_SIZE(p, 4);
    9840         156 :                 p->default_description_index = gf_bs_read_u32(bs);
    9841             :         }
    9842         346 :         entry_count = gf_bs_read_u32(bs);
    9843             : 
    9844         346 :         if (entry_count>p->size)
    9845             :                 return GF_ISOM_INVALID_FILE;
    9846             : 
    9847         701 :         while (entry_count) {
    9848             :                 void *ptr;
    9849         355 :                 u32 parsed_bytes=0;
    9850         355 :                 u32 size = p->default_length;
    9851         355 :                 if ((p->version>=1) && !size) {
    9852           0 :                         size = gf_bs_read_u32(bs);
    9853           0 :                         ISOM_DECREASE_SIZE(p, 4);
    9854             :                 }
    9855         355 :                 ptr = sgpd_parse_entry(p->grouping_type, bs, (s32) p->size, size, &parsed_bytes);
    9856             :                 //don't return an error, just stop parsing so that we skip over the sgpd box
    9857         355 :                 if (!ptr) return GF_OK;
    9858         355 :                 gf_list_add(p->group_descriptions, ptr);
    9859             : 
    9860         355 :                 ISOM_DECREASE_SIZE(p, parsed_bytes);
    9861         355 :                 entry_count--;
    9862             :         }
    9863             :         return GF_OK;
    9864             : }
    9865             : 
    9866             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9867         417 : GF_Err sgpd_box_write(GF_Box *s, GF_BitStream *bs)
    9868             : {
    9869             :         u32 i, nb_descs;
    9870             :         GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
    9871             :         GF_Err e;
    9872         417 :         e = gf_isom_full_box_write(s, bs);
    9873         417 :         if (e) return e;
    9874             : 
    9875         417 :         gf_bs_write_u32(bs, p->grouping_type);
    9876         417 :         if (p->version>=1) gf_bs_write_u32(bs, p->default_length);
    9877         417 :         if (p->version>=2) gf_bs_write_u32(bs, p->default_description_index);
    9878         417 :         nb_descs = gf_list_count(p->group_descriptions);
    9879         417 :         gf_bs_write_u32(bs, nb_descs);
    9880             : 
    9881         830 :         for (i=0; i<nb_descs; i++) {
    9882         413 :                 void *ptr = gf_list_get(p->group_descriptions, i);
    9883         413 :                 if ((p->version >= 1) && !p->default_length) {
    9884           2 :                         u32 size = sgpd_size_entry(p->grouping_type, ptr);
    9885           2 :                         gf_bs_write_u32(bs, size);
    9886             :                 }
    9887         413 :                 sgpd_write_entry(p->grouping_type, ptr, bs);
    9888             :         }
    9889             :         return GF_OK;
    9890             : }
    9891             : 
    9892         715 : GF_Err sgpd_box_size(GF_Box *s)
    9893             : {
    9894             :         u32 i, nb_descs;
    9895             :         Bool use_def_size = GF_TRUE;
    9896             :         GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
    9897             : 
    9898         715 :         p->size += 8;
    9899             : 
    9900             :         //we force all sample groups to version 1, v0 being deprecated
    9901         715 :         if (!p->version)
    9902           0 :                 p->version = 1;
    9903         715 :         p->size += 4;
    9904             : 
    9905         715 :         if (p->version>=2)
    9906         277 :                 p->size += 4;
    9907         715 :         p->default_length = 0;
    9908             : 
    9909         715 :         nb_descs = gf_list_count(p->group_descriptions);
    9910        1404 :         for (i=0; i<nb_descs; i++) {
    9911         689 :                 void *ptr = gf_list_get(p->group_descriptions, i);
    9912         689 :                 u32 size = sgpd_size_entry(p->grouping_type, ptr);
    9913         689 :                 p->size += size;
    9914         689 :                 if (use_def_size && !p->default_length) {
    9915         598 :                         p->default_length = size;
    9916          91 :                 } else if (p->default_length != size) {
    9917             :                         use_def_size = GF_FALSE;
    9918           3 :                         p->default_length = 0;
    9919             :                 }
    9920             :         }
    9921         715 :         if (p->version>=1) {
    9922         715 :                 if (!p->default_length) p->size += nb_descs * 4;
    9923             :         }
    9924         715 :         return GF_OK;
    9925             : }
    9926             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
    9927             : 
    9928             : 
    9929         916 : void saiz_box_del(GF_Box *s)
    9930             : {
    9931             :         GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
    9932         916 :         if (ptr == NULL) return;
    9933         916 :         if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
    9934         916 :         gf_free(ptr);
    9935             : }
    9936             : 
    9937             : 
    9938         402 : GF_Err saiz_box_read(GF_Box *s, GF_BitStream *bs)
    9939             : {
    9940             :         GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
    9941             : 
    9942         402 :         if (ptr->flags & 1) {
    9943           9 :                 ISOM_DECREASE_SIZE(ptr, 8);
    9944           9 :                 ptr->aux_info_type = gf_bs_read_u32(bs);
    9945           9 :                 ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
    9946             :         }
    9947         402 :         ISOM_DECREASE_SIZE(ptr, 5);
    9948         402 :         ptr->default_sample_info_size = gf_bs_read_u8(bs);
    9949         402 :         ptr->sample_count = gf_bs_read_u32(bs);
    9950             : 
    9951         402 :         if (ptr->default_sample_info_size == 0) {
    9952         177 :                 if (ptr->size < ptr->sample_count)
    9953             :                     return GF_ISOM_INVALID_FILE;
    9954             : 
    9955         177 :                 ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
    9956         177 :                 ptr->sample_alloc = ptr->sample_count;
    9957         177 :                 if (!ptr->sample_info_size)
    9958             :                     return GF_OUT_OF_MEM;
    9959             : 
    9960         177 :                 ISOM_DECREASE_SIZE(ptr, ptr->sample_count);
    9961         177 :                 gf_bs_read_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
    9962             :         }
    9963             :         return GF_OK;
    9964             : }
    9965             : 
    9966         916 : GF_Box *saiz_box_new()
    9967             : {
    9968        1832 :         ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
    9969         916 :         return (GF_Box *)tmp;
    9970             : }
    9971             : 
    9972             : #ifndef GPAC_DISABLE_ISOM_WRITE
    9973             : 
    9974         437 : GF_Err saiz_box_write(GF_Box *s, GF_BitStream *bs)
    9975             : {
    9976             :         GF_Err e;
    9977             :         GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s;
    9978         437 :         if (!s) return GF_BAD_PARAM;
    9979         437 :         e = gf_isom_full_box_write(s, bs);
    9980         437 :         if (e) return e;
    9981             : 
    9982         437 :         if (ptr->flags & 1) {
    9983           4 :                 gf_bs_write_u32(bs, ptr->aux_info_type);
    9984           4 :                 gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
    9985             :         }
    9986         437 :         gf_bs_write_u8(bs, ptr->default_sample_info_size);
    9987         437 :         gf_bs_write_u32(bs, ptr->sample_count);
    9988         437 :         if (!ptr->default_sample_info_size) {
    9989         134 :                 if (!ptr->sample_info_size)
    9990           2 :                         gf_bs_write_u8(bs, 0);
    9991             :                 else
    9992         132 :                         gf_bs_write_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
    9993             :         }
    9994             :         return GF_OK;
    9995             : }
    9996             : 
    9997        1245 : GF_Err saiz_box_size(GF_Box *s)
    9998             : {
    9999             :         GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
   10000             : 
   10001        1245 :         if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
   10002          12 :                 ptr->flags |= 1;
   10003             :         }
   10004        1245 :         if (ptr->flags & 1) ptr->size += 8;
   10005        1245 :         ptr->size += 5;
   10006        1245 :         if (ptr->default_sample_info_size==0)  ptr->size += ptr->sample_count;
   10007        1245 :         return GF_OK;
   10008             : }
   10009             : #endif //GPAC_DISABLE_ISOM_WRITE
   10010             : 
   10011         918 : void saio_box_del(GF_Box *s)
   10012             : {
   10013             :         GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
   10014         918 :         if (ptr == NULL) return;
   10015         918 :         if (ptr->offsets) gf_free(ptr->offsets);
   10016         918 :         if (ptr->cached_data) gf_free(ptr->cached_data);
   10017         918 :         gf_free(ptr);
   10018             : }
   10019             : 
   10020             : 
   10021         402 : GF_Err saio_box_read(GF_Box *s, GF_BitStream *bs)
   10022             : {
   10023             :         GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
   10024             : 
   10025         402 :         if (ptr->flags & 1) {
   10026           3 :                 ISOM_DECREASE_SIZE(ptr, 8);
   10027           3 :                 ptr->aux_info_type = gf_bs_read_u32(bs);
   10028           3 :                 ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
   10029             :         }
   10030         402 :         ISOM_DECREASE_SIZE(ptr, 4);
   10031         402 :         ptr->entry_count = gf_bs_read_u32(bs);
   10032             : 
   10033         402 :         if (ptr->entry_count) {
   10034             :                 u32 i;
   10035         400 :                 if (ptr->size / (ptr->version == 0 ? 4 : 8) < ptr->entry_count)
   10036             :                         return GF_ISOM_INVALID_FILE;
   10037         400 :                 ptr->offsets = gf_malloc(sizeof(u64)*ptr->entry_count);
   10038         400 :                 if (!ptr->offsets)
   10039             :                         return GF_OUT_OF_MEM;
   10040         400 :                 ptr->entry_alloc = ptr->entry_count;
   10041         400 :                 if (ptr->version==0) {
   10042           3 :                         ISOM_DECREASE_SIZE(ptr, 4*ptr->entry_count);
   10043           6 :                         for (i=0; i<ptr->entry_count; i++)
   10044           3 :                                 ptr->offsets[i] = gf_bs_read_u32(bs);
   10045             :                 } else {
   10046         397 :                         ISOM_DECREASE_SIZE(ptr, 8*ptr->entry_count);
   10047         794 :                         for (i=0; i<ptr->entry_count; i++)
   10048         397 :                                 ptr->offsets[i] = gf_bs_read_u64(bs);
   10049             :                 }
   10050             :         }
   10051             :         return GF_OK;
   10052             : }
   10053             : 
   10054         918 : GF_Box *saio_box_new()
   10055             : {
   10056        1836 :         ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
   10057         918 :         return (GF_Box *)tmp;
   10058             : }
   10059             : 
   10060             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10061             : 
   10062         437 : GF_Err saio_box_write(GF_Box *s, GF_BitStream *bs)
   10063             : {
   10064             :         GF_Err e;
   10065             :         GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s;
   10066         437 :         if (!s) return GF_BAD_PARAM;
   10067         437 :         e = gf_isom_full_box_write(s, bs);
   10068         437 :         if (e) return e;
   10069             : 
   10070         437 :         if (ptr->flags & 1) {
   10071           1 :                 gf_bs_write_u32(bs, ptr->aux_info_type);
   10072           1 :                 gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
   10073             :         }
   10074             : 
   10075             : 
   10076         437 :         gf_bs_write_u32(bs, ptr->entry_count);
   10077         437 :         if (ptr->entry_count) {
   10078             :                 u32 i;
   10079             :                 //store position in bitstream before writing data - offsets can be NULL if a single offset is rewritten later on (cf senc_box_write)
   10080         435 :                 ptr->offset_first_offset_field = gf_bs_get_position(bs);
   10081         435 :                 if (ptr->version==0) {
   10082           0 :                         if (!ptr->offsets) {
   10083           0 :                                 gf_bs_write_u32(bs, 0);
   10084             :                         } else {
   10085           0 :                                 for (i=0; i<ptr->entry_count; i++)
   10086           0 :                                         gf_bs_write_u32(bs, (u32) ptr->offsets[i]);
   10087             :                         }
   10088             :                 } else {
   10089         435 :                         if (!ptr->offsets) {
   10090         434 :                                 gf_bs_write_u64(bs, 0);
   10091             :                         } else {
   10092           1 :                                 for (i=0; i<ptr->entry_count; i++)
   10093           1 :                                         gf_bs_write_u64(bs, ptr->offsets[i]);
   10094             :                         }
   10095             :                 }
   10096             :         }
   10097             :         return GF_OK;
   10098             : }
   10099             : 
   10100        1245 : GF_Err saio_box_size(GF_Box *s)
   10101             : {
   10102             :         GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
   10103             : 
   10104        1245 :         if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
   10105           3 :                 ptr->flags |= 1;
   10106             :         }
   10107             : 
   10108        1245 :         if (ptr->flags & 1) ptr->size += 8;
   10109        1245 :         ptr->size += 4;
   10110             :         //a little optim here: in cenc, the saio always points to a single data block, only one entry is needed
   10111        1245 :         switch (ptr->aux_info_type) {
   10112           3 :         case GF_ISOM_CENC_SCHEME:
   10113             :         case GF_ISOM_CBC_SCHEME:
   10114             :         case GF_ISOM_CENS_SCHEME:
   10115             :         case GF_ISOM_CBCS_SCHEME:
   10116           3 :                 if (ptr->offsets) gf_free(ptr->offsets);
   10117           3 :                 ptr->offsets = NULL;
   10118           3 :                 ptr->entry_alloc = 0;
   10119           3 :                 ptr->entry_count = 1;
   10120           3 :                 break;
   10121             :         }
   10122             : 
   10123        1245 :         ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count;
   10124        1245 :         return GF_OK;
   10125             : }
   10126             : #endif //GPAC_DISABLE_ISOM_WRITE
   10127             : 
   10128             : 
   10129           4 : void prft_box_del(GF_Box *s)
   10130             : {
   10131           4 :         gf_free(s);
   10132           4 : }
   10133             : 
   10134           1 : GF_Err prft_box_read(GF_Box *s,GF_BitStream *bs)
   10135             : {
   10136             :         GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
   10137             : 
   10138           1 :         ISOM_DECREASE_SIZE(ptr, 12);
   10139           1 :         ptr->refTrackID = gf_bs_read_u32(bs);
   10140           1 :         ptr->ntp = gf_bs_read_u64(bs);
   10141           1 :         if (ptr->version==0) {
   10142           1 :                 ISOM_DECREASE_SIZE(ptr, 4);
   10143           1 :                 ptr->timestamp = gf_bs_read_u32(bs);
   10144             :         } else {
   10145           0 :                 ISOM_DECREASE_SIZE(ptr, 8);
   10146           0 :                 ptr->timestamp = gf_bs_read_u64(bs);
   10147             :         }
   10148             :         return GF_OK;
   10149             : }
   10150             : 
   10151           4 : GF_Box *prft_box_new()
   10152             : {
   10153           8 :         ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
   10154           4 :         return (GF_Box *)tmp;
   10155             : }
   10156             : 
   10157             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10158           1 : GF_Err prft_box_write(GF_Box *s, GF_BitStream *bs)
   10159             : {
   10160             :         GF_Err e;
   10161             :         GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
   10162           1 :         if (!s) return GF_BAD_PARAM;
   10163           1 :         e = gf_isom_full_box_write(s, bs);
   10164           1 :         if (e) return e;
   10165             : 
   10166           1 :         gf_bs_write_u32(bs, ptr->refTrackID);
   10167           1 :         gf_bs_write_u64(bs, ptr->ntp);
   10168           1 :         if (ptr->version==0) {
   10169           1 :                 gf_bs_write_u32(bs, (u32) ptr->timestamp);
   10170             :         } else {
   10171           0 :                 gf_bs_write_u64(bs, ptr->timestamp);
   10172             :         }
   10173             : 
   10174             :         return GF_OK;
   10175             : }
   10176             : 
   10177           1 : GF_Err prft_box_size(GF_Box *s)
   10178             : {
   10179             :         GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox*)s;
   10180             : 
   10181           1 :         ptr->size += 4+8+ (ptr->version ? 8 : 4);
   10182           1 :         return GF_OK;
   10183             : }
   10184             : #endif //GPAC_DISABLE_ISOM_WRITE
   10185             : 
   10186          28 : GF_Box *trgr_box_new()
   10187             : {
   10188          56 :         ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR);
   10189          28 :         tmp->groups = gf_list_new();
   10190          28 :         if (!tmp->groups) {
   10191           0 :                 gf_free(tmp);
   10192           0 :                 return NULL;
   10193             :         }
   10194             :         return (GF_Box *)tmp;
   10195             : }
   10196             : 
   10197          28 : void trgr_box_del(GF_Box *s)
   10198             : {
   10199             :         GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
   10200          28 :         if (ptr == NULL) return;
   10201          28 :         gf_list_del(ptr->groups);
   10202          28 :         gf_free(ptr);
   10203             : }
   10204             : 
   10205             : 
   10206          19 : GF_Err trgr_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
   10207             : {
   10208             :         GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
   10209             : 
   10210          19 :         BOX_FIELD_LIST_ASSIGN(groups)
   10211          19 :         return gf_list_add(ptr->groups, a);
   10212             : }
   10213             : 
   10214             : 
   10215          20 : GF_Err trgr_box_read(GF_Box *s, GF_BitStream *bs)
   10216             : {
   10217          20 :         return gf_isom_box_array_read_ex(s, bs, s->type);
   10218             : }
   10219             : 
   10220             : 
   10221             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10222             : 
   10223             : 
   10224          24 : GF_Err trgr_box_write(GF_Box *s, GF_BitStream *bs)
   10225             : {
   10226          24 :         return gf_isom_box_write_header(s, bs);
   10227             : }
   10228             : 
   10229          42 : GF_Err trgr_box_size(GF_Box *s)
   10230             : {
   10231          42 :         u32 pos=0;
   10232             :         GF_TrackGroupBox *ptr = (GF_TrackGroupBox *) s;
   10233          42 :         gf_isom_check_position_list(s, ptr->groups, &pos);
   10234          42 :         return GF_OK;
   10235             : }
   10236             : 
   10237             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10238             : 
   10239             : 
   10240          31 : GF_Box *trgt_box_new()
   10241             : {
   10242          62 :         ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT);
   10243          31 :         return (GF_Box *)tmp;
   10244             : }
   10245             : 
   10246          31 : void trgt_box_del(GF_Box *s)
   10247             : {
   10248             :         GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
   10249          31 :         if (ptr == NULL) return;
   10250          31 :         gf_free(ptr);
   10251             : }
   10252             : 
   10253          19 : GF_Err trgt_box_read(GF_Box *s, GF_BitStream *bs)
   10254             : {
   10255             :         GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
   10256          19 :         ISOM_DECREASE_SIZE(ptr, 4);
   10257          19 :         ptr->track_group_id = gf_bs_read_u32(bs);
   10258          19 :         return GF_OK;
   10259             : }
   10260             : 
   10261             : 
   10262             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10263             : 
   10264          26 : GF_Err trgt_box_write(GF_Box *s, GF_BitStream *bs)
   10265             : {
   10266             :         GF_Err e;
   10267             :         GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *) s;
   10268          26 :         if (!s) return GF_BAD_PARAM;
   10269          26 :         s->type = ptr->group_type;
   10270          26 :         e = gf_isom_full_box_write(s, bs);
   10271          26 :         s->type = GF_ISOM_BOX_TYPE_TRGT;
   10272          26 :         if (e) return e;
   10273          26 :         gf_bs_write_u32(bs, ptr->track_group_id);
   10274          26 :         return GF_OK;
   10275             : }
   10276             : 
   10277          44 : GF_Err trgt_box_size(GF_Box *s)
   10278             : {
   10279             :         GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
   10280             : 
   10281          44 :         ptr->size+= 4;
   10282          44 :         return GF_OK;
   10283             : }
   10284             : 
   10285             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10286             : 
   10287             : 
   10288             : 
   10289           3 : GF_Box *stvi_box_new()
   10290             : {
   10291           6 :         ISOM_DECL_BOX_ALLOC(GF_StereoVideoBox, GF_ISOM_BOX_TYPE_STVI);
   10292           3 :         return (GF_Box *)tmp;
   10293             : }
   10294             : 
   10295           3 : void stvi_box_del(GF_Box *s)
   10296             : {
   10297             :         GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
   10298           3 :         if (ptr == NULL) return;
   10299           3 :         if (ptr->stereo_indication_type) gf_free(ptr->stereo_indication_type);
   10300           3 :         gf_free(ptr);
   10301             : }
   10302             : 
   10303           1 : GF_Err stvi_box_read(GF_Box *s, GF_BitStream *bs)
   10304             : {
   10305             :         GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
   10306             : 
   10307           1 :         ISOM_DECREASE_SIZE(ptr, 12);
   10308           1 :         gf_bs_read_int(bs, 30);
   10309           1 :         ptr->single_view_allowed = gf_bs_read_int(bs, 2);
   10310           1 :         ptr->stereo_scheme = gf_bs_read_u32(bs);
   10311           1 :         ptr->sit_len = gf_bs_read_u32(bs);
   10312           1 :         ISOM_DECREASE_SIZE(ptr, ptr->sit_len);
   10313             : 
   10314           1 :         ptr->stereo_indication_type = gf_malloc(sizeof(char)*ptr->sit_len);
   10315           1 :         if (!ptr->stereo_indication_type) return GF_OUT_OF_MEM;
   10316             : 
   10317           1 :         gf_bs_read_data(bs, ptr->stereo_indication_type, ptr->sit_len);
   10318           1 :         return GF_OK;
   10319             : }
   10320             : 
   10321             : 
   10322             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10323             : 
   10324           1 : GF_Err stvi_box_write(GF_Box *s, GF_BitStream *bs)
   10325             : {
   10326             :         GF_Err e;
   10327             :         GF_StereoVideoBox *ptr = (GF_StereoVideoBox *) s;
   10328           1 :         if (!s) return GF_BAD_PARAM;
   10329           1 :         e = gf_isom_full_box_write(s, bs);
   10330           1 :         if (e) return e;
   10331             : 
   10332           1 :         gf_bs_write_int(bs, 0, 30);
   10333           1 :         gf_bs_write_int(bs, ptr->single_view_allowed, 2);
   10334           1 :         gf_bs_write_u32(bs, ptr->stereo_scheme);
   10335           1 :         gf_bs_write_u32(bs, ptr->sit_len);
   10336           1 :         gf_bs_write_data(bs, ptr->stereo_indication_type, ptr->sit_len);
   10337             : 
   10338           1 :         return GF_OK;
   10339             : }
   10340             : 
   10341           1 : GF_Err stvi_box_size(GF_Box *s)
   10342             : {
   10343             :         GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
   10344             : 
   10345           1 :         ptr->size+= 12 + ptr->sit_len;
   10346           1 :         return GF_OK;
   10347             : }
   10348             : 
   10349             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10350             : 
   10351             : 
   10352             : 
   10353           3 : GF_Box *fiin_box_new()
   10354             : {
   10355           6 :         ISOM_DECL_BOX_ALLOC(FDItemInformationBox, GF_ISOM_BOX_TYPE_FIIN);
   10356           3 :         return (GF_Box *)tmp;
   10357             : }
   10358             : 
   10359           3 : void fiin_box_del(GF_Box *s)
   10360             : {
   10361             :         FDItemInformationBox *ptr = (FDItemInformationBox *)s;
   10362           3 :         if (ptr == NULL) return;
   10363           3 :         if (ptr->partition_entries) gf_list_del(ptr->partition_entries);
   10364           3 :         gf_free(ptr);
   10365             : }
   10366             : 
   10367             : 
   10368           0 : GF_Err fiin_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
   10369             : {
   10370             :         FDItemInformationBox *ptr = (FDItemInformationBox *)s;
   10371           0 :         switch(a->type) {
   10372           0 :         case GF_ISOM_BOX_TYPE_PAEN:
   10373           0 :                 BOX_FIELD_LIST_ASSIGN(partition_entries)
   10374             :                 return GF_OK;
   10375           0 :         case GF_ISOM_BOX_TYPE_SEGR:
   10376           0 :                 BOX_FIELD_ASSIGN(session_info, FDSessionGroupBox)
   10377           0 :                 return GF_OK;
   10378           0 :         case GF_ISOM_BOX_TYPE_GITN:
   10379           0 :                 BOX_FIELD_ASSIGN(group_id_to_name, GroupIdToNameBox)
   10380           0 :                 return GF_OK;
   10381             :         }
   10382             :         return GF_OK;
   10383             : }
   10384             : 
   10385           1 : GF_Err fiin_box_read(GF_Box *s, GF_BitStream *bs)
   10386             : {
   10387             :         FDItemInformationBox *ptr = (FDItemInformationBox *)s;
   10388             : 
   10389           1 :         ISOM_DECREASE_SIZE(ptr, 2);
   10390           1 :         gf_bs_read_u16(bs);
   10391           1 :         return gf_isom_box_array_read(s, bs);
   10392             : }
   10393             : 
   10394             : 
   10395             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10396             : 
   10397           1 : GF_Err fiin_box_write(GF_Box *s, GF_BitStream *bs)
   10398             : {
   10399             :         GF_Err e;
   10400             :         FDItemInformationBox *ptr = (FDItemInformationBox *) s;
   10401           1 :         if (!s) return GF_BAD_PARAM;
   10402           1 :         e = gf_isom_full_box_write(s, bs);
   10403           1 :         if (e) return e;
   10404             : 
   10405           1 :         gf_bs_write_u16(bs, gf_list_count(ptr->partition_entries) );
   10406           1 :         return GF_OK;
   10407             : }
   10408             : 
   10409           1 : GF_Err fiin_box_size(GF_Box *s)
   10410             : {
   10411           1 :         u32 pos=0;
   10412             :         FDItemInformationBox *ptr = (FDItemInformationBox *) s;
   10413           1 :         s->size+= 2;
   10414           1 :         gf_isom_check_position_list(s, ptr->partition_entries, &pos);
   10415           1 :         return GF_OK;
   10416             : }
   10417             : 
   10418             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10419             : 
   10420             : 
   10421           3 : GF_Box *paen_box_new()
   10422             : {
   10423           6 :         ISOM_DECL_BOX_ALLOC(FDPartitionEntryBox, GF_ISOM_BOX_TYPE_PAEN);
   10424           3 :         return (GF_Box *)tmp;
   10425             : }
   10426             : 
   10427           3 : void paen_box_del(GF_Box *s)
   10428             : {
   10429           3 :         gf_free(s);
   10430           3 : }
   10431             : 
   10432             : 
   10433           0 : GF_Err paen_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
   10434             : {
   10435             :         FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
   10436           0 :         switch(a->type) {
   10437           0 :         case GF_ISOM_BOX_TYPE_FPAR:
   10438           0 :                 BOX_FIELD_ASSIGN(blocks_and_symbols, FilePartitionBox)
   10439           0 :                 return GF_OK;
   10440           0 :         case GF_ISOM_BOX_TYPE_FECR:
   10441           0 :                 BOX_FIELD_ASSIGN(FEC_symbol_locations, FECReservoirBox)
   10442           0 :                 return GF_OK;
   10443           0 :         case GF_ISOM_BOX_TYPE_FIRE:
   10444           0 :                 BOX_FIELD_ASSIGN(File_symbol_locations, FileReservoirBox)
   10445           0 :                 return GF_OK;
   10446             :         }
   10447             :         return GF_OK;
   10448             : }
   10449             : 
   10450           1 : GF_Err paen_box_read(GF_Box *s, GF_BitStream *bs)
   10451             : {
   10452           1 :         return gf_isom_box_array_read(s, bs);
   10453             : }
   10454             : 
   10455             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10456             : 
   10457           1 : GF_Err paen_box_write(GF_Box *s, GF_BitStream *bs)
   10458             : {
   10459           1 :         if (!s) return GF_BAD_PARAM;
   10460           1 :         return gf_isom_box_write_header(s, bs);
   10461             : }
   10462             : 
   10463           1 : GF_Err paen_box_size(GF_Box *s)
   10464             : {
   10465           1 :         return GF_OK;
   10466             : }
   10467             : 
   10468             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10469             : 
   10470             : 
   10471             : 
   10472             : 
   10473           4 : GF_Box *fpar_box_new()
   10474             : {
   10475           8 :         ISOM_DECL_BOX_ALLOC(FilePartitionBox, GF_ISOM_BOX_TYPE_FPAR);
   10476           4 :         return (GF_Box *)tmp;
   10477             : }
   10478             : 
   10479           4 : void fpar_box_del(GF_Box *s)
   10480             : {
   10481             :         FilePartitionBox *ptr = (FilePartitionBox *)s;
   10482           4 :         if (ptr == NULL) return;
   10483           4 :         if (ptr->scheme_specific_info) gf_free(ptr->scheme_specific_info);
   10484           4 :         if (ptr->entries) gf_free(ptr->entries);
   10485           4 :         gf_free(ptr);
   10486             : }
   10487             : 
   10488           7 : GF_Err gf_isom_read_null_terminated_string(GF_Box *s, GF_BitStream *bs, u64 size, char **out_str)
   10489             : {
   10490             :         u32 len=10;
   10491             :         u32 i=0;
   10492             : 
   10493           7 :         *out_str = gf_malloc(sizeof(char)*len);
   10494           7 :         if (! *out_str) return GF_OUT_OF_MEM;
   10495             : 
   10496           7 :         if (!s->size) {
   10497           0 :                 *out_str[0] = 0;
   10498           0 :                 return GF_OK;
   10499             :         }
   10500             : 
   10501             :         while (1) {
   10502        3647 :                 ISOM_DECREASE_SIZE(s, 1 );
   10503        3647 :                 (*out_str)[i] = gf_bs_read_u8(bs);
   10504        3647 :                 if (!(*out_str)[i]) break;
   10505        3640 :                 i++;
   10506        3640 :                 if (i==len) {
   10507         364 :                         len += 10;
   10508         364 :                         *out_str = gf_realloc(*out_str, sizeof(char)*len);
   10509             :                 }
   10510        3640 :                 if (gf_bs_available(bs) == 0) {
   10511           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] missing null character in null terminated string\n"));
   10512           0 :                         (*out_str)[i] = 0;
   10513           0 :                         return GF_OK;
   10514             :                 }
   10515        3640 :                 if (i >= size) {
   10516           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] string bigger than container, probably missing null character\n"));
   10517           0 :                         (*out_str)[i] = 0;
   10518           0 :                         return GF_OK;
   10519             :                 }
   10520             :         }
   10521             :         return GF_OK;
   10522             : }
   10523             : 
   10524           1 : GF_Err fpar_box_read(GF_Box *s, GF_BitStream *bs)
   10525             : {
   10526             :         u32 i;
   10527             :         GF_Err e;
   10528             :         FilePartitionBox *ptr = (FilePartitionBox *)s;
   10529             : 
   10530           1 :         ISOM_DECREASE_SIZE(ptr, ((ptr->version ? 4 : 2) + 12) );
   10531           1 :         ptr->itemID = gf_bs_read_int(bs, ptr->version ? 32 : 16);
   10532           1 :         ptr->packet_payload_size = gf_bs_read_u16(bs);
   10533           1 :         gf_bs_read_u8(bs);
   10534           1 :         ptr->FEC_encoding_ID = gf_bs_read_u8(bs);
   10535           1 :         ptr->FEC_instance_ID = gf_bs_read_u16(bs);
   10536           1 :         ptr->max_source_block_length = gf_bs_read_u16(bs);
   10537           1 :         ptr->encoding_symbol_length = gf_bs_read_u16(bs);
   10538           1 :         ptr->max_number_of_encoding_symbols = gf_bs_read_u16(bs);
   10539             : 
   10540           1 :         e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_specific_info);
   10541           1 :         if (e) return e;
   10542             : 
   10543           1 :         ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
   10544           1 :         ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
   10545           1 :         if (ptr->nb_entries > ptr->size / 6)
   10546             :                 return GF_ISOM_INVALID_FILE;
   10547             : 
   10548           1 :         ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * 6 );
   10549           1 :         GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FilePartitionEntry);
   10550           1 :         if (!ptr->entries) return GF_OUT_OF_MEM;
   10551             : 
   10552           0 :         for (i=0;i < ptr->nb_entries; i++) {
   10553           0 :                 ptr->entries[i].block_count = gf_bs_read_u16(bs);
   10554           0 :                 ptr->entries[i].block_size = gf_bs_read_u32(bs);
   10555             :         }
   10556             :         return GF_OK;
   10557             : }
   10558             : 
   10559             : 
   10560             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10561             : 
   10562           1 : GF_Err fpar_box_write(GF_Box *s, GF_BitStream *bs)
   10563             : {
   10564             :         GF_Err e;
   10565             :         u32 i;
   10566             :         FilePartitionBox *ptr = (FilePartitionBox *) s;
   10567           1 :         if (!s) return GF_BAD_PARAM;
   10568           1 :         e = gf_isom_full_box_write(s, bs);
   10569           1 :         if (e) return e;
   10570             : 
   10571           1 :         gf_bs_write_int(bs, ptr->itemID, ptr->version ? 32 : 16);
   10572           1 :         gf_bs_write_u16(bs, ptr->packet_payload_size);
   10573           1 :         gf_bs_write_u8(bs, 0);
   10574           1 :         gf_bs_write_u8(bs, ptr->FEC_encoding_ID);
   10575           1 :         gf_bs_write_u16(bs, ptr->FEC_instance_ID);
   10576           1 :         gf_bs_write_u16(bs, ptr->max_source_block_length);
   10577           1 :         gf_bs_write_u16(bs, ptr->encoding_symbol_length);
   10578           1 :         gf_bs_write_u16(bs, ptr->max_number_of_encoding_symbols);
   10579           1 :         if (ptr->scheme_specific_info) {
   10580           0 :                 gf_bs_write_data(bs, ptr->scheme_specific_info, (u32)strlen(ptr->scheme_specific_info) );
   10581             :         }
   10582             :         //null terminated string
   10583           1 :         gf_bs_write_u8(bs, 0);
   10584             : 
   10585           1 :         gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
   10586             : 
   10587           1 :         for (i=0;i < ptr->nb_entries; i++) {
   10588           0 :                 gf_bs_write_u16(bs, ptr->entries[i].block_count);
   10589           0 :                 gf_bs_write_u32(bs, ptr->entries[i].block_size);
   10590             :         }
   10591             :         return GF_OK;
   10592             : }
   10593             : 
   10594           1 : GF_Err fpar_box_size(GF_Box *s)
   10595             : {
   10596             :         FilePartitionBox *ptr = (FilePartitionBox *)s;
   10597             : 
   10598           1 :         ptr->size += 13 + (ptr->version ? 8 : 4);
   10599           1 :         if (ptr->scheme_specific_info)
   10600           0 :                 ptr->size += strlen(ptr->scheme_specific_info);
   10601             : 
   10602           1 :         ptr->size+= ptr->nb_entries * 6;
   10603           1 :         return GF_OK;
   10604             : }
   10605             : 
   10606             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10607             : 
   10608             : 
   10609           8 : GF_Box *fecr_box_new()
   10610             : {
   10611          16 :         ISOM_DECL_BOX_ALLOC(FECReservoirBox, GF_ISOM_BOX_TYPE_FECR);
   10612           8 :         return (GF_Box *)tmp;
   10613             : }
   10614             : 
   10615           8 : void fecr_box_del(GF_Box *s)
   10616             : {
   10617             :         FECReservoirBox *ptr = (FECReservoirBox *)s;
   10618           8 :         if (ptr == NULL) return;
   10619           8 :         if (ptr->entries) gf_free(ptr->entries);
   10620           8 :         gf_free(ptr);
   10621             : }
   10622             : 
   10623           2 : GF_Err fecr_box_read(GF_Box *s, GF_BitStream *bs)
   10624             : {
   10625             :         u32 i;
   10626             :         FECReservoirBox *ptr = (FECReservoirBox *)s;
   10627             : 
   10628           2 :         ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
   10629           2 :         ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
   10630             : 
   10631           2 :         ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * (ptr->version ? 8 : 6) );
   10632           2 :         GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FECReservoirEntry);
   10633           2 :         if (!ptr->entries) return GF_OUT_OF_MEM;
   10634             : 
   10635           0 :         for (i=0; i<ptr->nb_entries; i++) {
   10636           0 :                 ptr->entries[i].item_id = gf_bs_read_int(bs, ptr->version ? 32 : 16);
   10637           0 :                 ptr->entries[i].symbol_count = gf_bs_read_u32(bs);
   10638             :         }
   10639             :         return GF_OK;
   10640             : }
   10641             : 
   10642             : 
   10643             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10644             : 
   10645           2 : GF_Err fecr_box_write(GF_Box *s, GF_BitStream *bs)
   10646             : {
   10647             :         GF_Err e;
   10648             :         u32 i;
   10649             :         FECReservoirBox *ptr = (FECReservoirBox *) s;
   10650           2 :         if (!s) return GF_BAD_PARAM;
   10651           2 :         e = gf_isom_full_box_write(s, bs);
   10652           2 :         if (e) return e;
   10653             : 
   10654           2 :         gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
   10655           2 :         for (i=0; i<ptr->nb_entries; i++) {
   10656           0 :                 gf_bs_write_int(bs, ptr->entries[i].item_id, ptr->version ? 32 : 16);
   10657           0 :                 gf_bs_write_u32(bs, ptr->entries[i].symbol_count);
   10658             :         }
   10659             :         return GF_OK;
   10660             : }
   10661             : 
   10662           2 : GF_Err fecr_box_size(GF_Box *s)
   10663             : {
   10664             :         FECReservoirBox *ptr = (FECReservoirBox *)s;
   10665           2 :         ptr->size += (ptr->version ? 4 : 2) +  ptr->nb_entries * (ptr->version ? 8 : 6);
   10666           2 :         return GF_OK;
   10667             : }
   10668             : 
   10669             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10670             : 
   10671             : 
   10672             : 
   10673           3 : GF_Box *segr_box_new()
   10674             : {
   10675           6 :         ISOM_DECL_BOX_ALLOC(FDSessionGroupBox, GF_ISOM_BOX_TYPE_SEGR);
   10676           3 :         return (GF_Box *)tmp;
   10677             : }
   10678             : 
   10679           3 : void segr_box_del(GF_Box *s)
   10680             : {
   10681             :         u32 i;
   10682             :         FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
   10683           3 :         if (ptr == NULL) return;
   10684           0 :         for (i=0; i<ptr->num_session_groups; i++) {
   10685           0 :                 if (ptr->session_groups[i].group_ids) gf_free(ptr->session_groups[i].group_ids);
   10686           0 :                 if (ptr->session_groups[i].channels) gf_free(ptr->session_groups[i].channels);
   10687             :         }
   10688           3 :         if (ptr->session_groups) gf_free(ptr->session_groups);
   10689           3 :         gf_free(ptr);
   10690             : }
   10691             : 
   10692           1 : GF_Err segr_box_read(GF_Box *s, GF_BitStream *bs)
   10693             : {
   10694             :         u32 i, k;
   10695             :         FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
   10696             : 
   10697           1 :         ISOM_DECREASE_SIZE(ptr, 2);
   10698           1 :         ptr->num_session_groups = gf_bs_read_u16(bs);
   10699           1 :         if (ptr->size < ptr->num_session_groups) {
   10700           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in segr\n", ptr->num_session_groups));
   10701           0 :                 ptr->num_session_groups = 0;
   10702           0 :                 return GF_ISOM_INVALID_FILE;
   10703             :         }
   10704             : 
   10705           1 :         GF_SAFE_ALLOC_N(ptr->session_groups, ptr->num_session_groups, SessionGroupEntry);
   10706           1 :         if (!ptr->session_groups) return GF_OUT_OF_MEM;
   10707             : 
   10708           0 :         for (i=0; i<ptr->num_session_groups; i++) {
   10709           0 :                 ptr->session_groups[i].nb_groups = gf_bs_read_u8(bs);
   10710           0 :                 ISOM_DECREASE_SIZE(ptr, 1);
   10711             : 
   10712           0 :                 ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_groups*4);
   10713             : 
   10714           0 :                 GF_SAFE_ALLOC_N(ptr->session_groups[i].group_ids, ptr->session_groups[i].nb_groups, u32);
   10715           0 :                 if (!ptr->session_groups[i].group_ids) return GF_OUT_OF_MEM;
   10716             : 
   10717           0 :                 for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
   10718           0 :                         ptr->session_groups[i].group_ids[k] = gf_bs_read_u32(bs);
   10719             :                 }
   10720             : 
   10721           0 :                 ptr->session_groups[i].nb_channels = gf_bs_read_u16(bs);
   10722           0 :                 ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_channels*4);
   10723             : 
   10724           0 :                 GF_SAFE_ALLOC_N(ptr->session_groups[i].channels, ptr->session_groups[i].nb_channels, u32);
   10725           0 :                 if (!ptr->session_groups[i].channels) return GF_OUT_OF_MEM;
   10726             : 
   10727           0 :                 for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
   10728           0 :                         ptr->session_groups[i].channels[k] = gf_bs_read_u32(bs);
   10729             :                 }
   10730             :         }
   10731             :         return GF_OK;
   10732             : }
   10733             : 
   10734             : 
   10735             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10736             : 
   10737           1 : GF_Err segr_box_write(GF_Box *s, GF_BitStream *bs)
   10738             : {
   10739             :         u32 i, k;
   10740             :         GF_Err e;
   10741             :         FDSessionGroupBox *ptr = (FDSessionGroupBox *) s;
   10742           1 :         if (!s) return GF_BAD_PARAM;
   10743             : 
   10744           1 :         e = gf_isom_box_write_header(s, bs);
   10745           1 :         if (e) return e;
   10746             : 
   10747           1 :         gf_bs_write_u16(bs, ptr->num_session_groups);
   10748           1 :         for (i=0; i<ptr->num_session_groups; i++) {
   10749           0 :                 gf_bs_write_u8(bs, ptr->session_groups[i].nb_groups);
   10750           0 :                 for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
   10751           0 :                         gf_bs_write_u32(bs, ptr->session_groups[i].group_ids[k]);
   10752             :                 }
   10753             : 
   10754           0 :                 gf_bs_write_u16(bs, ptr->session_groups[i].nb_channels);
   10755           0 :                 for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
   10756           0 :                         gf_bs_write_u32(bs, ptr->session_groups[i].channels[k]);
   10757             :                 }
   10758             :         }
   10759             :         return GF_OK;
   10760             : }
   10761             : 
   10762           1 : GF_Err segr_box_size(GF_Box *s)
   10763             : {
   10764             :         u32 i;
   10765             :         FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
   10766             : 
   10767           1 :         ptr->size += 2;
   10768             : 
   10769           1 :         for (i=0; i<ptr->num_session_groups; i++) {
   10770           0 :                 ptr->size += 1 + 4*ptr->session_groups[i].nb_groups;
   10771           0 :                 ptr->size += 2 + 4*ptr->session_groups[i].nb_channels;
   10772             :         }
   10773           1 :         return GF_OK;
   10774             : }
   10775             : 
   10776             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10777             : 
   10778             : 
   10779           3 : GF_Box *gitn_box_new()
   10780             : {
   10781           6 :         ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN);
   10782           3 :         return (GF_Box *)tmp;
   10783             : }
   10784             : 
   10785           3 : void gitn_box_del(GF_Box *s)
   10786             : {
   10787             :         u32 i;
   10788             :         GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
   10789           3 :         if (ptr == NULL) return;
   10790           0 :         for (i=0; i<ptr->nb_entries; i++) {
   10791           0 :                 if (ptr->entries[i].name) gf_free(ptr->entries[i].name);
   10792             :         }
   10793           3 :         if (ptr->entries) gf_free(ptr->entries);
   10794           3 :         gf_free(ptr);
   10795             : }
   10796             : 
   10797           1 : GF_Err gitn_box_read(GF_Box *s, GF_BitStream *bs)
   10798             : {
   10799             :         u32 i;
   10800             :         GF_Err e;
   10801             :         GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
   10802             : 
   10803           1 :         ISOM_DECREASE_SIZE(ptr, 2);
   10804           1 :         ptr->nb_entries = gf_bs_read_u16(bs);
   10805           1 :         if (ptr->size / 4 < ptr->nb_entries)
   10806             :                 return GF_ISOM_INVALID_FILE;
   10807             : 
   10808           1 :         GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, GroupIdNameEntry);
   10809           1 :         if (!ptr->entries) return GF_OUT_OF_MEM;
   10810             : 
   10811           0 :         for (i=0; i<ptr->nb_entries; i++) {
   10812           0 :                 ISOM_DECREASE_SIZE(ptr, 4);
   10813           0 :                 ptr->entries[i].group_id = gf_bs_read_u32(bs);
   10814             : 
   10815           0 :                 e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->entries[i].name);
   10816           0 :                 if (e) return e;
   10817             :         }
   10818             :         return GF_OK;
   10819             : }
   10820             : 
   10821             : 
   10822             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10823             : 
   10824           1 : GF_Err gitn_box_write(GF_Box *s, GF_BitStream *bs)
   10825             : {
   10826             :         GF_Err e;
   10827             :         u32 i;
   10828             :         GroupIdToNameBox *ptr = (GroupIdToNameBox *) s;
   10829           1 :         if (!s) return GF_BAD_PARAM;
   10830           1 :         e = gf_isom_full_box_write(s, bs);
   10831           1 :         if (e) return e;
   10832             : 
   10833           1 :         gf_bs_write_u16(bs, ptr->nb_entries);
   10834           1 :         for (i=0; i<ptr->nb_entries; i++) {
   10835           0 :                 gf_bs_write_u32(bs, ptr->entries[i].group_id);
   10836           0 :                 if (ptr->entries[i].name) gf_bs_write_data(bs, ptr->entries[i].name, (u32)strlen(ptr->entries[i].name) );
   10837           0 :                 gf_bs_write_u8(bs, 0);
   10838             :         }
   10839             :         return GF_OK;
   10840             : }
   10841             : 
   10842           1 : GF_Err gitn_box_size(GF_Box *s)
   10843             : {
   10844             :         u32 i;
   10845             :         GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
   10846           1 :         ptr->size += 2;
   10847             : 
   10848           1 :         for (i=0; i<ptr->nb_entries; i++) {
   10849           0 :                 ptr->size += 5;
   10850           0 :                 if (ptr->entries[i].name) ptr->size += strlen(ptr->entries[i].name);
   10851             :         }
   10852           1 :         return GF_OK;
   10853             : }
   10854             : 
   10855             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10856             : 
   10857             : #ifndef GPAC_DISABLE_ISOM_HINTING
   10858             : 
   10859           3 : GF_Box *fdpa_box_new()
   10860             : {
   10861           6 :         ISOM_DECL_BOX_ALLOC(GF_FDpacketBox, GF_ISOM_BOX_TYPE_FDPA);
   10862           3 :         return (GF_Box *)tmp;
   10863             : }
   10864             : 
   10865           3 : void fdpa_box_del(GF_Box *s)
   10866             : {
   10867             :         u32 i;
   10868             :         GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
   10869           3 :         if (ptr == NULL) return;
   10870             : 
   10871           3 :         if (ptr->headers) {
   10872           0 :                 for (i=0; i<ptr->header_ext_count; i++) {
   10873           0 :                         if (ptr->headers[i].data) gf_free(ptr->headers[i].data);
   10874             :                 }
   10875           1 :                 gf_free(ptr->headers);
   10876             :         }
   10877           3 :         gf_free(ptr);
   10878             : }
   10879             : 
   10880           1 : GF_Err fdpa_box_read(GF_Box *s, GF_BitStream *bs)
   10881             : {
   10882             :         u32 i;
   10883             :         GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
   10884             : 
   10885           1 :         ISOM_DECREASE_SIZE(ptr, 3);
   10886           1 :         ptr->info.sender_current_time_present = gf_bs_read_int(bs, 1);
   10887           1 :         ptr->info.expected_residual_time_present = gf_bs_read_int(bs, 1);
   10888           1 :         ptr->info.session_close_bit = gf_bs_read_int(bs, 1);
   10889           1 :         ptr->info.object_close_bit = gf_bs_read_int(bs, 1);
   10890           1 :         gf_bs_read_int(bs, 4);
   10891           1 :         ptr->info.transport_object_identifier = gf_bs_read_u16(bs);
   10892           1 :         ISOM_DECREASE_SIZE(ptr, 2);
   10893           1 :         ptr->header_ext_count = gf_bs_read_u16(bs);
   10894           1 :         if (ptr->size / 2 < ptr->header_ext_count) {
   10895           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fdpa\n", ptr->header_ext_count));
   10896             :                 return GF_ISOM_INVALID_FILE;
   10897             :         }
   10898             : 
   10899           1 :         GF_SAFE_ALLOC_N(ptr->headers, ptr->header_ext_count, GF_LCTheaderExtension);
   10900           1 :         if (!ptr->headers) return GF_OUT_OF_MEM;
   10901             : 
   10902           0 :         for (i=0; i<ptr->header_ext_count; i++) {
   10903           0 :                 ptr->headers[i].header_extension_type = gf_bs_read_u8(bs);
   10904           0 :                 ISOM_DECREASE_SIZE(ptr, 1);
   10905             : 
   10906           0 :                 if (ptr->headers[i].header_extension_type > 127) {
   10907           0 :                         ISOM_DECREASE_SIZE(ptr, 3);
   10908           0 :                         gf_bs_read_data(bs, (char *) ptr->headers[i].content, 3);
   10909             :                 } else {
   10910           0 :                         ISOM_DECREASE_SIZE(ptr, 1);
   10911           0 :                         ptr->headers[i].data_length = gf_bs_read_u8(bs);
   10912           0 :                         if (ptr->headers[i].data_length) {
   10913           0 :                                 ptr->headers[i].data_length = 4*ptr->headers[i].data_length - 2;
   10914           0 :                                 if (ptr->size < sizeof(char) * ptr->headers[i].data_length)
   10915             :                                     return GF_ISOM_INVALID_FILE;
   10916           0 :                                 ptr->headers[i].data = gf_malloc(sizeof(char) * ptr->headers[i].data_length);
   10917           0 :                                 if (!ptr->headers[i].data) return GF_OUT_OF_MEM;
   10918             : 
   10919           0 :                                 ISOM_DECREASE_SIZE(ptr, ptr->headers[i].data_length);
   10920           0 :                                 gf_bs_read_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
   10921             :                         }
   10922             :                 }
   10923             :         }
   10924             :         return GF_OK;
   10925             : }
   10926             : 
   10927             : #ifndef GPAC_DISABLE_ISOM_WRITE
   10928             : 
   10929           1 : GF_Err fdpa_box_write(GF_Box *s, GF_BitStream *bs)
   10930             : {
   10931             :         GF_Err e;
   10932             :         u32 i;
   10933             :         GF_FDpacketBox *ptr = (GF_FDpacketBox *) s;
   10934           1 :         if (!s) return GF_BAD_PARAM;
   10935             : 
   10936           1 :         e = gf_isom_box_write_header(s, bs);
   10937           1 :         if (e) return e;
   10938             : 
   10939           1 :         gf_bs_write_int(bs, ptr->info.sender_current_time_present, 1);
   10940           1 :         gf_bs_write_int(bs, ptr->info.expected_residual_time_present, 1);
   10941           1 :         gf_bs_write_int(bs, ptr->info.session_close_bit, 1);
   10942           1 :         gf_bs_write_int(bs, ptr->info.object_close_bit, 1);
   10943           1 :         gf_bs_write_int(bs, 0, 4);
   10944           1 :         gf_bs_write_u16(bs, ptr->info.transport_object_identifier);
   10945           1 :         gf_bs_write_u16(bs, ptr->header_ext_count);
   10946           1 :         for (i=0; i<ptr->header_ext_count; i++) {
   10947           0 :                 gf_bs_write_u8(bs, ptr->headers[i].header_extension_type);
   10948           0 :                 if (ptr->headers[i].header_extension_type > 127) {
   10949           0 :                         gf_bs_write_data(bs, (const char *) ptr->headers[i].content, 3);
   10950             :                 } else {
   10951           0 :                         gf_bs_write_u8(bs, ptr->headers[i].data_length ? (ptr->headers[i].data_length+2)/4 : 0);
   10952           0 :                         if (ptr->headers[i].data_length) {
   10953           0 :                                 gf_bs_write_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
   10954             :                         }
   10955             :                 }
   10956             :         }
   10957             :         return GF_OK;
   10958             : }
   10959             : 
   10960           1 : GF_Err fdpa_box_size(GF_Box *s)
   10961             : {
   10962             :         u32 i;
   10963             :         GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
   10964             : 
   10965           1 :         ptr->size += 5;
   10966             : 
   10967           1 :         for (i=0; i<ptr->header_ext_count; i++) {
   10968           0 :                 ptr->size += 1;
   10969           0 :                 if (ptr->headers[i].header_extension_type > 127) {
   10970           0 :                         ptr->size += 3;
   10971             :                 } else {
   10972           0 :                         ptr->size += 1 + ptr->headers[i].data_length;
   10973             :                 }
   10974             :         }
   10975           1 :         return GF_OK;
   10976             : }
   10977             : 
   10978             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   10979             : 
   10980             : 
   10981           3 : GF_Box *extr_box_new()
   10982             : {
   10983           6 :         ISOM_DECL_BOX_ALLOC(GF_ExtraDataBox, GF_ISOM_BOX_TYPE_EXTR);
   10984           3 :         return (GF_Box *)tmp;
   10985             : }
   10986             : 
   10987           3 : void extr_box_del(GF_Box *s)
   10988             : {
   10989             :         GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
   10990           3 :         if (ptr == NULL) return;
   10991           3 :         if (ptr->feci) gf_isom_box_del((GF_Box*)ptr->feci);
   10992           3 :         if (ptr->data) gf_free(ptr->data);
   10993           3 :         gf_free(ptr);
   10994             : }
   10995             : 
   10996           1 : GF_Err extr_box_read(GF_Box *s, GF_BitStream *bs)
   10997             : {
   10998             :         GF_Err e;
   10999             :         GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
   11000             : 
   11001           1 :         e = gf_isom_box_parse((GF_Box**) &ptr->feci, bs);
   11002           1 :         if (e) return e;
   11003           0 :         if (!ptr->feci || ptr->feci->size > ptr->size) return GF_ISOM_INVALID_MEDIA;
   11004           0 :         ptr->data_length = (u32) (ptr->size - ptr->feci->size);
   11005           0 :         ptr->data = gf_malloc(sizeof(char)*ptr->data_length);
   11006           0 :         if (!ptr->data) return GF_OUT_OF_MEM;
   11007           0 :         gf_bs_read_data(bs, ptr->data, ptr->data_length);
   11008             : 
   11009           0 :         return GF_OK;
   11010             : }
   11011             : 
   11012             : 
   11013             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11014             : 
   11015           1 : GF_Err extr_box_write(GF_Box *s, GF_BitStream *bs)
   11016             : {
   11017             :         GF_Err e;
   11018             :         GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
   11019           1 :         if (!s) return GF_BAD_PARAM;
   11020             : 
   11021           1 :         e = gf_isom_box_write_header(s, bs);
   11022           1 :         if (e) return e;
   11023             : 
   11024           1 :         if (ptr->feci) {
   11025           0 :                 e = gf_isom_box_write((GF_Box *)ptr->feci, bs);
   11026           0 :                 if (e) return e;
   11027             :         }
   11028           1 :         gf_bs_write_data(bs, ptr->data, ptr->data_length);
   11029           1 :         return GF_OK;
   11030             : }
   11031             : 
   11032           1 : GF_Err extr_box_size(GF_Box *s)
   11033             : {
   11034             :         GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
   11035           1 :         ptr->size += ptr->data_length;
   11036           1 :         if (ptr->feci) {
   11037           0 :                 GF_Err e = gf_isom_box_size((GF_Box*)ptr->feci);
   11038           0 :                 if (e) return e;
   11039           0 :                 ptr->size += ptr->feci->size;
   11040             :         }
   11041             :         return GF_OK;
   11042             : }
   11043             : 
   11044             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11045             : 
   11046             : 
   11047             : 
   11048           3 : GF_Box *fdsa_box_new()
   11049             : {
   11050           6 :         ISOM_DECL_BOX_ALLOC(GF_HintSample, GF_ISOM_BOX_TYPE_FDSA);
   11051             :         if (!tmp) return NULL;
   11052           3 :         tmp->packetTable = gf_list_new();
   11053           3 :         tmp->hint_subtype = GF_ISOM_BOX_TYPE_FDP_STSD;
   11054           3 :         return (GF_Box*)tmp;
   11055             : }
   11056             : 
   11057           3 : void fdsa_box_del(GF_Box *s)
   11058             : {
   11059             :         GF_HintSample *ptr = (GF_HintSample *)s;
   11060           3 :         gf_list_del(ptr->packetTable);
   11061           3 :         gf_free(ptr);
   11062           3 : }
   11063             : 
   11064           0 : GF_Err fdsa_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
   11065             : {
   11066             :         GF_HintSample *ptr = (GF_HintSample *)s;
   11067           0 :         switch(a->type) {
   11068           0 :         case GF_ISOM_BOX_TYPE_FDPA:
   11069           0 :                 BOX_FIELD_LIST_ASSIGN(packetTable)
   11070             :                 return GF_OK;
   11071           0 :         case GF_ISOM_BOX_TYPE_EXTR:
   11072           0 :                 BOX_FIELD_ASSIGN(extra_data, GF_ExtraDataBox)
   11073           0 :                 break;
   11074             :         }
   11075             :         return GF_OK;
   11076             : }
   11077           1 : GF_Err fdsa_box_read(GF_Box *s, GF_BitStream *bs)
   11078             : {
   11079           1 :         return gf_isom_box_array_read(s, bs);
   11080             : }
   11081             : 
   11082             : 
   11083             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11084             : 
   11085           1 : GF_Err fdsa_box_write(GF_Box *s, GF_BitStream *bs)
   11086             : {
   11087             :         GF_Err e;
   11088             :         GF_HintSample *ptr = (GF_HintSample *) s;
   11089           1 :         if (!s) return GF_BAD_PARAM;
   11090             : 
   11091           1 :         e = gf_isom_box_write_header(s, bs);
   11092           1 :         if (e) return e;
   11093             : 
   11094           1 :         e = gf_isom_box_array_write(s, ptr->packetTable, bs);
   11095           1 :         if (e) return e;
   11096           1 :         if (ptr->extra_data) {
   11097           0 :                 e = gf_isom_box_write((GF_Box *)ptr->extra_data, bs);
   11098           0 :                 if (e) return e;
   11099             :         }
   11100             :         return GF_OK;
   11101             : }
   11102             : 
   11103           1 : GF_Err fdsa_box_size(GF_Box *s)
   11104             : {
   11105           1 :         return GF_OK;
   11106             : }
   11107             : 
   11108             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11109             : 
   11110             : #endif /*GPAC_DISABLE_ISOM_HINTING*/
   11111             : 
   11112             : 
   11113           3 : void trik_box_del(GF_Box *s)
   11114             : {
   11115             :         GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
   11116           3 :         if (ptr == NULL) return;
   11117           3 :         if (ptr->entries) gf_free(ptr->entries);
   11118           3 :         gf_free(ptr);
   11119             : }
   11120             : 
   11121           1 : GF_Err trik_box_read(GF_Box *s,GF_BitStream *bs)
   11122             : {
   11123             :         u32 i;
   11124             :         GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
   11125           1 :         ptr->entry_count = (u32) ptr->size;
   11126           1 :         ptr->entries = (GF_TrickPlayBoxEntry *) gf_malloc(ptr->entry_count * sizeof(GF_TrickPlayBoxEntry) );
   11127           1 :         if (!ptr->entries) return GF_OUT_OF_MEM;
   11128             : 
   11129           0 :         for (i=0; i< ptr->entry_count; i++) {
   11130           0 :                 ptr->entries[i].pic_type = gf_bs_read_int(bs, 2);
   11131           0 :                 ptr->entries[i].dependency_level = gf_bs_read_int(bs, 6);
   11132             :         }
   11133             :         return GF_OK;
   11134             : }
   11135             : 
   11136           3 : GF_Box *trik_box_new()
   11137             : {
   11138           6 :         ISOM_DECL_BOX_ALLOC(GF_TrickPlayBox, GF_ISOM_BOX_TYPE_TRIK);
   11139           3 :         return (GF_Box *)tmp;
   11140             : }
   11141             : 
   11142             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11143             : 
   11144           1 : GF_Err trik_box_write(GF_Box *s, GF_BitStream *bs)
   11145             : {
   11146             :         GF_Err e;
   11147             :         u32 i;
   11148             :         GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
   11149             : 
   11150           1 :         e = gf_isom_full_box_write(s, bs);
   11151           1 :         if (e) return e;
   11152             : 
   11153           0 :         for (i=0; i < ptr->entry_count; i++ ) {
   11154           0 :                 gf_bs_write_int(bs, ptr->entries[i].pic_type, 2);
   11155           0 :                 gf_bs_write_int(bs, ptr->entries[i].dependency_level, 6);
   11156             :         }
   11157             :         return GF_OK;
   11158             : }
   11159             : 
   11160           1 : GF_Err trik_box_size(GF_Box *s)
   11161             : {
   11162             :         GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
   11163           1 :         ptr->size += 8 * ptr->entry_count;
   11164           1 :         return GF_OK;
   11165             : }
   11166             : 
   11167             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11168             : 
   11169             : 
   11170           3 : void bloc_box_del(GF_Box *s)
   11171             : {
   11172           3 :         gf_free(s);
   11173           3 : }
   11174             : 
   11175           1 : GF_Err bloc_box_read(GF_Box *s,GF_BitStream *bs)
   11176             : {
   11177             :         GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
   11178             : 
   11179           1 :         ISOM_DECREASE_SIZE(s, 256)
   11180           1 :         gf_bs_read_data(bs, (char *) ptr->baseLocation, 256);
   11181           1 :         ISOM_DECREASE_SIZE(s, 256)
   11182           1 :         gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256);
   11183           1 :         ISOM_DECREASE_SIZE(s, 512)
   11184           1 :         gf_bs_skip_bytes(bs, 512);
   11185           1 :         return GF_OK;
   11186             : }
   11187             : 
   11188           3 : GF_Box *bloc_box_new()
   11189             : {
   11190           6 :         ISOM_DECL_BOX_ALLOC(GF_BaseLocationBox, GF_ISOM_BOX_TYPE_TRIK);
   11191           3 :         return (GF_Box *)tmp;
   11192             : }
   11193             : 
   11194             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11195             : 
   11196           1 : GF_Err bloc_box_write(GF_Box *s, GF_BitStream *bs)
   11197             : {
   11198             :         GF_Err e;
   11199             :         u32 i;
   11200             :         GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
   11201             : 
   11202           1 :         e = gf_isom_full_box_write(s, bs);
   11203           1 :         if (e) return e;
   11204           1 :         gf_bs_write_data(bs, (const char *) ptr->baseLocation, 256);
   11205           1 :         gf_bs_write_data(bs, (const char *) ptr->basePurlLocation, 256);
   11206          65 :         for (i=0; i < 64; i++ ) {
   11207          64 :                 gf_bs_write_u64(bs, 0);
   11208             :         }
   11209             :         return GF_OK;
   11210             : }
   11211             : 
   11212           1 : GF_Err bloc_box_size(GF_Box *s)
   11213             : {
   11214           1 :         s->size += 1024;
   11215           1 :         return GF_OK;
   11216             : }
   11217             : 
   11218             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11219             : 
   11220           3 : void ainf_box_del(GF_Box *s)
   11221             : {
   11222             :         GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
   11223           3 :         if (ptr->APID) gf_free(ptr->APID);
   11224           3 :         gf_free(s);
   11225           3 : }
   11226             : 
   11227           1 : GF_Err ainf_box_read(GF_Box *s,GF_BitStream *bs)
   11228             : {
   11229             :         GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
   11230             : 
   11231           1 :         ISOM_DECREASE_SIZE(s, 4)
   11232           1 :         ptr->profile_version = gf_bs_read_u32(bs);
   11233           1 :         return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->APID);
   11234             : }
   11235             : 
   11236           3 : GF_Box *ainf_box_new()
   11237             : {
   11238           6 :         ISOM_DECL_BOX_ALLOC(GF_AssetInformationBox, GF_ISOM_BOX_TYPE_AINF);
   11239           3 :         return (GF_Box *)tmp;
   11240             : }
   11241             : 
   11242             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11243             : 
   11244           1 : GF_Err ainf_box_write(GF_Box *s, GF_BitStream *bs)
   11245             : {
   11246             :         GF_Err e;
   11247             :         GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
   11248             : 
   11249           1 :         e = gf_isom_full_box_write(s, bs);
   11250           1 :         if (e) return e;
   11251           1 :         gf_bs_write_u32(bs, ptr->profile_version);
   11252           1 :     if (ptr->APID)
   11253           0 :         gf_bs_write_data(bs, ptr->APID, (u32) strlen(ptr->APID) );
   11254           1 :     gf_bs_write_u8(bs, 0);
   11255           1 :         return GF_OK;
   11256             : }
   11257             : 
   11258           1 : GF_Err ainf_box_size(GF_Box *s)
   11259             : {
   11260             :         GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
   11261           1 :     s->size += 4 + (ptr->APID ? strlen(ptr->APID) : 0 ) + 1;
   11262           1 :         return GF_OK;
   11263             : }
   11264             : 
   11265             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11266             : 
   11267             : 
   11268           4 : void mhac_box_del(GF_Box *s)
   11269             : {
   11270             :         GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
   11271           4 :         if (ptr->mha_config) gf_free(ptr->mha_config);
   11272           4 :         gf_free(s);
   11273           4 : }
   11274             : 
   11275           1 : GF_Err mhac_box_read(GF_Box *s,GF_BitStream *bs)
   11276             : {
   11277             :         GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
   11278             : 
   11279           1 :         ISOM_DECREASE_SIZE(s, 5)
   11280           1 :         ptr->configuration_version = gf_bs_read_u8(bs);
   11281           1 :         ptr->mha_pl_indication = gf_bs_read_u8(bs);
   11282           1 :         ptr->reference_channel_layout = gf_bs_read_u8(bs);
   11283           1 :         ptr->mha_config_size = gf_bs_read_u16(bs);
   11284           1 :         if (ptr->mha_config_size) {
   11285           0 :                 ISOM_DECREASE_SIZE(s, ptr->mha_config_size)
   11286             : 
   11287           0 :                 ptr->mha_config = gf_malloc(sizeof(char)*ptr->mha_config_size);
   11288           0 :                 if (!ptr->mha_config) return GF_OUT_OF_MEM;
   11289             : 
   11290           0 :                 gf_bs_read_data(bs, ptr->mha_config, ptr->mha_config_size);
   11291             :         }
   11292             :         return GF_OK;
   11293             : }
   11294             : 
   11295           4 : GF_Box *mhac_box_new()
   11296             : {
   11297           8 :         ISOM_DECL_BOX_ALLOC(GF_MHAConfigBox, GF_ISOM_BOX_TYPE_MHAC);
   11298           4 :         tmp->configuration_version = 1;
   11299           4 :         return (GF_Box *)tmp;
   11300             : }
   11301             : 
   11302             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11303             : 
   11304           2 : GF_Err mhac_box_write(GF_Box *s, GF_BitStream *bs)
   11305             : {
   11306             :         GF_Err e;
   11307             :         GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
   11308             : 
   11309           2 :         e = gf_isom_box_write_header(s, bs);
   11310           2 :         if (e) return e;
   11311           2 :         gf_bs_write_u8(bs, ptr->configuration_version);
   11312           2 :         gf_bs_write_u8(bs, ptr->mha_pl_indication);
   11313           2 :         gf_bs_write_u8(bs, ptr->reference_channel_layout);
   11314           2 :         gf_bs_write_u16(bs, ptr->mha_config ? ptr->mha_config_size : 0);
   11315           2 :         if (ptr->mha_config && ptr->mha_config_size)
   11316           1 :                 gf_bs_write_data(bs, ptr->mha_config, ptr->mha_config_size);
   11317             : 
   11318             :         return GF_OK;
   11319             : }
   11320             : 
   11321           4 : GF_Err mhac_box_size(GF_Box *s)
   11322             : {
   11323             :         GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
   11324           4 :         s->size += 5;
   11325           4 :         if (ptr->mha_config_size && ptr->mha_config) s->size += ptr->mha_config_size;
   11326           4 :         return GF_OK;
   11327             : }
   11328             : 
   11329             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11330             : 
   11331           3 : void mhap_box_del(GF_Box *s)
   11332             : {
   11333             :         GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
   11334           3 :         if (ptr->compat_profiles) gf_free(ptr->compat_profiles);
   11335           3 :         gf_free(s);
   11336           3 : }
   11337             : 
   11338           1 : GF_Err mhap_box_read(GF_Box *s,GF_BitStream *bs)
   11339             : {
   11340             :         u32 i;
   11341             :         GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
   11342             : 
   11343           1 :         ISOM_DECREASE_SIZE(s, 1)
   11344           1 :         ptr->num_profiles = gf_bs_read_u8(bs);
   11345           1 :         if (!ptr->num_profiles) return GF_OK;
   11346             : 
   11347           0 :         ISOM_DECREASE_SIZE(s, ptr->num_profiles)
   11348           0 :         ptr->compat_profiles = gf_malloc(sizeof(u8) * ptr->num_profiles);
   11349           0 :         if (!ptr->compat_profiles) return GF_OUT_OF_MEM;
   11350           0 :         for (i=0; i<ptr->num_profiles; i++) {
   11351           0 :                 ptr->compat_profiles[i] = gf_bs_read_u8(bs);
   11352             :         }
   11353             :         return GF_OK;
   11354             : }
   11355             : 
   11356           3 : GF_Box *mhap_box_new()
   11357             : {
   11358           6 :         ISOM_DECL_BOX_ALLOC(GF_MHACompatibleProfilesBox, GF_ISOM_BOX_TYPE_MHAP);
   11359           3 :         return (GF_Box *)tmp;
   11360             : }
   11361             : 
   11362             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11363             : 
   11364           1 : GF_Err mhap_box_write(GF_Box *s, GF_BitStream *bs)
   11365             : {
   11366             :         u32 i;
   11367             :         GF_Err e;
   11368             :         GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
   11369             : 
   11370           1 :         e = gf_isom_box_write_header(s, bs);
   11371           1 :         if (e) return e;
   11372           1 :         gf_bs_write_u8(bs, ptr->num_profiles);
   11373           1 :         for (i=0; i<ptr->num_profiles; i++) {
   11374           0 :                 gf_bs_write_u8(bs, ptr->compat_profiles[i]);
   11375             :         }
   11376             :         return GF_OK;
   11377             : }
   11378             : 
   11379           1 : GF_Err mhap_box_size(GF_Box *s)
   11380             : {
   11381             :         GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
   11382           1 :         s->size += 1 + ptr->num_profiles;
   11383           1 :         return GF_OK;
   11384             : }
   11385             : 
   11386             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11387             : 
   11388             : 
   11389          32 : void jp2h_box_del(GF_Box *s)
   11390             : {
   11391          32 :         gf_free(s);
   11392          32 : }
   11393             : 
   11394          54 : GF_Err jp2h_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
   11395             : {
   11396             :         GF_J2KHeaderBox *ptr = (GF_J2KHeaderBox *)s;
   11397          54 :         switch(a->type) {
   11398          27 :         case GF_ISOM_BOX_TYPE_IHDR:
   11399          27 :                 BOX_FIELD_ASSIGN(ihdr, GF_J2KImageHeaderBox)
   11400          27 :                 return GF_OK;
   11401          27 :         case GF_ISOM_BOX_TYPE_COLR:
   11402          27 :                 BOX_FIELD_ASSIGN(colr, GF_ColourInformationBox)
   11403          27 :                 return GF_OK;
   11404             :         }
   11405             :         return GF_OK;
   11406             : }
   11407          28 : GF_Err jp2h_box_read(GF_Box *s,GF_BitStream *bs)
   11408             : {
   11409          28 :         return gf_isom_box_array_read_ex(s, bs, s->type);
   11410             : }
   11411             : 
   11412          32 : GF_Box *jp2h_box_new()
   11413             : {
   11414          64 :         ISOM_DECL_BOX_ALLOC(GF_J2KHeaderBox, GF_ISOM_BOX_TYPE_JP2H);
   11415          32 :         return (GF_Box *)tmp;
   11416             : }
   11417             : 
   11418             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11419             : 
   11420          17 : GF_Err jp2h_box_write(GF_Box *s, GF_BitStream *bs)
   11421             : {
   11422          17 :         return gf_isom_box_write_header(s, bs);
   11423             : }
   11424             : 
   11425          31 : GF_Err jp2h_box_size(GF_Box *s)
   11426             : {
   11427          31 :         return GF_OK;
   11428             : }
   11429             : 
   11430             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11431             : 
   11432             : 
   11433          30 : void ihdr_box_del(GF_Box *s)
   11434             : {
   11435          30 :         gf_free(s);
   11436          30 : }
   11437             : 
   11438          28 : GF_Err ihdr_box_read(GF_Box *s,GF_BitStream *bs)
   11439             : {
   11440             :         GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;
   11441             : 
   11442          28 :         ISOM_DECREASE_SIZE(s, 14)
   11443             : 
   11444          28 :         ptr->height = gf_bs_read_u32(bs);
   11445          28 :         ptr->width = gf_bs_read_u32(bs);
   11446          28 :         ptr->nb_comp = gf_bs_read_u16(bs);
   11447          28 :         ptr->bpc = gf_bs_read_u8(bs);
   11448          28 :         ptr->Comp = gf_bs_read_u8(bs);
   11449          28 :         ptr->UnkC = gf_bs_read_u8(bs);
   11450          28 :         ptr->IPR = gf_bs_read_u8(bs);
   11451             : 
   11452          28 :         return GF_OK;
   11453             : }
   11454             : 
   11455          30 : GF_Box *ihdr_box_new()
   11456             : {
   11457          60 :         ISOM_DECL_BOX_ALLOC(GF_J2KImageHeaderBox, GF_ISOM_BOX_TYPE_IHDR);
   11458          30 :         return (GF_Box *)tmp;
   11459             : }
   11460             : 
   11461             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11462             : 
   11463          24 : GF_Err ihdr_box_write(GF_Box *s, GF_BitStream *bs)
   11464             : {
   11465             :         GF_Err e;
   11466             :         GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;
   11467             : 
   11468          24 :         e = gf_isom_box_write_header(s, bs);
   11469          24 :         if (e) return e;
   11470             : 
   11471          24 :         gf_bs_write_u32(bs, ptr->height);
   11472          24 :         gf_bs_write_u32(bs, ptr->width);
   11473          24 :         gf_bs_write_u16(bs, ptr->nb_comp);
   11474          24 :         gf_bs_write_u8(bs, ptr->bpc);
   11475          24 :         gf_bs_write_u8(bs, ptr->Comp);
   11476          24 :         gf_bs_write_u8(bs, ptr->UnkC);
   11477          24 :         gf_bs_write_u8(bs, ptr->IPR);
   11478          24 :         return GF_OK;
   11479             : }
   11480             : 
   11481          31 : GF_Err ihdr_box_size(GF_Box *s)
   11482             : {
   11483          31 :         s->size += 14;
   11484          31 :         return GF_OK;
   11485             : }
   11486             : 
   11487             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11488             : 
   11489             : 
   11490             : /* Dolby Vision */
   11491             : 
   11492           7 : GF_Box *dvcC_box_new()
   11493             : {
   11494           7 :         GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox));
   11495           7 :         if (tmp == NULL) return NULL;
   11496             :         memset(tmp, 0, sizeof(GF_DOVIConfigurationBox));
   11497           7 :         tmp->type = GF_ISOM_BOX_TYPE_DVCC;
   11498           7 :         return (GF_Box *)tmp;
   11499             : }
   11500             : 
   11501           7 : void dvcC_box_del(GF_Box *s)
   11502             : {
   11503             :         GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
   11504           7 :         gf_free(ptr);
   11505           7 : }
   11506             : 
   11507           4 : GF_Err dvcC_box_read(GF_Box *s, GF_BitStream *bs)
   11508             : {
   11509             :         u32 i;
   11510             :         u32 data[5];
   11511             :         GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;
   11512             : 
   11513             :         //GF_DOVIDecoderConfigurationRecord
   11514           4 :         ISOM_DECREASE_SIZE(ptr, 24)
   11515           4 :         ptr->DOVIConfig.dv_version_major = gf_bs_read_u8(bs);
   11516           4 :         ptr->DOVIConfig.dv_version_minor = gf_bs_read_u8(bs);
   11517           4 :         ptr->DOVIConfig.dv_profile = gf_bs_read_int(bs, 7);
   11518           4 :         ptr->DOVIConfig.dv_level = gf_bs_read_int(bs, 6);
   11519           4 :         ptr->DOVIConfig.rpu_present_flag = gf_bs_read_int(bs, 1);
   11520           4 :         ptr->DOVIConfig.el_present_flag = gf_bs_read_int(bs, 1);
   11521           4 :         ptr->DOVIConfig.bl_present_flag = gf_bs_read_int(bs, 1);
   11522             : 
   11523             :         memset(data, 0, sizeof(u32)*5);
   11524           4 :         gf_bs_read_data(bs, (char*)data, 20);
   11525          24 :         for (i = 0; i < 5; ++i) {
   11526          20 :                 if (data[i] != 0) {
   11527           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bytes are not zero\n"));
   11528             :                         //return GF_ISOM_INVALID_FILE;
   11529             :                 }
   11530             :         }
   11531             :         return GF_OK;
   11532             : }
   11533             : 
   11534             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11535           4 : GF_Err dvcC_box_write(GF_Box *s, GF_BitStream *bs)
   11536             : {
   11537             :         GF_Err e;
   11538             :         GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *) s;
   11539           4 :         if (!s) return GF_BAD_PARAM;
   11540             : 
   11541           4 :         e = gf_isom_box_write_header(s, bs);
   11542           4 :         if (e) return e;
   11543             : 
   11544             :         //GF_DOVIDecoderConfigurationRecord
   11545           4 :         gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_major);
   11546           4 :         gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_minor);
   11547           4 :         gf_bs_write_int(bs, ptr->DOVIConfig.dv_profile, 7);
   11548           4 :         gf_bs_write_int(bs, ptr->DOVIConfig.dv_level, 6);
   11549           4 :         gf_bs_write_int(bs, ptr->DOVIConfig.rpu_present_flag, 1);
   11550           4 :         gf_bs_write_int(bs, ptr->DOVIConfig.el_present_flag, 1);
   11551           4 :         gf_bs_write_int(bs, ptr->DOVIConfig.bl_present_flag, 1);
   11552           4 :     gf_bs_write_u32(bs, 0);
   11553           4 :     gf_bs_write_u32(bs, 0);
   11554           4 :     gf_bs_write_u32(bs, 0);
   11555           4 :     gf_bs_write_u32(bs, 0);
   11556           4 :     gf_bs_write_u32(bs, 0);
   11557             : 
   11558           4 :         return GF_OK;
   11559             : }
   11560             : 
   11561           6 : GF_Err dvcC_box_size(GF_Box *s)
   11562             : {
   11563             :         GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;
   11564             : 
   11565           6 :         ptr->size += 24;
   11566           6 :         return GF_OK;
   11567             : }
   11568             : 
   11569             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11570             : 
   11571             : 
   11572          16 : GF_Box *dOps_box_new()
   11573             : {
   11574          32 :         ISOM_DECL_BOX_ALLOC(GF_OpusSpecificBox, GF_ISOM_BOX_TYPE_DOPS);
   11575          16 :         return (GF_Box *)tmp;
   11576             : }
   11577             : 
   11578          16 : void dOps_box_del(GF_Box *s)
   11579             : {
   11580             :         GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
   11581          16 :         if (ptr) gf_free(ptr);
   11582          16 : }
   11583             : 
   11584           9 : GF_Err dOps_box_read(GF_Box *s, GF_BitStream *bs)
   11585             : {
   11586             :         GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
   11587           9 :         ptr->version = gf_bs_read_u8(bs);
   11588           9 :         ptr->OutputChannelCount = gf_bs_read_u8(bs);
   11589           9 :         ptr->PreSkip = gf_bs_read_u16(bs);
   11590           9 :         ptr->InputSampleRate = gf_bs_read_u32(bs);
   11591           9 :         ptr->OutputGain = gf_bs_read_u16(bs);
   11592           9 :         ptr->ChannelMappingFamily = gf_bs_read_u8(bs);
   11593           9 :         ISOM_DECREASE_SIZE(ptr, 11)
   11594           9 :         if (ptr->size) {
   11595           8 :                 ISOM_DECREASE_SIZE(ptr, 2+ptr->OutputChannelCount);
   11596           8 :                 ptr->StreamCount = gf_bs_read_u8(bs);
   11597           8 :                 ptr->CoupledCount = gf_bs_read_u8(bs);
   11598           8 :                 gf_bs_read_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount);
   11599             :         }
   11600             :         return GF_OK;
   11601             : }
   11602             : 
   11603             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11604             : 
   11605          10 : GF_Err dOps_box_write(GF_Box *s, GF_BitStream *bs)
   11606             : {
   11607             :         GF_Err e;
   11608             :         GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
   11609          10 :         if (!s) return GF_BAD_PARAM;
   11610          10 :         e = gf_isom_box_write_header(s, bs);
   11611          10 :         if (e) return e;
   11612          10 :         gf_bs_write_u8(bs, ptr->version);
   11613          10 :         gf_bs_write_u8(bs, ptr->OutputChannelCount);
   11614          10 :         gf_bs_write_u16(bs, ptr->PreSkip);
   11615          10 :         gf_bs_write_u32(bs, ptr->InputSampleRate);
   11616          10 :         gf_bs_write_u16(bs, ptr->OutputGain);
   11617          10 :         gf_bs_write_u8(bs, ptr->ChannelMappingFamily);
   11618          10 :         if (ptr->ChannelMappingFamily) {
   11619           9 :                 gf_bs_write_u8(bs, ptr->StreamCount);
   11620           9 :                 gf_bs_write_u8(bs, ptr->CoupledCount);
   11621           9 :                 gf_bs_write_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount);
   11622             :         }
   11623             :         return GF_OK;
   11624             : }
   11625             : 
   11626          14 : GF_Err dOps_box_size(GF_Box *s)
   11627             : {
   11628             :         GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
   11629          14 :         ptr->size += 11;
   11630          14 :         if (ptr->ChannelMappingFamily)
   11631          13 :                 ptr->size += 2 + ptr->OutputChannelCount;
   11632             : 
   11633          14 :         return GF_OK;
   11634             : }
   11635             : 
   11636             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11637             : 
   11638             : 
   11639          10 : void dfla_box_del(GF_Box *s)
   11640             : {
   11641             :         GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
   11642          10 :         if (ptr->data) gf_free(ptr->data);
   11643          10 :         gf_free(ptr);
   11644          10 : }
   11645             : 
   11646           6 : GF_Err dfla_box_read(GF_Box *s,GF_BitStream *bs)
   11647             : {
   11648             :         GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
   11649           6 :         ptr->dataSize = (u32) ptr->size;
   11650           6 :         ptr->size=0;
   11651           6 :         ptr->data = gf_malloc(ptr->dataSize);
   11652           6 :         gf_bs_read_data(bs, ptr->data, ptr->dataSize);
   11653           6 :         return GF_OK;
   11654             : }
   11655             : 
   11656          10 : GF_Box *dfla_box_new()
   11657             : {
   11658          20 :         ISOM_DECL_BOX_ALLOC(GF_FLACConfigBox, GF_ISOM_BOX_TYPE_DFLA);
   11659          10 :         return (GF_Box *)tmp;
   11660             : }
   11661             : 
   11662             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11663             : 
   11664           5 : GF_Err dfla_box_write(GF_Box *s, GF_BitStream *bs)
   11665             : {
   11666             :         GF_Err e;
   11667             :         GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
   11668           5 :         e = gf_isom_full_box_write(s, bs);
   11669           5 :         if (e) return e;
   11670           5 :         gf_bs_write_data(bs, ptr->data, ptr->dataSize);
   11671           5 :         return GF_OK;
   11672             : }
   11673             : 
   11674           9 : GF_Err dfla_box_size(GF_Box *s)
   11675             : {
   11676             :         GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
   11677           9 :         ptr->size += ptr->dataSize;
   11678           9 :         return GF_OK;
   11679             : }
   11680             : 
   11681             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11682             : 
   11683             : 
   11684             : 
   11685           3 : void mvcg_box_del(GF_Box *s)
   11686             : {
   11687             :         GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
   11688           3 :         if (ptr->entries) gf_free(ptr->entries);
   11689           3 :         gf_free(ptr);
   11690           3 : }
   11691             : 
   11692           1 : GF_Err mvcg_box_read(GF_Box *s,GF_BitStream *bs)
   11693             : {
   11694             :         u32 i;
   11695             :         GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
   11696           1 :         ISOM_DECREASE_SIZE(s, 7)
   11697           1 :         ptr->multiview_group_id = gf_bs_read_u32(bs);
   11698           1 :         ptr->num_entries = gf_bs_read_u16(bs);
   11699           1 :         gf_bs_read_u8(bs);
   11700           1 :         ptr->entries = gf_malloc(ptr->num_entries * sizeof(MVCIEntry));
   11701           1 :         memset(ptr->entries, 0, ptr->num_entries * sizeof(MVCIEntry));
   11702           1 :         for (i=0; i<ptr->num_entries; i++) {
   11703           0 :                 ISOM_DECREASE_SIZE(s, 1)
   11704           0 :                 ptr->entries[i].entry_type = gf_bs_read_u8(bs);
   11705           0 :                 switch (ptr->entries[i].entry_type) {
   11706           0 :                 case 0:
   11707           0 :                         ISOM_DECREASE_SIZE(s, 4)
   11708           0 :                         ptr->entries[i].trackID = gf_bs_read_u32(bs);
   11709           0 :                         break;
   11710           0 :                 case 1:
   11711           0 :                         ISOM_DECREASE_SIZE(s, 6)
   11712           0 :                         ptr->entries[i].trackID = gf_bs_read_u32(bs);
   11713           0 :                         ptr->entries[i].tierID = gf_bs_read_u16(bs);
   11714           0 :                         break;
   11715           0 :                 case 2:
   11716           0 :                         ISOM_DECREASE_SIZE(s, 2)
   11717           0 :                         gf_bs_read_int(bs, 6);
   11718           0 :                         ptr->entries[i].output_view_id = gf_bs_read_int(bs, 10);
   11719           0 :                         break;
   11720           0 :                 case 3:
   11721           0 :                         ISOM_DECREASE_SIZE(s, 4)
   11722           0 :                         gf_bs_read_int(bs, 6)   ;
   11723           0 :                         ptr->entries[i].start_view_id = gf_bs_read_int(bs, 10);
   11724           0 :                         ptr->entries[i].view_count = gf_bs_read_u16(bs);
   11725           0 :                         break;
   11726             :                 }
   11727             :         }
   11728           1 :         return gf_isom_box_array_read(s, bs);
   11729             : }
   11730             : 
   11731           3 : GF_Box *mvcg_box_new()
   11732             : {
   11733           6 :         ISOM_DECL_BOX_ALLOC(GF_MultiviewGroupBox, GF_ISOM_BOX_TYPE_MVCG);
   11734           3 :         return (GF_Box *)tmp;
   11735             : }
   11736             : 
   11737             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11738             : 
   11739           1 : GF_Err mvcg_box_write(GF_Box *s, GF_BitStream *bs)
   11740             : {
   11741             :         GF_Err e;
   11742             :         u32 i;
   11743             :         GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
   11744           1 :         e = gf_isom_full_box_write(s, bs);
   11745           1 :         if (e) return e;
   11746             : 
   11747             : 
   11748           1 :         gf_bs_write_u32(bs, ptr->multiview_group_id);
   11749           1 :         gf_bs_write_u16(bs, ptr->num_entries);
   11750           1 :         gf_bs_write_u8(bs, 0);
   11751             : 
   11752           1 :         for (i=0; i<ptr->num_entries; i++) {
   11753           0 :                 gf_bs_write_u8(bs, ptr->entries[i].entry_type);
   11754           0 :                 switch (ptr->entries[i].entry_type) {
   11755           0 :                 case 0:
   11756           0 :                         gf_bs_write_u32(bs, ptr->entries[i].trackID);
   11757           0 :                         break;
   11758           0 :                 case 1:
   11759           0 :                         gf_bs_write_u32(bs, ptr->entries[i].trackID);
   11760           0 :                         gf_bs_write_u16(bs, ptr->entries[i].tierID);
   11761           0 :                         break;
   11762           0 :                 case 2:
   11763           0 :                         gf_bs_write_int(bs, 0, 6);
   11764           0 :                         gf_bs_write_int(bs, ptr->entries[i].output_view_id, 10);
   11765           0 :                         break;
   11766           0 :                 case 3:
   11767           0 :                         gf_bs_write_int(bs, 0, 6)       ;
   11768           0 :                         gf_bs_write_int(bs, ptr->entries[i].start_view_id, 10);
   11769           0 :                         gf_bs_write_u16(bs, ptr->entries[i].view_count);
   11770           0 :                         break;
   11771             :                 }
   11772             :         }
   11773             :         return GF_OK;
   11774             : }
   11775             : 
   11776           1 : GF_Err mvcg_box_size(GF_Box *s)
   11777             : {
   11778             :         u32 i;
   11779             :         GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
   11780             : 
   11781           1 :         ptr->size += 7;
   11782           1 :         for (i=0; i<ptr->num_entries; i++) {
   11783           0 :                 switch (ptr->entries[i].entry_type) {
   11784           0 :                 case 0:
   11785           0 :                         ptr->size += 1 + 4;
   11786           0 :                         break;
   11787           0 :                 case 1:
   11788           0 :                         ptr->size += 1 + 6;
   11789           0 :                         break;
   11790           0 :                 case 2:
   11791           0 :                         ptr->size += 1 + 2;
   11792           0 :                         break;
   11793           0 :                 case 3:
   11794           0 :                         ptr->size += 1 + 4;
   11795           0 :                         break;
   11796             :                 }
   11797             :         }
   11798           1 :         return GF_OK;
   11799             : }
   11800             : 
   11801             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11802             : 
   11803             : 
   11804           3 : void vwid_box_del(GF_Box *s)
   11805             : {
   11806             :         u32 i;
   11807             :         GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
   11808           3 :         if (ptr->views) {
   11809           0 :                 for (i=0; i<ptr->num_views; i++) {
   11810           0 :                         if (ptr->views[i].view_refs)
   11811           0 :                                 gf_free(ptr->views[i].view_refs);
   11812             :                 }
   11813           1 :                 gf_free(ptr->views);
   11814             :         }
   11815           3 :         gf_free(ptr);
   11816           3 : }
   11817             : 
   11818           1 : GF_Err vwid_box_read(GF_Box *s,GF_BitStream *bs)
   11819             : {
   11820             :         u32 i;
   11821             :         GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
   11822           1 :         ISOM_DECREASE_SIZE(s, 3)
   11823           1 :         gf_bs_read_int(bs, 2);
   11824           1 :         ptr->min_temporal_id = gf_bs_read_int(bs, 3);
   11825           1 :         ptr->max_temporal_id = gf_bs_read_int(bs, 3);
   11826           1 :         ptr->num_views = gf_bs_read_u16(bs);
   11827           1 :         if (ptr->num_views > ptr->size / 6)
   11828             :                 return GF_ISOM_INVALID_FILE;
   11829             : 
   11830           1 :         ptr->views = gf_malloc(sizeof(ViewIDEntry)*ptr->num_views);
   11831           1 :         memset(ptr->views, 0, sizeof(ViewIDEntry)*ptr->num_views);
   11832           1 :         for (i=0; i<ptr->num_views; i++) {
   11833             :                 u32 j;
   11834           0 :                 ISOM_DECREASE_SIZE(s, 6)
   11835             : 
   11836           0 :                 gf_bs_read_int(bs, 6);
   11837           0 :                 ptr->views[i].view_id = gf_bs_read_int(bs, 10);
   11838           0 :                 gf_bs_read_int(bs, 6);
   11839           0 :                 ptr->views[i].view_order_index = gf_bs_read_int(bs, 10);
   11840           0 :                 ptr->views[i].texture_in_stream = gf_bs_read_int(bs, 1);
   11841           0 :                 ptr->views[i].texture_in_track = gf_bs_read_int(bs, 1);
   11842           0 :                 ptr->views[i].depth_in_stream = gf_bs_read_int(bs, 1);
   11843           0 :                 ptr->views[i].depth_in_track = gf_bs_read_int(bs, 1);
   11844           0 :                 ptr->views[i].base_view_type = gf_bs_read_int(bs, 2);
   11845           0 :                 ptr->views[i].num_ref_views = gf_bs_read_int(bs, 10);
   11846             : 
   11847           0 :                 if (ptr->views[i].num_ref_views > ptr->size / 2)
   11848             :                         return GF_ISOM_INVALID_FILE;
   11849             : 
   11850           0 :                 ptr->views[i].view_refs = gf_malloc(sizeof(ViewIDRefViewEntry)*ptr->views[i].num_ref_views);
   11851           0 :                 for (j=0; j<ptr->views[i].num_ref_views; j++) {
   11852           0 :                         ISOM_DECREASE_SIZE(s, 2)
   11853           0 :                         gf_bs_read_int(bs, 4);
   11854           0 :                         ptr->views[i].view_refs[j].dep_comp_idc = gf_bs_read_int(bs, 2);
   11855           0 :                         ptr->views[i].view_refs[j].ref_view_id = gf_bs_read_int(bs, 10);
   11856             :                 }
   11857             :         }
   11858             :         return GF_OK;
   11859             : }
   11860             : 
   11861           3 : GF_Box *vwid_box_new()
   11862             : {
   11863           6 :         ISOM_DECL_BOX_ALLOC(GF_ViewIdentifierBox, GF_ISOM_BOX_TYPE_VWID);
   11864           3 :         return (GF_Box *)tmp;
   11865             : }
   11866             : 
   11867             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11868             : 
   11869           1 : GF_Err vwid_box_write(GF_Box *s, GF_BitStream *bs)
   11870             : {
   11871             :         GF_Err e;
   11872             :         u32 i, j;
   11873             :         GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
   11874           1 :         e = gf_isom_full_box_write(s, bs);
   11875           1 :         if (e) return e;
   11876             : 
   11877           1 :         gf_bs_write_int(bs, 0, 2);
   11878           1 :         gf_bs_write_int(bs, ptr->min_temporal_id, 3);
   11879           1 :         gf_bs_write_int(bs, ptr->max_temporal_id, 3);
   11880           1 :         gf_bs_write_u16(bs, ptr->num_views);
   11881             : 
   11882           1 :         for (i=0; i<ptr->num_views; i++) {
   11883           0 :                 gf_bs_write_int(bs, 0, 6);
   11884           0 :                 gf_bs_write_int(bs, ptr->views[i].view_id, 10);
   11885           0 :                 gf_bs_write_int(bs, 0, 6);
   11886           0 :                 gf_bs_write_int(bs, ptr->views[i].view_order_index, 10);
   11887             : 
   11888           0 :                 gf_bs_write_int(bs, ptr->views[i].texture_in_stream, 1);
   11889           0 :                 gf_bs_write_int(bs, ptr->views[i].texture_in_track, 1);
   11890           0 :                 gf_bs_write_int(bs, ptr->views[i].depth_in_stream, 1);
   11891           0 :                 gf_bs_write_int(bs, ptr->views[i].depth_in_track, 1);
   11892           0 :                 gf_bs_write_int(bs, ptr->views[i].base_view_type, 2);
   11893           0 :                 gf_bs_write_int(bs, ptr->views[i].num_ref_views, 10);
   11894             : 
   11895           0 :                 for (j=0; j<ptr->views[i].num_ref_views; j++) {
   11896           0 :                         gf_bs_write_int(bs, 0, 4);
   11897           0 :                         gf_bs_write_int(bs, ptr->views[i].view_refs[j].dep_comp_idc, 2);
   11898           0 :                         gf_bs_write_int(bs, ptr->views[i].view_refs[j].ref_view_id, 10);
   11899             :                 }
   11900             :         }
   11901             :         return GF_OK;
   11902             : }
   11903             : 
   11904           1 : GF_Err vwid_box_size(GF_Box *s)
   11905             : {
   11906             :         u32 i;
   11907             :         GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
   11908           1 :         ptr->size += 3;
   11909           1 :         for (i=0; i<ptr->num_views; i++) {
   11910           0 :                 ptr->size += 6 + 2 * ptr->views[i].num_ref_views;
   11911             :         }
   11912           1 :         return GF_OK;
   11913             : }
   11914             : 
   11915             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11916             : 
   11917             : 
   11918           8 : void pcmC_box_del(GF_Box *s)
   11919             : {
   11920           8 :         gf_free(s);
   11921           8 : }
   11922             : 
   11923           6 : GF_Err pcmC_box_read(GF_Box *s,GF_BitStream *bs)
   11924             : {
   11925             :         GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;
   11926             : 
   11927           6 :         ISOM_DECREASE_SIZE(s, 2)
   11928           6 :         ptr->format_flags = gf_bs_read_u8(bs);
   11929           6 :         ptr->PCM_sample_size = gf_bs_read_u8(bs);
   11930           6 :         return GF_OK;
   11931             : }
   11932             : 
   11933           8 : GF_Box *pcmC_box_new()
   11934             : {
   11935          16 :         ISOM_DECL_BOX_ALLOC(GF_PCMConfigBox, GF_ISOM_BOX_TYPE_PCMC);
   11936           8 :         return (GF_Box *)tmp;
   11937             : }
   11938             : 
   11939             : #ifndef GPAC_DISABLE_ISOM_WRITE
   11940             : 
   11941           6 : GF_Err pcmC_box_write(GF_Box *s, GF_BitStream *bs)
   11942             : {
   11943             :         GF_Err e;
   11944             :         GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;
   11945             : 
   11946           6 :         e = gf_isom_full_box_write(s, bs);
   11947           6 :         if (e) return e;
   11948           6 :         gf_bs_write_u8(bs, ptr->format_flags);
   11949           6 :         gf_bs_write_u8(bs, ptr->PCM_sample_size);
   11950           6 :         return GF_OK;
   11951             : }
   11952             : 
   11953           6 : GF_Err pcmC_box_size(GF_Box *s)
   11954             : {
   11955           6 :         s->size += 2;
   11956           6 :         return GF_OK;
   11957             : }
   11958             : 
   11959             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   11960             : 
   11961             : 
   11962             : 
   11963          13 : void chnl_box_del(GF_Box *s)
   11964             : {
   11965          13 :         gf_free(s);
   11966          13 : }
   11967             : 
   11968           6 : GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
   11969             : {
   11970             :         GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
   11971             : 
   11972           6 :         ISOM_DECREASE_SIZE(s, 1)
   11973           6 :         ptr->layout.stream_structure = gf_bs_read_u8(bs);
   11974           6 :         if (ptr->layout.stream_structure & 1) {
   11975           5 :                 ISOM_DECREASE_SIZE(s, 1)
   11976           5 :                 ptr->layout.definedLayout = gf_bs_read_u8(bs);
   11977           5 :                 if (ptr->layout.definedLayout) {
   11978           5 :                         u32 remain = (u32) ptr->size;
   11979           5 :                         if (ptr->layout.stream_structure & 2) remain--;
   11980           5 :                         ptr->layout.channels_count = 0;
   11981          50 :                         while (remain) {
   11982          40 :                                 ISOM_DECREASE_SIZE(s, 1)
   11983          40 :                                 ptr->layout.layouts[ptr->layout.channels_count].position = gf_bs_read_u8(bs);
   11984          40 :                                 remain--;
   11985          40 :                                 if (ptr->layout.layouts[ptr->layout.channels_count].position == 126) {
   11986           0 :                                         ISOM_DECREASE_SIZE(s, 3)
   11987           0 :                                         ptr->layout.layouts[ptr->layout.channels_count].azimuth = gf_bs_read_int(bs, 16);
   11988           0 :                                         ptr->layout.layouts[ptr->layout.channels_count].elevation = gf_bs_read_int(bs, 8);
   11989           0 :                                         remain-=3;
   11990             :                                 }
   11991             :                         }
   11992             :                 } else {
   11993           0 :                         ISOM_DECREASE_SIZE(s, 8)
   11994           0 :                         ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
   11995             :                 }
   11996             :         }
   11997           6 :         if (ptr->layout.stream_structure & 2) {
   11998           0 :                 ISOM_DECREASE_SIZE(s, 1)
   11999           0 :                 ptr->layout.object_count = gf_bs_read_u8(bs);
   12000             :         }
   12001             :         return GF_OK;
   12002             : }
   12003             : 
   12004          13 : GF_Box *chnl_box_new()
   12005             : {
   12006          26 :         ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutBox, GF_ISOM_BOX_TYPE_CHNL);
   12007          13 :         return (GF_Box *)tmp;
   12008             : }
   12009             : 
   12010             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12011             : 
   12012          11 : GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs)
   12013             : {
   12014             :         GF_Err e;
   12015             :         GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
   12016             : 
   12017          11 :         e = gf_isom_full_box_write(s, bs);
   12018          11 :         if (e) return e;
   12019             : 
   12020          11 :         gf_bs_write_u8(bs, ptr->layout.stream_structure);
   12021          11 :         if (ptr->layout.stream_structure & 1) {
   12022          10 :                 gf_bs_write_u8(bs, ptr->layout.definedLayout);
   12023          10 :                 if (ptr->layout.definedLayout==0) {
   12024             :                         u32 i;
   12025           0 :                         for (i=0; i<ptr->layout.channels_count; i++) {
   12026           0 :                                 gf_bs_write_u8(bs, ptr->layout.layouts[i].position);
   12027           0 :                                 if (ptr->layout.layouts[i].position==126) {
   12028           0 :                                         gf_bs_write_int(bs, ptr->layout.layouts[i].azimuth, 16);
   12029           0 :                                         gf_bs_write_int(bs, ptr->layout.layouts[i].elevation, 8);
   12030             :                                 }
   12031             :                         }
   12032             :                 } else {
   12033          10 :                         gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
   12034             :                 }
   12035             :         }
   12036          11 :         if (ptr->layout.stream_structure & 2) {
   12037           0 :                 gf_bs_write_u8(bs, ptr->layout.object_count);
   12038             :         }
   12039             :         return GF_OK;
   12040             : }
   12041             : 
   12042          21 : GF_Err chnl_box_size(GF_Box *s)
   12043             : {
   12044             :         GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
   12045          21 :         s->size += 1;
   12046          21 :         if (ptr->layout.stream_structure & 1) {
   12047          20 :                 s->size += 1;
   12048          20 :                 if (ptr->layout.definedLayout==0) {
   12049             :                         u32 i;
   12050           0 :                         for (i=0; i<ptr->layout.channels_count; i++) {
   12051           0 :                                 s->size+=1;
   12052           0 :                                 if (ptr->layout.layouts[i].position==126)
   12053           0 :                                         s->size+=3;
   12054             :                         }
   12055             :                 } else {
   12056          20 :                         s->size += 8;
   12057             :                 }
   12058             :         }
   12059          21 :         if (ptr->layout.stream_structure & 2) {
   12060           0 :                 s->size += 1;
   12061             :         }
   12062          21 :         return GF_OK;
   12063             : }
   12064             : 
   12065             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12066             : 
   12067             : 
   12068           4 : GF_Box *emsg_box_new()
   12069             : {
   12070           8 :         ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMSG);
   12071           4 :         return (GF_Box *)tmp;
   12072             : }
   12073             : 
   12074           4 : void emsg_box_del(GF_Box *s)
   12075             : {
   12076             :         GF_EventMessageBox *ptr = (GF_EventMessageBox *) s;
   12077           4 :         if (ptr == NULL) return;
   12078           4 :         if (ptr->scheme_id_uri) gf_free(ptr->scheme_id_uri);
   12079           4 :         if (ptr->value) gf_free(ptr->value);
   12080           4 :         if (ptr->message_data) gf_free(ptr->message_data);
   12081           4 :         gf_free(ptr);
   12082             : }
   12083             : 
   12084           0 : GF_Err emsg_box_read(GF_Box *s,GF_BitStream *bs)
   12085             : {
   12086             :         GF_Err e;
   12087             :         GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
   12088             : 
   12089           0 :         if (ptr->version==0) {
   12090           0 :                 e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
   12091           0 :                 if (e) return e;
   12092           0 :                 e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
   12093           0 :                 if (e) return e;
   12094             : 
   12095           0 :                 ISOM_DECREASE_SIZE(ptr, 16);
   12096           0 :                 ptr->timescale = gf_bs_read_u32(bs);
   12097           0 :                 ptr->presentation_time_delta = gf_bs_read_u32(bs);
   12098           0 :                 ptr->event_duration = gf_bs_read_u32(bs);
   12099           0 :                 ptr->event_id = gf_bs_read_u32(bs);
   12100           0 :         } else if (ptr->version==1) {
   12101           0 :                 ISOM_DECREASE_SIZE(ptr, 20);
   12102           0 :                 ptr->timescale = gf_bs_read_u32(bs);
   12103           0 :                 ptr->presentation_time_delta = gf_bs_read_u64(bs);
   12104           0 :                 ptr->event_duration = gf_bs_read_u32(bs);
   12105           0 :                 ptr->event_id = gf_bs_read_u32(bs);
   12106             : 
   12107           0 :                 e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
   12108           0 :                 if (e) return e;
   12109           0 :                 e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
   12110           0 :                 if (e) return e;
   12111             :         } else {
   12112             :                 return GF_OK;
   12113             :         }
   12114           0 :         if (ptr->size) {
   12115           0 :                 if (ptr->size>0xFFFFFFFUL) {
   12116           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] emsg message data size too big ("LLU") to be loaded\n", ptr->size));
   12117             :                         return GF_OUT_OF_MEM;
   12118             :                 }
   12119           0 :                 ptr->message_data_size = (u32) ptr->size;
   12120           0 :                 ptr->message_data = gf_malloc(ptr->message_data_size);
   12121           0 :                 if (!ptr->message_data) return GF_OUT_OF_MEM;
   12122           0 :                 gf_bs_read_data(bs, ptr->message_data, ptr->message_data_size);
   12123           0 :                 ptr->size = 0;
   12124             :         }
   12125             :         return GF_OK;
   12126             : }
   12127             : 
   12128             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12129             : 
   12130           1 : GF_Err emsg_box_write(GF_Box *s, GF_BitStream *bs)
   12131             : {
   12132             :         GF_Err e;
   12133             :         u32 len;
   12134             :         GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
   12135             : 
   12136           1 :         e = gf_isom_full_box_write(s, bs);
   12137           1 :         if (e) return e;
   12138             : 
   12139           1 :         if (ptr->version==1) {
   12140           0 :                 gf_bs_write_u32(bs, ptr->timescale);
   12141           0 :                 gf_bs_write_u64(bs, ptr->presentation_time_delta);
   12142           0 :                 gf_bs_write_u32(bs, ptr->event_duration);
   12143           0 :                 gf_bs_write_u32(bs, ptr->event_id);
   12144             :         }
   12145             : 
   12146           1 :         len = ptr->scheme_id_uri ? (u32) strlen(ptr->scheme_id_uri) : 0;
   12147           0 :         if (len) gf_bs_write_data(bs, ptr->scheme_id_uri, len);
   12148           1 :         gf_bs_write_u8(bs, 0);
   12149             : 
   12150           1 :         len = ptr->value ? (u32) strlen(ptr->value) : 0;
   12151           0 :         if (len) gf_bs_write_data(bs, ptr->value, len);
   12152           1 :         gf_bs_write_u8(bs, 0);
   12153             : 
   12154           1 :         if (ptr->version==0) {
   12155           1 :                 gf_bs_write_u32(bs, ptr->timescale);
   12156           1 :                 gf_bs_write_u32(bs, (u32) ptr->presentation_time_delta);
   12157           1 :                 gf_bs_write_u32(bs, ptr->event_duration);
   12158           1 :                 gf_bs_write_u32(bs, ptr->event_id);
   12159             :         }
   12160           1 :         if (ptr->message_data)
   12161           0 :                 gf_bs_write_data(bs, ptr->message_data, ptr->message_data_size);
   12162             :         return GF_OK;
   12163             : }
   12164             : 
   12165           1 : GF_Err emsg_box_size(GF_Box *s)
   12166             : {
   12167             :         GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
   12168             : 
   12169           1 :         ptr->size += 4;
   12170           1 :         if (ptr->version) {
   12171           0 :                 ptr->size += 20;
   12172             :         } else {
   12173           1 :                 ptr->size += 16;
   12174             :         }
   12175           1 :         ptr->size+=2; //1 NULL-terminated strings
   12176           1 :         if (ptr->scheme_id_uri) ptr->size += strlen(ptr->scheme_id_uri);
   12177           1 :         if (ptr->value) ptr->size += strlen(ptr->value);
   12178           1 :         if (ptr->message_data)
   12179           0 :                 ptr->size += ptr->message_data_size;
   12180             : 
   12181           1 :         return GF_OK;
   12182             : }
   12183             : #endif // GPAC_DISABLE_ISOM_WRITE
   12184             : 
   12185             : 
   12186             : 
   12187             : 
   12188           3 : GF_Box *csgp_box_new()
   12189             : {
   12190           6 :         ISOM_DECL_BOX_ALLOC(GF_CompactSampleGroupBox, GF_ISOM_BOX_TYPE_CSGP);
   12191           3 :         return (GF_Box *)tmp;
   12192             : }
   12193           3 : void csgp_box_del(GF_Box *a)
   12194             : {
   12195             :         GF_CompactSampleGroupBox *p = (GF_CompactSampleGroupBox *)a;
   12196           3 :         if (p->patterns) {
   12197             :                 u32 i;
   12198           0 :                 for (i=0; i<p->pattern_count; i++) {
   12199           0 :                         gf_free(p->patterns[i].sample_group_description_indices);
   12200             :                 }
   12201           1 :                 gf_free(p->patterns);
   12202             :         }
   12203           3 :         gf_free(p);
   12204           3 : }
   12205             : 
   12206           0 : u32 get_size_by_code(u32 code)
   12207             : {
   12208           9 :         if (code==0) return 4;
   12209           0 :         if (code==1) return 8;
   12210           0 :         if (code==2) return 16;
   12211           0 :         return 32;
   12212             : }
   12213           1 : GF_Err csgp_box_read(GF_Box *s, GF_BitStream *bs)
   12214             : {
   12215             :         u32 i, bits, gidx_mask;
   12216             :         Bool index_msb_indicates_fragment_local_description, grouping_type_parameter_present;
   12217             :         u32 pattern_size, scount_size, index_size;
   12218             :         GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox *)s;
   12219             : 
   12220           1 :         ISOM_DECREASE_SIZE(ptr, 8);
   12221           1 :         ptr->version = gf_bs_read_u8(bs);
   12222           1 :         ptr->flags = gf_bs_read_u24(bs);
   12223             : 
   12224           1 :         index_msb_indicates_fragment_local_description = (ptr->flags & (1<<7)) ? GF_TRUE : GF_FALSE;
   12225           1 :         grouping_type_parameter_present = (ptr->flags & (1<<6)) ? GF_TRUE : GF_FALSE;
   12226             : 
   12227           1 :         pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
   12228           1 :         scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
   12229           1 :         index_size = get_size_by_code( (ptr->flags & 0x3) );
   12230             : 
   12231           1 :         if (((pattern_size==4) && (scount_size!=4)) || ((pattern_size!=4) && (scount_size==4))) {
   12232           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample gorup pattern_size and sample_count_size mare not both 4 bits\n"));
   12233             :                 return GF_ISOM_INVALID_FILE;
   12234             :         }
   12235             : 
   12236           1 :         ptr->grouping_type = gf_bs_read_u32(bs);
   12237           1 :         if (grouping_type_parameter_present) {
   12238           0 :                 ISOM_DECREASE_SIZE(ptr, 4);
   12239           0 :                 ptr->grouping_type_parameter = gf_bs_read_u32(bs);
   12240             :         }
   12241           1 :         ISOM_DECREASE_SIZE(ptr, 4);
   12242           1 :         ptr->pattern_count = gf_bs_read_u32(bs);
   12243             : 
   12244             : 
   12245           1 :         if (ptr->size / ( (pattern_size + scount_size) / 8 ) < ptr->pattern_count )
   12246             :             return GF_ISOM_INVALID_FILE;
   12247             : 
   12248           1 :         ptr->patterns = gf_malloc(sizeof(GF_CompactSampleGroupPattern) * ptr->pattern_count);
   12249           1 :         if (!ptr->patterns) return GF_OUT_OF_MEM;
   12250             : 
   12251             :         bits = 0;
   12252           0 :         for (i=0; i<ptr->pattern_count; i++) {
   12253           0 :                 ptr->patterns[i].length = gf_bs_read_int(bs, pattern_size);
   12254           0 :                 ptr->patterns[i].sample_count = gf_bs_read_int(bs, scount_size);
   12255           0 :                 bits += pattern_size + scount_size;
   12256           0 :                 if (! (bits % 8)) {
   12257           0 :                         bits/=8;
   12258           0 :                         ISOM_DECREASE_SIZE(ptr, bits);
   12259             :                         bits=0;
   12260             :                 }
   12261           0 :                 ptr->patterns[i].sample_group_description_indices = gf_malloc(sizeof(u32) * ptr->patterns[i].length);
   12262           0 :                 if (!ptr->patterns[i].sample_group_description_indices) return GF_OUT_OF_MEM;
   12263             :         }
   12264             :         bits = 0;
   12265           1 :         gidx_mask = ((u32)1) << (index_size-1);
   12266           1 :         for (i=0; i<ptr->pattern_count; i++) {
   12267             :                 u32 j;
   12268           0 :                 for (j=0; j<ptr->patterns[i].length; j++) {
   12269           0 :                         u32 idx = gf_bs_read_int(bs, index_size);
   12270           0 :                         if (index_msb_indicates_fragment_local_description) {
   12271             :                                 //MSB set, this is a index of a group described in the fragment
   12272           0 :                                 if (idx & gidx_mask) {
   12273           0 :                                         idx += 0x10000;
   12274             :                                 }
   12275             :                         }
   12276           0 :                         ptr->patterns[i].sample_group_description_indices[j] = idx;
   12277           0 :                         bits += index_size;
   12278             : 
   12279           0 :                         if (! (bits % 8)) {
   12280           0 :                                 bits/=8;
   12281           0 :                                 ISOM_DECREASE_SIZE(ptr, bits);
   12282             :                                 bits=0;
   12283             :                         }
   12284             :                 }
   12285             :         }
   12286           1 :         if (bits)
   12287           0 :                 gf_bs_align(bs);
   12288             :         return GF_OK;
   12289             : }
   12290             : 
   12291             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12292           1 : GF_Err csgp_box_write(GF_Box *s, GF_BitStream *bs)
   12293             : {
   12294             :         u32 i;
   12295             :         GF_Err e;
   12296             :         GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
   12297           1 :         u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
   12298           1 :         u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
   12299           1 :         u32 index_size = get_size_by_code( (ptr->flags & 0x3) );
   12300             : 
   12301           1 :         e = gf_isom_box_write_header(s, bs);
   12302           1 :         if (e) return e;
   12303             : 
   12304           1 :         gf_bs_write_u8(bs, ptr->version);
   12305           1 :         gf_bs_write_int(bs, ptr->flags, 24);
   12306           1 :         gf_bs_write_u32(bs, ptr->grouping_type);
   12307             : 
   12308           1 :         if (ptr->flags & (1<<6))
   12309           0 :                 gf_bs_write_u32(bs, ptr->grouping_type_parameter);
   12310             : 
   12311           1 :         gf_bs_write_u32(bs, ptr->pattern_count);
   12312             : 
   12313           1 :         for (i = 0; i<ptr->pattern_count; i++ ) {
   12314           0 :                 gf_bs_write_int(bs, ptr->patterns[i].length, pattern_size);
   12315           0 :                 gf_bs_write_int(bs, ptr->patterns[i].sample_count, scount_size);
   12316             :         }
   12317             : 
   12318           0 :         for (i = 0; i<ptr->pattern_count; i++ ) {
   12319             :                 u32 j;
   12320           0 :                 for (j=0; j<ptr->patterns[i].length; j++) {
   12321           0 :                         u32 idx = ptr->patterns[i].sample_group_description_indices[j];
   12322           0 :                         if (idx > 0x10000) {
   12323           0 :                                 idx -= 0x10000;
   12324           0 :                                 gf_bs_write_int(bs, 1, 1);
   12325           0 :                                 gf_bs_write_int(bs, idx, index_size-1);
   12326             :                         } else {
   12327           0 :                                 gf_bs_write_int(bs, idx, index_size);
   12328             :                         }
   12329             :                 }
   12330             :         }
   12331           1 :         gf_bs_align(bs);
   12332           1 :         return GF_OK;
   12333             : }
   12334             : 
   12335           1 : GF_Err csgp_box_size(GF_Box *s)
   12336             : {
   12337             :         u32 i, bits;
   12338             :         GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
   12339           1 :         u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
   12340           1 :         u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
   12341           1 :         u32 index_size = get_size_by_code( (ptr->flags & 0x3) );
   12342             : 
   12343           1 :         ptr->size += 12; //v, flags , grouping_type, pattern_length
   12344           1 :         if (ptr->flags & (1<<6))
   12345           0 :                 ptr->size+=4;
   12346             : 
   12347           1 :         ptr->size += ptr->pattern_count * (pattern_size + scount_size) / 8;
   12348             :         bits=0;
   12349           1 :         for (i=0; i<ptr->pattern_count; i++)
   12350           0 :                 bits += ptr->patterns[i].length * index_size;
   12351           1 :         ptr->size += bits/8;
   12352           1 :         if (bits % 8) ptr->size++;
   12353           1 :         return GF_OK;
   12354             : }
   12355             : 
   12356             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12357             : 
   12358           9 : GF_Box *dmlp_box_new()
   12359             : {
   12360          18 :         ISOM_DECL_BOX_ALLOC(GF_TrueHDConfigBox, GF_ISOM_BOX_TYPE_DMLP);
   12361           9 :         return (GF_Box *)tmp;
   12362             : }
   12363             : 
   12364           9 : void dmlp_box_del(GF_Box *s)
   12365             : {
   12366           9 :         gf_free(s);
   12367           9 : }
   12368             : 
   12369             : 
   12370           6 : GF_Err dmlp_box_read(GF_Box *s, GF_BitStream *bs)
   12371             : {
   12372             :         GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;
   12373           6 :         ISOM_DECREASE_SIZE(ptr, 10)
   12374           6 :         ptr->format_info = gf_bs_read_u32(bs);
   12375           6 :         ptr->peak_data_rate = gf_bs_read_int(bs, 15);
   12376           6 :         gf_bs_read_int(bs, 1);
   12377           6 :         gf_bs_read_u32(bs);
   12378           6 :         return GF_OK;
   12379             : }
   12380             : 
   12381             : 
   12382             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12383             : 
   12384           3 : GF_Err dmlp_box_write(GF_Box *s, GF_BitStream *bs)
   12385             : {
   12386             :         GF_Err e;
   12387             :         GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;
   12388             : 
   12389           3 :         e = gf_isom_box_write_header(s, bs);
   12390           3 :         if (e) return e;
   12391           3 :         gf_bs_write_u32(bs, ptr->format_info);
   12392           3 :         gf_bs_write_int(bs, ptr->peak_data_rate, 15);
   12393           3 :         gf_bs_write_int(bs, 0, 1);
   12394           3 :         gf_bs_write_u32(bs, 0);
   12395           3 :         return GF_OK;
   12396             : }
   12397             : 
   12398           5 : GF_Err dmlp_box_size(GF_Box *s)
   12399             : {
   12400           5 :         s->size += 10;
   12401           5 :         return GF_OK;
   12402             : }
   12403             : 
   12404             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12405             : 
   12406           3 : GF_Box *xtra_box_new()
   12407             : {
   12408           6 :         ISOM_DECL_BOX_ALLOC(GF_XtraBox, GF_ISOM_BOX_TYPE_XTRA);
   12409           3 :         tmp->tags = gf_list_new();
   12410           3 :         return (GF_Box *)tmp;
   12411             : }
   12412             : 
   12413           3 : void xtra_box_del(GF_Box *s)
   12414             : {
   12415             :         GF_XtraBox *ptr = (GF_XtraBox *)s;
   12416           6 :         while (gf_list_count(ptr->tags)) {
   12417           0 :                 GF_XtraTag *tag = gf_list_pop_back(ptr->tags);
   12418           0 :                 if (tag->name) gf_free(tag->name);
   12419           0 :                 if (tag->prop_value) gf_free(tag->prop_value);
   12420           0 :                 gf_free(tag);
   12421             :         }
   12422           3 :         gf_list_del(ptr->tags);
   12423           3 :         gf_free(s);
   12424           3 : }
   12425             : 
   12426           1 : GF_Err xtra_box_read(GF_Box *s, GF_BitStream *bs)
   12427             : {
   12428             :         GF_XtraBox *ptr = (GF_XtraBox *)s;
   12429           2 :         while (ptr->size) {
   12430             :                 GF_XtraTag *tag;
   12431             :                 u32 prop_type = 0;
   12432             : 
   12433             :                 char *data=NULL, *data2=NULL;
   12434           0 :                 ISOM_DECREASE_SIZE_NO_ERR(ptr, 18)
   12435           0 :                 s32 tag_size = gf_bs_read_u32(bs);
   12436           0 :                 u32 name_size = gf_bs_read_u32(bs);
   12437           0 :                 tag_size -= 8;
   12438             : 
   12439           0 :                 ISOM_DECREASE_SIZE_NO_ERR(ptr, name_size)
   12440           0 :                 data = gf_malloc(sizeof(char) * (name_size+1));
   12441           0 :                 gf_bs_read_data(bs, data, name_size);
   12442           0 :                 data[name_size] = 0;
   12443           0 :                 tag_size-=name_size;
   12444             : 
   12445           0 :                 u32 flags = gf_bs_read_u32(bs);
   12446           0 :                 u32 prop_size = gf_bs_read_u32(bs);
   12447           0 :                 tag_size-=8;
   12448             : 
   12449           0 :                 if (prop_size>4) {
   12450           0 :                         tag_size-=2;
   12451           0 :                         prop_type = gf_bs_read_u16(bs);
   12452           0 :                         prop_size -= 6;
   12453           0 :                         ISOM_DECREASE_SIZE_NO_ERR(ptr, prop_size)
   12454           0 :                         data2 = gf_malloc(sizeof(char) * (prop_size));
   12455           0 :                         gf_bs_read_data(bs, data2, prop_size);
   12456           0 :                         tag_size-=prop_size;
   12457             :                 }
   12458           0 :                 GF_SAFEALLOC(tag, GF_XtraTag)
   12459           0 :                 tag->flags = flags;
   12460           0 :                 tag->name = data;
   12461           0 :                 tag->prop_size = prop_size;
   12462           0 :                 tag->prop_value = data2;
   12463           0 :                 tag->prop_type = prop_type;
   12464           0 :                 gf_list_add(ptr->tags, tag);
   12465             : 
   12466           0 :                 if (tag_size) {
   12467           0 :                         GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isom] invalid tag size in Xtra !\n"));
   12468             :                 }
   12469             :         }
   12470             :         return GF_OK;
   12471             : }
   12472             : 
   12473             : 
   12474             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12475             : 
   12476           1 : GF_Err xtra_box_write(GF_Box *s, GF_BitStream *bs)
   12477             : {
   12478             :         GF_Err e;
   12479             :         GF_XtraBox *ptr = (GF_XtraBox *)s;
   12480           1 :         u32 i, count = gf_list_count(ptr->tags);
   12481             : 
   12482           1 :         e = gf_isom_box_write_header(s, bs);
   12483           1 :         if (e) return e;
   12484             : 
   12485           0 :         for (i=0; i<count; i++) {
   12486           0 :                 GF_XtraTag *tag = gf_list_get(ptr->tags, i);
   12487             :                 u32 tag_size = 16;
   12488           0 :                 u32 name_len = tag->name ? (u32) strlen(tag->name) : 0;
   12489           0 :                 tag_size += name_len;
   12490           0 :                 if (tag->prop_value) {
   12491           0 :                         tag_size += 2 + tag->prop_size;
   12492             :                 }
   12493           0 :                 gf_bs_write_u32(bs, tag_size);
   12494           0 :                 gf_bs_write_u32(bs, name_len);
   12495           0 :                 gf_bs_write_data(bs, tag->name, name_len);
   12496           0 :                 gf_bs_write_u32(bs, tag->flags);
   12497           0 :                 gf_bs_write_u32(bs, 6 + tag->prop_size);
   12498           0 :                 gf_bs_write_u16(bs, tag->prop_type);
   12499           0 :                 gf_bs_write_data(bs, tag->prop_value, tag->prop_size);
   12500             :         }
   12501             :         return GF_OK;
   12502             : }
   12503             : 
   12504           1 : GF_Err xtra_box_size(GF_Box *s)
   12505             : {
   12506             :         GF_XtraBox *ptr = (GF_XtraBox *)s;
   12507           1 :         u32 i, count = gf_list_count(ptr->tags);
   12508           1 :         for (i=0; i<count; i++) {
   12509           0 :                 GF_XtraTag *tag = gf_list_get(ptr->tags, i);
   12510           0 :                 ptr->size += 18 + (u32) strlen(tag->name) + tag->prop_size;
   12511             :         }
   12512           1 :         return GF_OK;
   12513             : }
   12514             : 
   12515             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12516             : 
   12517             : 
   12518             : 
   12519           3 : GF_Box *st3d_box_new()
   12520             : {
   12521           6 :         ISOM_DECL_BOX_ALLOC(GF_Stereo3DBox, GF_ISOM_BOX_TYPE_ST3D);
   12522           3 :         return (GF_Box *)tmp;
   12523             : }
   12524             : 
   12525           3 : void st3d_box_del(GF_Box *s)
   12526             : {
   12527           3 :         gf_free(s);
   12528           3 : }
   12529             : 
   12530             : 
   12531           1 : GF_Err st3d_box_read(GF_Box *s, GF_BitStream *bs)
   12532             : {
   12533             :         GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;
   12534           1 :         ISOM_DECREASE_SIZE(ptr, 1)
   12535           1 :         ptr->stereo_type = gf_bs_read_u8(bs);
   12536           1 :         return GF_OK;
   12537             : }
   12538             : 
   12539             : 
   12540             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12541             : 
   12542           1 : GF_Err st3d_box_write(GF_Box *s, GF_BitStream *bs)
   12543             : {
   12544             :         GF_Err e;
   12545             :         GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;
   12546             : 
   12547           1 :         e = gf_isom_full_box_write(s, bs);
   12548           1 :         if (e) return e;
   12549           1 :         gf_bs_write_u8(bs, ptr->stereo_type);
   12550           1 :         return GF_OK;
   12551             : }
   12552             : 
   12553           1 : GF_Err st3d_box_size(GF_Box *s)
   12554             : {
   12555           1 :         s->size += 1;
   12556           1 :         return GF_OK;
   12557             : }
   12558             : 
   12559             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12560             : 
   12561             : 
   12562             : 
   12563           3 : GF_Box *svhd_box_new()
   12564             : {
   12565           6 :         ISOM_DECL_BOX_ALLOC(GF_SphericalVideoInfoBox, GF_ISOM_BOX_TYPE_SVHD);
   12566           3 :         return (GF_Box *)tmp;
   12567             : }
   12568             : 
   12569           3 : void svhd_box_del(GF_Box *s)
   12570             : {
   12571             :         GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
   12572           3 :         if (ptr->string) gf_free(ptr->string);
   12573           3 :         gf_free(s);
   12574           3 : }
   12575             : 
   12576             : 
   12577           1 : GF_Err svhd_box_read(GF_Box *s, GF_BitStream *bs)
   12578             : {
   12579             :         GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
   12580           1 :         ptr->string = gf_malloc(sizeof(char) * ((u32) ptr->size+1));
   12581           1 :         if (!ptr->string) return GF_OUT_OF_MEM;
   12582           1 :         gf_bs_read_data(bs, ptr->string, (u32) ptr->size);
   12583           1 :         ptr->string[ptr->size] = 0;
   12584           1 :         return GF_OK;
   12585             : }
   12586             : 
   12587             : 
   12588             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12589             : 
   12590           1 : GF_Err svhd_box_write(GF_Box *s, GF_BitStream *bs)
   12591             : {
   12592             :         GF_Err e;
   12593             :         GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
   12594             : 
   12595           1 :         e = gf_isom_full_box_write(s, bs);
   12596           1 :         if (e) return e;
   12597           1 :         if (ptr->string)
   12598           0 :                 gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string));
   12599           1 :         gf_bs_write_u8(bs, 0);
   12600           1 :         return GF_OK;
   12601             : }
   12602             : 
   12603           1 : GF_Err svhd_box_size(GF_Box *s)
   12604             : {
   12605             :         GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
   12606           1 :         if (ptr->string)
   12607           0 :                 s->size += (u32) strlen(ptr->string);
   12608           1 :         s->size += 1;
   12609           1 :         return GF_OK;
   12610             : }
   12611             : 
   12612             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12613             : 
   12614             : 
   12615           3 : GF_Box *prhd_box_new()
   12616             : {
   12617           6 :         ISOM_DECL_BOX_ALLOC(GF_ProjectionHeaderBox, GF_ISOM_BOX_TYPE_PRHD);
   12618           3 :         return (GF_Box *)tmp;
   12619             : }
   12620             : 
   12621           3 : void prhd_box_del(GF_Box *s)
   12622             : {
   12623           3 :         gf_free(s);
   12624           3 : }
   12625             : 
   12626             : 
   12627           1 : GF_Err prhd_box_read(GF_Box *s, GF_BitStream *bs)
   12628             : {
   12629             :         GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;
   12630           1 :         ISOM_DECREASE_SIZE(ptr, 12)
   12631           1 :         ptr->yaw = (s32) gf_bs_read_u32(bs);
   12632           1 :         ptr->pitch = (s32) gf_bs_read_u32(bs);
   12633           1 :         ptr->roll = (s32) gf_bs_read_u32(bs);
   12634           1 :         return GF_OK;
   12635             : }
   12636             : 
   12637             : 
   12638             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12639             : 
   12640           1 : GF_Err prhd_box_write(GF_Box *s, GF_BitStream *bs)
   12641             : {
   12642             :         GF_Err e;
   12643             :         GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;
   12644             : 
   12645           1 :         e = gf_isom_full_box_write(s, bs);
   12646           1 :         if (e) return e;
   12647           1 :         gf_bs_write_u32(bs, ptr->yaw);
   12648           1 :         gf_bs_write_u32(bs, ptr->pitch);
   12649           1 :         gf_bs_write_u32(bs, ptr->roll);
   12650           1 :         return GF_OK;
   12651             : }
   12652             : 
   12653           1 : GF_Err prhd_box_size(GF_Box *s)
   12654             : {
   12655           1 :         s->size += 12;
   12656           1 :         return GF_OK;
   12657             : }
   12658             : 
   12659             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12660             : 
   12661           9 : GF_Box *proj_type_box_new()
   12662             : {
   12663          18 :         ISOM_DECL_BOX_ALLOC(GF_ProjectionTypeBox, GF_ISOM_BOX_TYPE_EQUI); //will be overwritten
   12664           9 :         return (GF_Box *)tmp;
   12665             : }
   12666             : 
   12667           9 : void proj_type_box_del(GF_Box *s)
   12668             : {
   12669           9 :         gf_free(s);
   12670           9 : }
   12671             : 
   12672           3 : GF_Err proj_type_box_read(GF_Box *s, GF_BitStream *bs)
   12673             : {
   12674             :         GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
   12675             : 
   12676           3 :         if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
   12677           1 :                 ISOM_DECREASE_SIZE(ptr, 8)
   12678           1 :                 ptr->layout = gf_bs_read_u32(bs);
   12679           1 :                 ptr->padding = gf_bs_read_u32(bs);
   12680             :         }
   12681           2 :         else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
   12682           1 :                 ISOM_DECREASE_SIZE(ptr, 16)
   12683           1 :                 ptr->bounds_top = gf_bs_read_u32(bs);
   12684           1 :                 ptr->bounds_bottom = gf_bs_read_u32(bs);
   12685           1 :                 ptr->bounds_left = gf_bs_read_u32(bs);
   12686           1 :                 ptr->bounds_right = gf_bs_read_u32(bs);
   12687             :         } else {
   12688           1 :                 ISOM_DECREASE_SIZE(ptr, 8)
   12689           1 :                 ptr->crc = gf_bs_read_u32(bs);
   12690           1 :                 ptr->encoding_4cc = gf_bs_read_u32(bs);
   12691             :         }
   12692           3 :         return gf_isom_box_array_read(s, bs);
   12693             : }
   12694             : 
   12695             : 
   12696             : #ifndef GPAC_DISABLE_ISOM_WRITE
   12697             : 
   12698           3 : GF_Err proj_type_box_write(GF_Box *s, GF_BitStream *bs)
   12699             : {
   12700             :         GF_Err e;
   12701             :         GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
   12702             : 
   12703           3 :         e = gf_isom_full_box_write(s, bs);
   12704           3 :         if (e) return e;
   12705           3 :         if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
   12706           1 :                 gf_bs_write_u32(bs, ptr->layout);
   12707           1 :                 gf_bs_write_u32(bs, ptr->padding);
   12708             :         }
   12709           2 :         else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
   12710           1 :                 gf_bs_write_u32(bs, ptr->bounds_top);
   12711           1 :                 gf_bs_write_u32(bs, ptr->bounds_bottom);
   12712           1 :                 gf_bs_write_u32(bs, ptr->bounds_left);
   12713           1 :                 gf_bs_write_u32(bs, ptr->bounds_right);
   12714             :         } else {
   12715           1 :                 gf_bs_write_u32(bs, ptr->crc);
   12716           1 :                 gf_bs_write_u32(bs, ptr->encoding_4cc);
   12717             :         }
   12718             :         return GF_OK;
   12719             : }
   12720             : 
   12721           3 : GF_Err proj_type_box_size(GF_Box *s)
   12722             : {
   12723             :         GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
   12724           3 :         if (ptr->type==GF_ISOM_BOX_TYPE_CBMP)
   12725           1 :                 s->size += 8;
   12726           2 :         else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI)
   12727           1 :                 s->size += 16;
   12728             :         else
   12729           1 :                 s->size += 8;
   12730             : 
   12731           3 :         return GF_OK;
   12732             : }
   12733             : 
   12734             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
   12735             : 
   12736             : #endif /*GPAC_DISABLE_ISOM*/

Generated by: LCOV version 1.13