/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2026
 *					All rights reserved
 *
 *  This file is part of GPAC / ISO Media File Format sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <gpac/internal/isomedia_dev.h>


#ifndef GPAC_DISABLE_ISOM

void co64_box_del(GF_Box *s)
{
	GF_ChunkLargeOffsetBox *ptr;
	ptr = (GF_ChunkLargeOffsetBox *) s;
	if (ptr == NULL) return;
	if (ptr->offsets) gf_free(ptr->offsets);
	gf_free(ptr);
}

GF_Err co64_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 entries;
	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
	ptr->nb_entries = gf_bs_read_u32(bs);

	ISOM_DECREASE_SIZE(ptr, 4)

	if ((u64)ptr->nb_entries > ptr->size / 8 || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(u64)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in co64\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) );
	if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
	ptr->alloc_size = ptr->nb_entries;
	for (entries = 0; entries < ptr->nb_entries; entries++) {
		ptr->offsets[entries] = gf_bs_read_u64(bs);
	}
	return GF_OK;
}

GF_Box *co64_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err co64_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i = 0; i < ptr->nb_entries; i++ ) {
		gf_bs_write_u64(bs, ptr->offsets[i]);
	}
	return GF_OK;
}

GF_Err co64_box_size(GF_Box *s)
{
	GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;

	ptr->size += 4 + (8 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void cprt_box_del(GF_Box *s)
{
	GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
	if (ptr == NULL) return;
	if (ptr->notice)
		gf_free(ptr->notice);
	gf_free(ptr);
}


GF_Box *chpl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
	tmp->list = gf_list_new();
	tmp->version = 1;
	return (GF_Box *)tmp;
}

void chpl_box_del(GF_Box *s)
{
	GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
	if (ptr == NULL) return;
	while (gf_list_count(ptr->list)) {
		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0);
		if (ce->name) gf_free(ce->name);
		gf_free(ce);
		gf_list_rem(ptr->list, 0);
	}
	gf_list_del(ptr->list);
	gf_free(ptr);
}

/*this is using chpl format according to some NeroRecode samples*/
GF_Err chpl_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_Err e;
	GF_ChapterEntry *ce=NULL;
	u32 nb_chaps, len, i, count;
	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;

	ISOM_DECREASE_SIZE(ptr, 5)
	/*reserved or ???*/
	gf_bs_read_u32(bs);
	nb_chaps = gf_bs_read_u8(bs);

	count = 0;
	while (nb_chaps) {
		GF_SAFEALLOC(ce, GF_ChapterEntry);
		if (!ce) return GF_OUT_OF_MEM;
		ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 9)
		ce->start_time = gf_bs_read_u64(bs);
		len = gf_bs_read_u8(bs);
		if (ptr->size<len) {
			e = GF_ISOM_INVALID_FILE;
			goto exit;
		}
		if (len) {
			ce->name = (char *)gf_malloc(sizeof(char)*(len+1));
			if (!ce->name) {
				e = GF_OUT_OF_MEM;
				goto exit;
			}
			ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, len)
			gf_bs_read_data(bs, ce->name, len);
			ce->name[len] = 0;
		} else {
			ce->name = gf_strdup("");
		}

		for (i=0; i<count; i++) {
			GF_ChapterEntry *ace = (GF_ChapterEntry *) gf_list_get(ptr->list, i);
			if (ace->start_time >= ce->start_time) {
				gf_list_insert(ptr->list, ce, i);
				ce = NULL;
				break;
			}
		}
		if (ce) gf_list_add(ptr->list, ce);
		count++;
		nb_chaps--;
		ce = NULL;
	}
	return GF_OK;
exit:
	if (ce) gf_free(ce);
	return e;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err chpl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 count, i;
	GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	count = gf_list_count(ptr->list);
	gf_bs_write_u32(bs, 0);
	gf_bs_write_u8(bs, count);
	for (i=0; i<count; i++) {
		u32 len;
		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
		gf_bs_write_u64(bs, ce->start_time);
		if (ce->name) {
			len = (u32) strlen(ce->name);
			if (len>255) len = 255;
			gf_bs_write_u8(bs, len);
			gf_bs_write_data(bs, ce->name, len);
		} else {
			gf_bs_write_u8(bs, 0);
		}
	}
	return GF_OK;
}

GF_Err chpl_box_size(GF_Box *s)
{
	u32 count, i;
	GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;

	ptr->size += 5;

	count = gf_list_count(ptr->list);
	for (i=0; i<count; i++) {
		GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
		ptr->size += 9; /*64bit time stamp + 8bit str len*/
		if (ce->name) ptr->size += strlen(ce->name);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Err cprt_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;

	ISOM_DECREASE_SIZE(ptr, 2);
	gf_bs_read_int(bs, 1);
	//the spec is unclear here, just says "the value 0 is interpreted as undetermined"
	ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5);
	ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5);
	ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5);

	//but before or after compaction ?? We assume before
	if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) {
		ptr->packedLanguageCode[0] += 0x60;
		ptr->packedLanguageCode[1] += 0x60;
		ptr->packedLanguageCode[2] += 0x60;
	} else {
		ptr->packedLanguageCode[0] = 'u';
		ptr->packedLanguageCode[1] = 'n';
		ptr->packedLanguageCode[2] = 'd';
	}
	if (ptr->size) {
		u32 bytesToRead = (u32) ptr->size;
		ptr->notice = (char*)gf_malloc((bytesToRead+1) * sizeof(char));
		if (ptr->notice == NULL) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->notice, bytesToRead);
		ptr->notice[bytesToRead] = 0;
	}
	return GF_OK;
}

GF_Box *cprt_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
	tmp->packedLanguageCode[0] = 'u';
	tmp->packedLanguageCode[1] = 'n';
	tmp->packedLanguageCode[2] = 'd';

	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err cprt_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, 0, 1);
	if (ptr->packedLanguageCode[0]) {
		gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5);
		gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5);
		gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5);
	} else {
		gf_bs_write_int(bs, 0, 15);
	}
	if (ptr->notice) {
		gf_bs_write_data(bs, ptr->notice, (u32) (strlen(ptr->notice) + 1) );
	}
	return GF_OK;
}

GF_Err cprt_box_size(GF_Box *s)
{
	GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;

	ptr->size += 2;
	if (ptr->notice)
		ptr->size += strlen(ptr->notice) + 1;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void kind_box_del(GF_Box *s)
{
	GF_KindBox *ptr = (GF_KindBox *) s;
	if (ptr == NULL) return;
	if (ptr->schemeURI) gf_free(ptr->schemeURI);
	if (ptr->value) gf_free(ptr->value);
	gf_free(ptr);
}

GF_Err kind_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_KindBox *ptr = (GF_KindBox *)s;

	if (ptr->size) {
		u32 bytesToRead = (u32) ptr->size;
		char *data;
		u32 schemeURIlen;
		data = (char*)gf_malloc(bytesToRead * sizeof(char));
		if (!data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, data, bytesToRead);
		/*safety check in case the string is not null-terminated*/
		if (data[bytesToRead-1]) {
			data = (char*)gf_realloc(data, sizeof(char)*(bytesToRead + 1));
			if (!data) return GF_OUT_OF_MEM;
			data[bytesToRead] = 0;
			bytesToRead++;
		}
		ptr->schemeURI = gf_strdup(data);
		if (!ptr->schemeURI) return GF_OUT_OF_MEM;
		schemeURIlen = (u32) strlen(data);
		if (bytesToRead > schemeURIlen+1) {
			/* read the value */
			char *data_value = data + schemeURIlen +1;
			ptr->value = gf_strdup(data_value);
			if (!ptr->value) return GF_OUT_OF_MEM;
		}
		gf_free(data);
	}
	return GF_OK;
}

GF_Box *kind_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err kind_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_KindBox *ptr = (GF_KindBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->schemeURI)
		gf_bs_write_data(bs, ptr->schemeURI, (u32) (strlen(ptr->schemeURI) + 1 ));
	else
		gf_bs_write_u8(bs, 0);

	if (ptr->value) {
		gf_bs_write_data(bs, ptr->value, (u32) (strlen(ptr->value) + 1) );
	}
	return GF_OK;
}

GF_Err kind_box_size(GF_Box *s)
{
	GF_KindBox *ptr = (GF_KindBox *)s;

	ptr->size += (ptr->schemeURI ? strlen(ptr->schemeURI) : 0) + 1;
	if (ptr->value) {
		ptr->size += strlen(ptr->value) + 1;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void prsl_box_del(GF_Box *s)
{
	GF_PreselectionGroupBox *ptr = (GF_PreselectionGroupBox *) s;
	if (ptr == NULL) return;
	if (s->child_boxes) gf_isom_box_array_del(s->child_boxes);
	if (ptr->entity_id_count && ptr->entity_ids) gf_free(ptr->entity_ids);
	if (ptr->preselection_tag) gf_free(ptr->preselection_tag);
	if (ptr->interleaving_tag) gf_free(ptr->interleaving_tag);
	gf_free(ptr);
}

#define GF_READ_STRING_WITH_0END(bs, ptr, size) \
    { \
        char *x_data; \
        u32 x_i = 0; \
        GF_SAFE_ALLOC_N(x_data, (size) + 1, char); \
        while (gf_bs_available(bs) && x_i < (size)) { \
            x_data[x_i] = (char) gf_bs_read_u8(bs); \
            if (x_data[x_i] == '\0') break; \
            x_i++; \
        } \
        x_data[(size)] = '\0'; \
        ptr = gf_strdup(x_data); \
        gf_free(x_data); \
		if (!ptr) return GF_OUT_OF_MEM; \
    }

GF_Err prsl_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i, size, str_len;
	GF_PreselectionGroupBox *ptr = (GF_PreselectionGroupBox *)s;

	ptr->version = gf_bs_read_int(bs, 8);
	ptr->flags = gf_bs_read_int(bs, 24);
	ISOM_DECREASE_SIZE(ptr, 4)

	ptr->group_id = gf_bs_read_u32(bs);
	ptr->entity_id_count = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 8)

	if ((u64) ptr->entity_id_count > (u64) SIZE_MAX / sizeof(u32)) {
		return GF_OUT_OF_MEM;
	}
	if ((u64) ptr->entity_id_count > ptr->size / 4) {
		return GF_ISOM_INVALID_FILE;
	}

	if (ptr->entity_id_count) {
		ptr->entity_ids = (u32 *) gf_malloc(ptr->entity_id_count * sizeof(u32));
		if (!ptr->entity_ids) return GF_OUT_OF_MEM;
	}
	for (i = 0; i < ptr->entity_id_count; i++) {
		ptr->entity_ids[i] = gf_bs_read_u32(bs);
	}
	ISOM_DECREASE_SIZE(ptr, 4 * ptr->entity_id_count)

	size = (u32) ptr->size;

	if (ptr->flags & GF_ISOM_PRESELECTION_TAG_PRESENT) {
		GF_READ_STRING_WITH_0END(bs, ptr->preselection_tag, size);

		str_len = (u32) strlen(ptr->preselection_tag) + 1;
		ISOM_DECREASE_SIZE(ptr, str_len)
	}
	if (ptr->flags & GF_ISOM_SELECTION_PRIORITY_PRESENT) {
		ptr->selection_priority = gf_bs_read_u8(bs);
		size -= 1;
		ISOM_DECREASE_SIZE(ptr, 1)
	}
	if (ptr->flags & GF_ISOM_INTERLEAVING_TAG_PRESENT) {
		GF_READ_STRING_WITH_0END(bs, ptr->interleaving_tag, size);

		str_len = (u32) strlen(ptr->interleaving_tag) + 1;
		ISOM_DECREASE_SIZE(ptr, str_len)
	}

	return gf_isom_box_array_read(s, bs);
}

GF_Box *prsl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PreselectionGroupBox, GF_ISOM_BOX_TYPE_PRSL);
	tmp->child_boxes = gf_list_new();
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err prsl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_PreselectionGroupBox *ptr = (GF_PreselectionGroupBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->group_id);
	gf_bs_write_u32(bs, ptr->entity_id_count);
	for (i = 0; i < ptr->entity_id_count; i++) {
		gf_bs_write_u32(bs, ptr->entity_ids[i]);
	}
	if (ptr->flags & GF_ISOM_PRESELECTION_TAG_PRESENT) {
		gf_bs_write_data(bs, ptr->preselection_tag, (u32) (strlen(ptr->preselection_tag) + 1 ));
	}
	if (ptr->flags & GF_ISOM_SELECTION_PRIORITY_PRESENT) {
		gf_bs_write_u8(bs, ptr->selection_priority);
	}
	if (ptr->flags & GF_ISOM_INTERLEAVING_TAG_PRESENT) {
		gf_bs_write_data(bs, ptr->interleaving_tag, (u32) (strlen(ptr->interleaving_tag) + 1 ));
	}

	return GF_OK;
}

GF_Err prsl_box_size(GF_Box *s)
{
	GF_PreselectionGroupBox *ptr = (GF_PreselectionGroupBox *)s;

	ptr->size += 12 + (4 * ptr->entity_id_count);
	if (ptr->flags & GF_ISOM_PRESELECTION_TAG_PRESENT) {
		ptr->size += strlen(ptr->preselection_tag) + 1;
	}
	if (ptr->flags & GF_ISOM_SELECTION_PRIORITY_PRESENT) {
		ptr->size += 1;
	}
	if (ptr->flags & GF_ISOM_INTERLEAVING_TAG_PRESENT) {
		ptr->size += strlen(ptr->interleaving_tag) + 1;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ardi_box_del(GF_Box *s)
{
	GF_AudioRenderingIndicationBox *ptr = (GF_AudioRenderingIndicationBox *) s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err ardi_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_AudioRenderingIndicationBox *ptr = (GF_AudioRenderingIndicationBox *)s;
	ptr->version = gf_bs_read_int(bs, 8);
	ptr->flags = gf_bs_read_int(bs, 24);
	ptr->audio_rendering_indication = gf_bs_read_u8(bs);
	return GF_OK;
}

GF_Box *ardi_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AudioRenderingIndicationBox, GF_ISOM_BOX_TYPE_ARDI);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ardi_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AudioRenderingIndicationBox *ptr = (GF_AudioRenderingIndicationBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->audio_rendering_indication);
	return GF_OK;
}

GF_Err ardi_box_size(GF_Box *s)
{
	GF_AudioRenderingIndicationBox *ptr = (GF_AudioRenderingIndicationBox *)s;

	ptr->size += 5;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void diap_box_del(GF_Box *s)
{
	GF_DialogueProcessingBox *ptr = (GF_DialogueProcessingBox *) s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err diap_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_DialogueProcessingBox *ptr = (GF_DialogueProcessingBox *)s;
	ptr->version = gf_bs_read_int(bs, 8);
	ptr->flags = gf_bs_read_int(bs, 24);
	ptr->dialog_gain = (s8) gf_bs_read_u8(bs);
	return GF_OK;
}

GF_Box *diap_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DialogueProcessingBox, GF_ISOM_BOX_TYPE_DIAP);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err diap_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DialogueProcessingBox *ptr = (GF_DialogueProcessingBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, (u8) ptr->dialog_gain);
	return GF_OK;
}

GF_Err diap_box_size(GF_Box *s)
{
	GF_DialogueProcessingBox *ptr = (GF_DialogueProcessingBox *)s;

	ptr->size += 5;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void labl_box_del(GF_Box *s)
{
	GF_LabelBox *ptr = (GF_LabelBox *) s;
	if (ptr == NULL) return;
	if (ptr->language) gf_free(ptr->language);
	if (ptr->label) gf_free(ptr->label);
	gf_free(ptr);
}

GF_Err labl_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_LabelBox *ptr = (GF_LabelBox *)s;
	u32 size;

	ptr->version = gf_bs_read_int(bs, 8);
	ptr->flags = gf_bs_read_int(bs, 24);

	ptr->label_id = gf_bs_read_u16(bs);
	size = (u32) ptr->size - 2;

	GF_READ_STRING_WITH_0END(bs, ptr->language, size);

	size -= (u32) strlen(ptr->language) + 1;

	GF_READ_STRING_WITH_0END(bs, ptr->label, size);

	return GF_OK;
}

GF_Box *labl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_LabelBox, GF_ISOM_BOX_TYPE_LABL);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err labl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_LabelBox *ptr = (GF_LabelBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u16(bs, ptr->label_id);
	if (ptr->language) {
		gf_bs_write_data(bs, ptr->language, (u32) (strlen(ptr->language) + 1 ));
	}
	if (ptr->label) {
		gf_bs_write_data(bs, ptr->label, (u32) (strlen(ptr->label) + 1));
	}
	return GF_OK;
}

GF_Err labl_box_size(GF_Box *s)
{
	GF_LabelBox *ptr = (GF_LabelBox *)s;

	ptr->size += 6;
	if (ptr->language) {
		ptr->size += strlen(ptr->language) + 1;
	}
	if (ptr->label) {
		ptr->size += strlen(ptr->label) + 1;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ctts_box_del(GF_Box *s)
{
	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}



GF_Err ctts_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	u32 sampleCount;
	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nb_entries = gf_bs_read_u32(bs);

	if (ptr->nb_entries > ptr->size / 8 || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(GF_DttsEntry) ) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->alloc_size = ptr->nb_entries;
	ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
	if (!ptr->entries) return GF_OUT_OF_MEM;
	sampleCount = 0;
	for (i=0; i<ptr->nb_entries; i++) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
		if (ptr->version)
			ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
		else {
			ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs);

			if (ptr->entries[i].decodingOffset <= INT_MIN) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid decodingOffset (%d) in entry #%i - defaulting to 0.\n", ptr->entries[i].decodingOffset, i));
				ptr->entries[i].decodingOffset = 0;
			}
			if (ptr->entries[i].decodingOffset<ptr->min_neg_cts_offset)
				ptr->min_neg_cts_offset = ptr->entries[i].decodingOffset;
		}

		if (ptr->entries[i].decodingOffset == INT_MIN) {
			ptr->max_cts_delta = INT_MAX;
		} else if (ptr->max_cts_delta <= ABS(ptr->entries[i].decodingOffset)) {
			ptr->max_cts_delta = ABS(ptr->entries[i].decodingOffset);
		}
		sampleCount += ptr->entries[i].sampleCount;
	}
#ifndef GPAC_DISABLE_ISOM_WRITE
	ptr->w_LastSampleNumber = sampleCount;
#endif
	return GF_OK;
}

GF_Box *ctts_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
	return (GF_Box *) tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ctts_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->nb_entries && !ptr->entries)
		return GF_ISOM_INVALID_MEDIA;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i=0; i<ptr->nb_entries; i++ ) {
		gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
		if (ptr->version) {
			gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
		} else {
			gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset);
		}
	}
	return GF_OK;
}

GF_Err ctts_box_size(GF_Box *s)
{
	GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *) s;

	ptr->size += 4 + (8 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void cslg_box_del(GF_Box *s)
{
	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
	return;
}

GF_Err cslg_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;

	if (s->version == 0) {
		ISOM_DECREASE_SIZE(ptr, 20);
		ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
		ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
		ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
		ptr->compositionStartTime = gf_bs_read_int(bs, 32);
		ptr->compositionEndTime = gf_bs_read_int(bs, 32);
		return GF_OK;
	} else if (s->version == 1) {
		ISOM_DECREASE_SIZE(ptr, 40);
		ptr->compositionToDTSShift = gf_bs_read_int(bs, 64);
		ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 64);
		ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 64);
		ptr->compositionStartTime = gf_bs_read_int(bs, 64);
		ptr->compositionEndTime = gf_bs_read_int(bs, 64);
		return GF_OK;
	}
	return GF_NOT_SUPPORTED;
}

GF_Box *cslg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err cslg_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (s->version == 0) {
		gf_bs_write_int(bs, (s32) ptr->compositionToDTSShift, 32);
		gf_bs_write_int(bs, (s32) ptr->leastDecodeToDisplayDelta, 32);
		gf_bs_write_int(bs, (s32) ptr->greatestDecodeToDisplayDelta, 32);
		gf_bs_write_int(bs, (s32) ptr->compositionStartTime, 32);
		gf_bs_write_int(bs, (s32) ptr->compositionEndTime, 32);
		return GF_OK;
	} else if (s->version == 1) {
		gf_bs_write_long_int(bs, ptr->compositionToDTSShift, 64);
		gf_bs_write_long_int(bs, ptr->leastDecodeToDisplayDelta, 64);
		gf_bs_write_long_int(bs, ptr->greatestDecodeToDisplayDelta, 64);
		gf_bs_write_long_int(bs, ptr->compositionStartTime, 64);
		gf_bs_write_long_int(bs, ptr->compositionEndTime, 64);
		return GF_OK;
	}
	return GF_NOT_SUPPORTED;
}

GF_Err cslg_box_size(GF_Box *s)
{
	GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
	if (s->version == 0) {
		ptr->size += 20;
		return GF_OK;
	} else if (s->version == 1) {
		ptr->size += 40;
		return GF_OK;
	}
	return GF_NOT_SUPPORTED;

}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ccst_box_del(GF_Box *s)
{
	GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
	if (ptr) gf_free(ptr);
	return;
}

GF_Err ccst_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->all_ref_pics_intra = gf_bs_read_int(bs, 1);
	ptr->intra_pred_used = gf_bs_read_int(bs, 1);
	ptr->max_ref_per_pic = gf_bs_read_int(bs, 4);
	ptr->reserved = gf_bs_read_int(bs, 26);
	return GF_OK;
}

GF_Box *ccst_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CodingConstraintsBox, GF_ISOM_BOX_TYPE_CCST);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ccst_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, ptr->all_ref_pics_intra, 1);
	gf_bs_write_int(bs, ptr->intra_pred_used, 1);
	gf_bs_write_int(bs, ptr->max_ref_per_pic, 4);
	gf_bs_write_int(bs, 0, 26);
	return GF_OK;
}

GF_Err ccst_box_size(GF_Box *s)
{
	GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
	ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void url_box_del(GF_Box *s)
{
	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
	if (ptr == NULL) return;
	if (ptr->location) gf_free(ptr->location);
	gf_free(ptr);
	return;
}


GF_Err url_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;

	//imdt case
	if (ptr->type == GF_ISOM_BOX_TYPE_IMDT) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->imda_ref_id = gf_bs_read_u32(bs);
		return GF_OK;
	}

	if (ptr->size) {
		u32 location_size = (u32) ptr->size;
		if (location_size < 1) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in svhd box\n", ptr->size));
			return GF_ISOM_INVALID_FILE;
		}
		ptr->location = (char*)gf_malloc(location_size);
		if (! ptr->location) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->location, location_size);
		if (ptr->location[location_size-1]) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] url box location is not 0-terminated\n" ));
			return GF_ISOM_INVALID_FILE;
		}
	}
	return GF_OK;
}

GF_Box *url_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err url_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//imdt case
	if (ptr->type == GF_ISOM_BOX_TYPE_IMDT) {
		gf_bs_write_u32(bs, ptr->imda_ref_id);
		return GF_OK;
	}
	//the flag set indicates we have a string (WE HAVE TO for URLs)
	if ( !(ptr->flags & 1)) {
		if (ptr->location) {
			gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
		}
	}
	return GF_OK;
}

GF_Err url_box_size(GF_Box *s)
{
	GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;

	//imdt case
	if (ptr->type == GF_ISOM_BOX_TYPE_IMDT) {
		ptr->size+=4;
		return GF_OK;
	}
	if ( !(ptr->flags & 1)) {
		if (ptr->location) ptr->size += 1 + strlen(ptr->location);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void urn_box_del(GF_Box *s)
{
	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
	if (ptr == NULL) return;
	if (ptr->location) gf_free(ptr->location);
	if (ptr->nameURN) gf_free(ptr->nameURN);
	gf_free(ptr);
}


GF_Err urn_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, to_read;
	char *tmpName;
	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
	if (! ptr->size ) return GF_OK;

	//here we have to handle that in a clever way
	to_read = (u32) ptr->size;
	tmpName = (char*)gf_malloc(sizeof(char) * to_read);
	if (!tmpName) return GF_OUT_OF_MEM;
	//get the data
	gf_bs_read_data(bs, tmpName, to_read);

	//then get the break
	i = 0;
	while ( (i < to_read) && (tmpName[i] != 0) ) {
		i++;
	}
	//check the data is consistent
	if (i == to_read) {
		gf_free(tmpName);
		return GF_ISOM_INVALID_FILE;
	}
	//no NULL char, URL is not specified
	if (i == to_read - 1) {
		ptr->nameURN = tmpName;
		ptr->location = NULL;
		return GF_OK;
	}
	//OK, this has both URN and URL
	ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1));
	if (!ptr->nameURN) {
		gf_free(tmpName);
		return GF_OUT_OF_MEM;
	}
	memcpy(ptr->nameURN, tmpName, i + 1);

	if (tmpName[to_read - 1] != 0) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] urn box contains invalid location field\n" ));
	}
	else {
		ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1));
		if (!ptr->location) {
			gf_free(tmpName);
			gf_free(ptr->nameURN);
			ptr->nameURN = NULL;
			return GF_OUT_OF_MEM;
		}
		memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1));
	}

	gf_free(tmpName);
	return GF_OK;
}

GF_Box *urn_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err urn_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//the flag set indicates we have a string (WE HAVE TO for URLs)
	if ( !(ptr->flags & 1)) {
		//to check, the spec says: First name, then location
		if (ptr->nameURN) {
			gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1);
		}
		if (ptr->location) {
			gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
		}
	}
	return GF_OK;
}

GF_Err urn_box_size(GF_Box *s)
{
	GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;

	if ( !(ptr->flags & 1)) {
		if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN);
		if (ptr->location) ptr->size += 1 + strlen(ptr->location);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void unkn_box_del(GF_Box *s)
{
	GF_UnknownBox *ptr = (GF_UnknownBox *) s;
	if (!s) return;
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}


GF_Err unkn_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 bytesToRead, sub_size, sub_a;
	GF_BitStream *sub_bs;
	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
	if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
	bytesToRead = (u32) (ptr->size);

	if (!bytesToRead) return GF_OK;
	if (bytesToRead>1000000) {
		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->original_4cc), ptr->original_4cc ));
		gf_bs_skip_bytes(bs, ptr->dataSize);
		return GF_OK;
	}

	ptr->data = (char*)gf_malloc(bytesToRead);
	if (ptr->data == NULL ) return GF_OUT_OF_MEM;
	ptr->dataSize = bytesToRead;
	gf_bs_read_data(bs, ptr->data, ptr->dataSize);

	//don't try to load sub boxes if already in udta child box loading
	if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_IN_UDTA) {
		return GF_OK;
	}

	//try to parse container boxes, check if next 8 bytes match a subbox
	sub_bs = gf_bs_new(ptr->data, ptr->dataSize, GF_BITSTREAM_READ);
	sub_size = gf_bs_read_u32(sub_bs);
	sub_a = gf_bs_read_u8(sub_bs);
	e = (sub_size && (sub_size <= ptr->dataSize)) ? GF_OK : GF_NOT_SUPPORTED;
	if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
	sub_a = gf_bs_read_u8(sub_bs);
	if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
	sub_a = gf_bs_read_u8(sub_bs);
	if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
	sub_a = gf_bs_read_u8(sub_bs);
	if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;

	if (e == GF_OK) {
		gf_bs_seek(sub_bs, 0);
		gf_bs_set_cookie(sub_bs, GF_ISOM_BS_COOKIE_NO_LOGS|GF_ISOM_BS_COOKIE_IN_UDTA);
		e = gf_isom_box_array_read(s, sub_bs);
	}
	gf_bs_del(sub_bs);
	if (e==GF_OK) {
		gf_free(ptr->data);
		ptr->data = NULL;
		ptr->dataSize = 0;
	} else if (s->child_boxes) {
		gf_isom_box_array_del(s->child_boxes);
		s->child_boxes=NULL;
	}

	return GF_OK;
}

GF_Box *unkn_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err unkn_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 type;
	GF_UnknownBox *ptr = (GF_UnknownBox *)s;
	if (!s) return GF_BAD_PARAM;
	if (ptr->original_4cc == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	type = s->type;
	ptr->type = ptr->original_4cc;
	e = gf_isom_box_write_header(s, bs);
	ptr->type = type;
	if (e) return e;

	if (ptr->sai_type) {
		if (ptr->saio_box) {
			u64 pos = gf_bs_get_position(bs);
			gf_bs_seek(bs, ptr->saio_box->offset_first_offset_field);
			if (ptr->saio_box->version)
				gf_bs_write_u64(bs, pos);
			else
				gf_bs_write_u32(bs, (u32) pos);
			gf_bs_seek(bs, pos);
		} else {
			ptr->sai_offset = gf_bs_get_position(bs);
		}
	}

	if (ptr->dataSize && ptr->data) {
		gf_bs_write_data(bs, ptr->data, ptr->dataSize);
	}
	return GF_OK;
}

GF_Err unkn_box_size(GF_Box *s)
{
	GF_UnknownBox *ptr = (GF_UnknownBox *)s;

	if (ptr->dataSize && ptr->data) {
		ptr->size += ptr->dataSize;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void def_parent_box_del(GF_Box *s)
{
	if (s) gf_free(s);
}


GF_Err def_parent_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *def_parent_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, 0);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err def_parent_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err def_parent_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void def_parent_full_box_del(GF_Box *s)
{
	if (s) gf_free(s);
}


GF_Err def_parent_full_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *def_parent_full_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, 0);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err def_parent_full_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err def_parent_full_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void uuid_box_del(GF_Box *s)
{
	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s;
	if (!s) return;
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}


GF_Err uuid_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 bytesToRead;
	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
	if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
	bytesToRead = (u32) (ptr->size);

	if (bytesToRead) {
		ptr->data = (char*)gf_malloc(bytesToRead);
		if (ptr->data == NULL ) return GF_OUT_OF_MEM;
		ptr->dataSize = bytesToRead;
		gf_bs_read_data(bs, ptr->data, ptr->dataSize);
	}
	return GF_OK;
}

GF_Box *uuid_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err uuid_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	if (ptr->data) {
		gf_bs_write_data(bs, ptr->data, ptr->dataSize);
	}
	return GF_OK;
}

GF_Err uuid_box_size(GF_Box *s)
{
	GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s;
	ptr->size += ptr->dataSize;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void dinf_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err dinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_DREF:
		BOX_FIELD_ASSIGN(dref, GF_DataReferenceBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err dinf_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DataInformationBox *dinf;
	GF_Err e = gf_isom_box_array_read(s, bs);
	if (e) {
		return e;
	}
	dinf = (GF_DataInformationBox *)s;
	if (!dinf->dref) {
		if (! (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_NO_LOGS) ) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing dref box in dinf\n"));
		}
		dinf->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&dinf->child_boxes, GF_ISOM_BOX_TYPE_DREF);
	}
	return GF_OK;
}

GF_Box *dinf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dinf_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err dinf_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void dref_box_del(GF_Box *s)
{
	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err dref_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	gf_bs_read_u32(bs);
	return gf_isom_box_array_read(s, bs);
}

GF_Box *dref_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dref_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 count;
	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	count = ptr->child_boxes ? gf_list_count(ptr->child_boxes) : 0;
	gf_bs_write_u32(bs, count);
	return GF_OK;
}

GF_Err dref_box_size(GF_Box *s)
{
	GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
	if (!s) return GF_BAD_PARAM;

	ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void edts_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err edts_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_EditBox *ptr = (GF_EditBox *)s;
	if (a->type == GF_ISOM_BOX_TYPE_ELST) {
		BOX_FIELD_ASSIGN(editList, GF_EditListBox)
		return GF_OK;
	} else {
		return GF_OK;
	}
	return GF_OK;
}


GF_Err edts_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *edts_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
	return (GF_Box *) tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err edts_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_EditBox *ptr = (GF_EditBox *)s;

	//here we have a trick: if editList is empty, skip the box
	if (ptr->editList && gf_list_count(ptr->editList->entryList)) {
		return gf_isom_box_write_header(s, bs);
	} else {
		s->size = 0;
	}
	return GF_OK;
}

GF_Err edts_box_size(GF_Box *s)
{
	GF_EditBox *ptr = (GF_EditBox *)s;

	//here we have a trick: if editList is empty, skip the box
	if (!ptr->editList || ! gf_list_count(ptr->editList->entryList)) {
		ptr->size = 0;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void elst_box_del(GF_Box *s)
{
	GF_EditListBox *ptr;
	u32 nb_entries;
	u32 i;

	ptr = (GF_EditListBox *)s;
	if (ptr == NULL) return;
	nb_entries = gf_list_count(ptr->entryList);
	for (i = 0; i < nb_entries; i++) {
		GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
		if (p) gf_free(p);
	}
	gf_list_del(ptr->entryList);
	gf_free(ptr);
}

GF_Err elst_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 entries;
	s32 tr;
	u32 nb_entries;
	GF_EditListBox *ptr = (GF_EditListBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	nb_entries = gf_bs_read_u32(bs);

	if (ptr->version == 1) {
		if (nb_entries > ptr->size / 20) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	} else {
		if (nb_entries > ptr->size / 12) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	}


	for (entries = 0; entries < nb_entries; entries++) {
		GF_EdtsEntry *p;
		GF_SAFEALLOC(p, GF_EdtsEntry);
		if (!p) return GF_OUT_OF_MEM;
		if (ptr->version == 1) {
			ISOM_DECREASE_SIZE(ptr, 16);
			p->segmentDuration = gf_bs_read_u64(bs);
			p->mediaTime = (s64) gf_bs_read_u64(bs);
		} else {
			ISOM_DECREASE_SIZE(ptr, 8);
			p->segmentDuration = gf_bs_read_u32(bs);
			tr = gf_bs_read_u32(bs);
			p->mediaTime = (s64) tr;
		}
		ISOM_DECREASE_SIZE(ptr, 4);
		p->mediaRate = gf_bs_read_u32(bs);
		gf_list_add(ptr->entryList, p);
	}
	return GF_OK;
}

GF_Box *elst_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
	tmp->entryList = gf_list_new();
	if (!tmp->entryList) {
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err elst_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	u32 nb_entries;
	GF_EditListBox *ptr = (GF_EditListBox *)s;
	if (!ptr) return GF_BAD_PARAM;

	nb_entries = gf_list_count(ptr->entryList);
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, nb_entries);
	for (i = 0; i < nb_entries; i++ ) {
		GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
		if (ptr->version == 1) {
			gf_bs_write_u64(bs, p->segmentDuration);
			gf_bs_write_u64(bs, p->mediaTime);
		} else {
			gf_bs_write_u32(bs, (u32) p->segmentDuration);
			gf_bs_write_u32(bs, (s32) p->mediaTime);
		}
		gf_bs_write_u32(bs, p->mediaRate);
	}
	return GF_OK;
}

GF_Err elst_box_size(GF_Box *s)
{
	u32 durtimebytes;
	u32 i, nb_entries;
	GF_EditListBox *ptr = (GF_EditListBox *)s;

	//entry count
	ptr->size += 4;
	nb_entries = gf_list_count(ptr->entryList);
	ptr->version = 0;
	for (i=0; i<nb_entries; i++) {
		GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
		if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) {
			ptr->version = 1;
			break;
		}
	}
	durtimebytes = (ptr->version == 1 ? 16 : 8) + 4;
	ptr->size += (nb_entries * durtimebytes);
	return GF_OK;
}


#endif /*GPAC_DISABLE_ISOM_WRITE*/

void esds_box_del(GF_Box *s)
{
	GF_ESDBox *ptr = (GF_ESDBox *)s;
	if (ptr == NULL)	return;
	if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc);
	gf_free(ptr);
}


GF_Err esds_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e=GF_OK;
	u32 descSize;
	GF_ESDBox *ptr = (GF_ESDBox *)s;

	descSize = (u32) (ptr->size);

	if (descSize) {
		char *enc_desc = (char*)gf_malloc(sizeof(char) * descSize);
		if (!enc_desc) return GF_OUT_OF_MEM;
		//get the payload
		gf_bs_read_data(bs, enc_desc, descSize);
		//send it to the OD Codec
		e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc);
		//OK, free our desc
		gf_free(enc_desc);

		if (ptr->desc && (ptr->desc->tag!=GF_ODF_ESD_TAG) ) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor tag 0x%x in esds\n", ptr->desc->tag));
			gf_odf_desc_del((GF_Descriptor*)ptr->desc);
			ptr->desc=NULL;
			return GF_ISOM_INVALID_FILE;
		}

		if (e) {
			ptr->desc = NULL;
		} else {
			/*fix broken files*/
			if (ptr->desc && !ptr->desc->URLString) {
				if (!ptr->desc->slConfig) {
					ptr->desc->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
					ptr->desc->slConfig->predefined = SLPredef_MP4;
				} else if (ptr->desc->slConfig->predefined != SLPredef_MP4) {
					ptr->desc->slConfig->predefined = SLPredef_MP4;
					gf_odf_slc_set_pref(ptr->desc->slConfig);
				}
			}
		}
	}
	return e;
}

GF_Box *esds_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err esds_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u8 *enc_desc;
	u32 descSize = 0;
	GF_ESDBox *ptr = (GF_ESDBox *)s;
	//make sure we write with no ESID and no OCRESID
	if (ptr->desc) {
		ptr->desc->ESID = 0;
		ptr->desc->OCRESID = 0;
	}
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize);
	if (e) return e;
	gf_bs_write_data(bs, enc_desc, descSize);
	//free our buffer
	gf_free(enc_desc);
	return GF_OK;
}

GF_Err esds_box_size(GF_Box *s)
{
	u32 descSize = 0;
	GF_ESDBox *ptr = (GF_ESDBox *)s;
	//make sure we write with no ESID and no OCRESID
	if (ptr->desc) {
		ptr->desc->ESID = 0;
		ptr->desc->OCRESID = 0;
	}
	descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc);
	ptr->size += descSize;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void free_box_del(GF_Box *s)
{
	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}


GF_Err free_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 bytesToRead;
	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;

	if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR;

	bytesToRead = (u32) (ptr->size);

	if (bytesToRead) {
		ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char));
		if (!ptr->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->data, bytesToRead);
		ptr->dataSize = bytesToRead;
	}
	return GF_OK;
}

GF_Box *free_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err free_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
	if (ptr->original_4cc) {
		u32 t = s->type;
		s->type=ptr->original_4cc;
		e = gf_isom_box_write_header(s, bs);
		s->type=t;
	} else {
		e = gf_isom_box_write_header(s, bs);
	}
	if (e) return e;
	if (ptr->dataSize)	{
		if (ptr->data) {
			gf_bs_write_data(bs, ptr->data, ptr->dataSize);
		} else {
			u32 i = 0;
			while (i<ptr->dataSize) {
				gf_bs_write_u8(bs, 0);
				i++;
			}
		}
	}
	return GF_OK;
}

GF_Err free_box_size(GF_Box *s)
{
	GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
	ptr->size += ptr->dataSize;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ftyp_box_del(GF_Box *s)
{
	GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
	if (ptr->altBrand) gf_free(ptr->altBrand);
	gf_free(ptr);
}

GF_Box *ftyp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
	return (GF_Box *)tmp;
}

GF_Err ftyp_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->majorBrand = gf_bs_read_u32(bs);
	ptr->minorVersion = gf_bs_read_u32(bs);

	if (ptr->size % 4) return GF_ISOM_INVALID_FILE;
	ptr->altCount = ( (u32) (ptr->size)) / 4;
	if (!ptr->altCount) return GF_OK;

	ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount);
	if (!ptr->altBrand) return GF_OUT_OF_MEM;

	for (i = 0; i<ptr->altCount; i++) {
		ptr->altBrand[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ftyp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->majorBrand);
	gf_bs_write_u32(bs, ptr->minorVersion);
	for (i=0; i<ptr->altCount; i++) {
		gf_bs_write_u32(bs, ptr->altBrand[i]);
	}
	return GF_OK;
}

GF_Err ftyp_box_size(GF_Box *s)
{
	GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;

	ptr->size += 8 + ptr->altCount * 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void gnrm_box_del(GF_Box *s)
{
	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}

GF_Box *gnrm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);

	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}

GF_Err gnrm_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
	GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
	if (e) return e;
	ISOM_DECREASE_SIZE(ptr, 8)
	if (ptr->size) {
		ptr->data_size = (u32) ptr->size;
		ptr->data = (char*)gf_malloc(ptr->data_size * sizeof(char));
		if (!ptr->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->data, ptr->data_size);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err gnrm_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;

	//careful we are not writing the box type but the entry type so switch for write
	if (ptr->EntryType == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	ptr->type = ptr->EntryType;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	ptr->type = GF_ISOM_BOX_TYPE_GNRM;
	gf_bs_write_data(bs, ptr->reserved, 6);
	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
	gf_bs_write_data(bs,  ptr->data, ptr->data_size);
	return GF_OK;
}

GF_Err gnrm_box_size(GF_Box *s)
{
	GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
	s->type = GF_ISOM_BOX_TYPE_GNRM;
	ptr->size += 8+ptr->data_size;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void gnrv_box_del(GF_Box *s)
{
	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}

GF_Box *gnrv_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
	gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp);
	return (GF_Box *)tmp;
}

GF_Err gnrv_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
	GF_Err e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)ptr, bs);
	if (e) return e;
	if (ptr->size) {
		ptr->data_size = (u32) ptr->size;
		ptr->data = (char*)gf_malloc(ptr->data_size * sizeof(char));
		if (!ptr->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->data, ptr->data_size);
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err gnrv_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;

	//careful we are not writing the box type but the entry type so switch for write
	if (ptr->EntryType == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	ptr->type = ptr->EntryType;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	ptr->type = GF_ISOM_BOX_TYPE_GNRV;

	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs);
	gf_bs_write_data(bs,  ptr->data, ptr->data_size);
	return GF_OK;
}

GF_Err gnrv_box_size(GF_Box *s)
{
	GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
	s->type = GF_ISOM_BOX_TYPE_GNRV;
	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
	ptr->size += ptr->data_size;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void gnra_box_del(GF_Box *s)
{
	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}

GF_Box *gnra_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp);
	return (GF_Box *)tmp;
}

GF_Err gnra_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
	GF_Err e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *)ptr, bs);
	if (e) return e;
	if (ptr->size) {
		ptr->data_size = (u32) ptr->size;
		ptr->data = (char*)gf_malloc(ptr->data_size * sizeof(char));
		if (!ptr->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->data, ptr->data_size);
	}
	return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err gnra_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;

	//careful we are not writing the box type but the entry type so switch for write
	if (ptr->EntryType == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	ptr->type = ptr->EntryType;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	ptr->type = GF_ISOM_BOX_TYPE_GNRA;

	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs);
	if (ptr->data) {
		gf_bs_write_data(bs,  ptr->data, ptr->data_size);
	}
	return GF_OK;
}

GF_Err gnra_box_size(GF_Box *s)
{
	GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
	s->type = GF_ISOM_BOX_TYPE_GNRA;
	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s);
	ptr->size += ptr->data_size;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void hdlr_box_del(GF_Box *s)
{
	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
	if (ptr == NULL) return;
	if (ptr->nameUTF8) gf_free(ptr->nameUTF8);
	gf_free(ptr);
}


GF_Err hdlr_box_read(GF_Box *s, GF_BitStream *bs)
{
	u64 cookie;
	GF_HandlerBox *ptr = (GF_HandlerBox *)s;

	ISOM_DECREASE_SIZE(ptr, 20);
	ptr->reserved1 = gf_bs_read_u32(bs);
	ptr->handlerType = gf_bs_read_u32(bs);
	gf_bs_read_data(bs, (char*)ptr->reserved2, 12);

	cookie = gf_bs_get_cookie(bs);
	if (ptr->handlerType==GF_ISOM_MEDIA_VISUAL)
		cookie |= GF_ISOM_BS_COOKIE_VISUAL_TRACK;
	else
		cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
	gf_bs_set_cookie(bs, cookie);

	if (ptr->size) {
		u32 name_size = (u32) ptr->size;
		if (name_size < 1) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in hdlr\n", ptr->size));
			return GF_ISOM_INVALID_FILE;
		}
		ptr->nameUTF8 = (char*)gf_malloc(name_size);
		if (!ptr->nameUTF8) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->nameUTF8, name_size);

		//patch for old QT files - we cannot rely on checking if str[0]==len(str+1) since we may have
		//cases where the first character of the string decimal value is indeed the same as the string length!!
		//we had this issue with encryption_import test
		//we therefore only check if last char is null, and if not so assume old QT style
		if (ptr->nameUTF8[name_size-1]) {
			if (name_size > 1)
				memmove(ptr->nameUTF8, ptr->nameUTF8+1, sizeof(char) * (u32) (name_size-1) );
			ptr->nameUTF8[name_size-1] = 0;
			ptr->store_counted_string = GF_TRUE;
		}
	}
	return GF_OK;
}

GF_Box *hdlr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err hdlr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->reserved1);
	gf_bs_write_u32(bs, ptr->handlerType);
	gf_bs_write_data(bs, (char*)ptr->reserved2, 12);

	if (ptr->nameUTF8) {
		u32 len = (u32)strlen(ptr->nameUTF8);
		if (ptr->store_counted_string) {
			gf_bs_write_u8(bs, len);
			gf_bs_write_data(bs, ptr->nameUTF8, len);
		} else {
			gf_bs_write_data(bs, ptr->nameUTF8, len);
			gf_bs_write_u8(bs, 0);
		}
	} else {
		gf_bs_write_u8(bs, 0);
	}
	return GF_OK;
}

GF_Err hdlr_box_size(GF_Box *s)
{
	GF_HandlerBox *ptr = (GF_HandlerBox *)s;
	ptr->size += 20 + 1; //null term or counted string
	if (ptr->nameUTF8) {
		ptr->size += strlen(ptr->nameUTF8);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void hinf_box_del(GF_Box *s)
{
	GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
	gf_free(hinf);
}

GF_Box *hinf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);

	tmp->child_boxes = gf_list_new();
	return (GF_Box *)tmp;
}

GF_Err hinf_on_child_box(GF_Box *s, GF_Box *_a, Bool is_rem)
{
	GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
	switch (_a->type) {
	case GF_ISOM_BOX_TYPE_MAXR:
		if (!is_rem) {
			u32 i=0;
			GF_MAXRBox *a = (GF_MAXRBox *)_a;
			GF_MAXRBox *maxR;
			while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->child_boxes, &i))) {
				if ((maxR != a) && (maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == a->granularity))
					ERROR_ON_DUPLICATED_BOX(_a, s)
			}
		}
		break;
	}
	return GF_OK;
}


GF_Err hinf_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err hinf_box_write(GF_Box *s, GF_BitStream *bs)
{
//	GF_HintInfoBox *ptr = (GF_HintInfoBox *)s;
	if (!s) return GF_BAD_PARAM;
	return gf_isom_box_write_header(s, bs);
}

GF_Err hinf_box_size(GF_Box *s)
{
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

void hmhd_box_del(GF_Box *s)
{
	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err hmhd_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;

	ISOM_DECREASE_SIZE(ptr, 16);
	ptr->maxPDUSize = gf_bs_read_u16(bs);
	ptr->avgPDUSize = gf_bs_read_u16(bs);
	ptr->maxBitrate = gf_bs_read_u32(bs);
	ptr->avgBitrate = gf_bs_read_u32(bs);
	ptr->slidingAverageBitrate = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *hmhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err hmhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u16(bs, ptr->maxPDUSize);
	gf_bs_write_u16(bs, ptr->avgPDUSize);
	gf_bs_write_u32(bs, ptr->maxBitrate);
	gf_bs_write_u32(bs, ptr->avgBitrate);
	gf_bs_write_u32(bs, ptr->slidingAverageBitrate);
	return GF_OK;
}

GF_Err hmhd_box_size(GF_Box *s)
{
	GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
	ptr->size += 16;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *hnti_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
	return (GF_Box *)tmp;
}

void hnti_box_del(GF_Box *a)
{
	gf_free(a);
}

GF_Err hnti_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_HintTrackInfoBox *ptr = (GF_HintTrackInfoBox *)s;
	if (!ptr || !a) return GF_BAD_PARAM;

	switch (a->type) {
	//this is the value for GF_RTPBox - same as HintSampleEntry for RTP !!!
	case GF_ISOM_BOX_TYPE_RTP:
	case GF_ISOM_BOX_TYPE_SDP:
		BOX_FIELD_ASSIGN(SDP, GF_Box)
		break;
	default:
		break;
	}
	return GF_OK;
}

GF_Err hnti_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err hnti_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}


GF_Err hnti_box_size(GF_Box *s)
{
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/**********************************************************
		GF_SDPBox
**********************************************************/

void sdp_box_del(GF_Box *s)
{
	GF_SDPBox *ptr = (GF_SDPBox *)s;
	if (ptr->sdpText) gf_free(ptr->sdpText);
	gf_free(ptr);

}
GF_Err sdp_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 length;
	GF_SDPBox *ptr = (GF_SDPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	length = (u32) (ptr->size);

	if (length >= (u32)0xFFFFFFFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid length %lu in sdp box\n", length));
		return GF_ISOM_INVALID_FILE;
	}

	//sdp text has no delimiter !!!
	ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
	if (!ptr->sdpText) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, ptr->sdpText, length);
	ptr->sdpText[length] = 0;
	return GF_OK;
}
GF_Box *sdp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sdp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SDPBox *ptr = (GF_SDPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	//don't write the NULL char!!!
	if (ptr->sdpText)
		gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
	return GF_OK;
}
GF_Err sdp_box_size(GF_Box *s)
{
	GF_SDPBox *ptr = (GF_SDPBox *)s;
	//don't count the NULL char!!!
	if (ptr->sdpText)
		ptr->size += strlen(ptr->sdpText);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/




void rtp_hnti_box_del(GF_Box *s)
{
	GF_RTPBox *ptr = (GF_RTPBox *)s;
	if (ptr->sdpText) gf_free(ptr->sdpText);
	gf_free(ptr);

}
GF_Err rtp_hnti_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 length;
	GF_RTPBox *ptr = (GF_RTPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->subType = gf_bs_read_u32(bs);

	length = (u32) (ptr->size);

	if (length >= (u32)0xFFFFFFFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid length %lu in rtp_hnti box\n", length));
		return GF_ISOM_INVALID_FILE;
	}

	//sdp text has no delimiter !!!
	ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
	if (!ptr->sdpText) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, ptr->sdpText, length);
	ptr->sdpText[length] = 0;
	return GF_OK;
}

GF_Box *rtp_hnti_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_RTPBox, GF_ISOM_BOX_TYPE_RTP);
	tmp->subType = GF_ISOM_BOX_TYPE_SDP;
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rtp_hnti_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_RTPBox *ptr = (GF_RTPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->subType);
	//don't write the NULL char!!!
	gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
	return GF_OK;
}

GF_Err rtp_hnti_box_size(GF_Box *s)
{
	GF_RTPBox *ptr = (GF_RTPBox *)s;
	ptr->size += 4 + strlen(ptr->sdpText);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		TRPY GF_Box
**********************************************************/

void trpy_box_del(GF_Box *s)
{
	gf_free((GF_TRPYBox *)s);
}
GF_Err trpy_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TRPYBox *ptr = (GF_TRPYBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->nbBytes = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *trpy_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err trpy_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TRPYBox *ptr = (GF_TRPYBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err trpy_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/**********************************************************
		TOTL GF_Box
**********************************************************/

void totl_box_del(GF_Box *s)
{
	gf_free((GF_TRPYBox *)s);
}
GF_Err totl_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TOTLBox *ptr = (GF_TOTLBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nbBytes = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *totl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err totl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TOTLBox *ptr = (GF_TOTLBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err totl_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		NUMP GF_Box
**********************************************************/

void nump_box_del(GF_Box *s)
{
	gf_free((GF_NUMPBox *)s);
}
GF_Err nump_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_NUMPBox *ptr = (GF_NUMPBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->nbPackets = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *nump_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err nump_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_NUMPBox *ptr = (GF_NUMPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbPackets);
	return GF_OK;
}
GF_Err nump_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		NPCK GF_Box
**********************************************************/

void npck_box_del(GF_Box *s)
{
	gf_free((GF_NPCKBox *)s);
}
GF_Err npck_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_NPCKBox *ptr = (GF_NPCKBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nbPackets = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *npck_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err npck_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_NPCKBox *ptr = (GF_NPCKBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nbPackets);
	return GF_OK;
}
GF_Err npck_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		TPYL GF_Box
**********************************************************/

void tpyl_box_del(GF_Box *s)
{
	gf_free((GF_NTYLBox *)s);
}
GF_Err tpyl_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_NTYLBox *ptr = (GF_NTYLBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->nbBytes = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *tpyl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tpyl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_NTYLBox *ptr = (GF_NTYLBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err tpyl_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/**********************************************************
		TPAY GF_Box
**********************************************************/

void tpay_box_del(GF_Box *s)
{
	gf_free((GF_TPAYBox *)s);
}
GF_Err tpay_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TPAYBox *ptr = (GF_TPAYBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nbBytes = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *tpay_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tpay_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TPAYBox *ptr = (GF_TPAYBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err tpay_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		MAXR GF_Box
**********************************************************/

void maxr_box_del(GF_Box *s)
{
	gf_free((GF_MAXRBox *)s);
}
GF_Err maxr_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MAXRBox *ptr = (GF_MAXRBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->granularity = gf_bs_read_u32(bs);
	ptr->maxDataRate = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *maxr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err maxr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MAXRBox *ptr = (GF_MAXRBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->granularity);
	gf_bs_write_u32(bs, ptr->maxDataRate);
	return GF_OK;
}
GF_Err maxr_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		DMED GF_Box
**********************************************************/

void dmed_box_del(GF_Box *s)
{
	gf_free((GF_DMEDBox *)s);
}
GF_Err dmed_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DMEDBox *ptr = (GF_DMEDBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->nbBytes = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *dmed_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dmed_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DMEDBox *ptr = (GF_DMEDBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err dmed_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/**********************************************************
		DIMM GF_Box
**********************************************************/

void dimm_box_del(GF_Box *s)
{
	gf_free((GF_DIMMBox *)s);
}
GF_Err dimm_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DIMMBox *ptr = (GF_DIMMBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8)
	ptr->nbBytes = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *dimm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dimm_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DIMMBox *ptr = (GF_DIMMBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err dimm_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/**********************************************************
		DREP GF_Box
**********************************************************/

void drep_box_del(GF_Box *s)
{
	gf_free((GF_DREPBox *)s);
}
GF_Err drep_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DREPBox *ptr = (GF_DREPBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8)
	ptr->nbBytes = gf_bs_read_u64(bs);
	return GF_OK;
}
GF_Box *drep_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err drep_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DREPBox *ptr = (GF_DREPBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->nbBytes);
	return GF_OK;
}
GF_Err drep_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/



/**********************************************************
		TMIN GF_Box
**********************************************************/

void tmin_box_del(GF_Box *s)
{
	gf_free((GF_TMINBox *)s);
}
GF_Err tmin_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TMINBox *ptr = (GF_TMINBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->minTime = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *tmin_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tmin_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TMINBox *ptr = (GF_TMINBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->minTime);
	return GF_OK;
}
GF_Err tmin_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		TMAX GF_Box
**********************************************************/

void tmax_box_del(GF_Box *s)
{
	gf_free((GF_TMAXBox *)s);
}
GF_Err tmax_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TMAXBox *ptr = (GF_TMAXBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->maxTime = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *tmax_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tmax_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TMAXBox *ptr = (GF_TMAXBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->maxTime);
	return GF_OK;
}
GF_Err tmax_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		PMAX GF_Box
**********************************************************/

void pmax_box_del(GF_Box *s)
{
	gf_free((GF_PMAXBox *)s);
}
GF_Err pmax_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_PMAXBox *ptr = (GF_PMAXBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->maxSize = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *pmax_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err pmax_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PMAXBox *ptr = (GF_PMAXBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->maxSize);
	return GF_OK;
}
GF_Err pmax_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		DMAX GF_Box
**********************************************************/

void dmax_box_del(GF_Box *s)
{
	gf_free((GF_DMAXBox *)s);
}
GF_Err dmax_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DMAXBox *ptr = (GF_DMAXBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->maxDur = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *dmax_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dmax_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DMAXBox *ptr = (GF_DMAXBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->maxDur);
	return GF_OK;
}
GF_Err dmax_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		PAYT GF_Box
**********************************************************/

void payt_box_del(GF_Box *s)
{
	GF_PAYTBox *payt = (GF_PAYTBox *)s;
	if (payt->payloadString) gf_free(payt->payloadString);
	gf_free(payt);
}
GF_Err payt_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 length;
	GF_PAYTBox *ptr = (GF_PAYTBox *)s;

	ISOM_DECREASE_SIZE(ptr, 5 );
	ptr->payloadCode = gf_bs_read_u32(bs);
	length = gf_bs_read_u8(bs);
	ISOM_DECREASE_SIZE(ptr, length);
	ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) );
	if (! ptr->payloadString) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->payloadString, length);
	ptr->payloadString[length] = 0;

	return GF_OK;
}
GF_Box *payt_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err payt_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 len;
	GF_Err e;
	GF_PAYTBox *ptr = (GF_PAYTBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->payloadCode);
	len = ptr->payloadString ? (u32) strlen(ptr->payloadString) : 0;
	gf_bs_write_u8(bs, len);
	if (len) gf_bs_write_data(bs, ptr->payloadString, len);
	return GF_OK;
}
GF_Err payt_box_size(GF_Box *s)
{
	GF_PAYTBox *ptr = (GF_PAYTBox *)s;
	s->size += 4 + 1;
	if (ptr->payloadString) ptr->size += strlen(ptr->payloadString);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/**********************************************************
		PAYT GF_Box
**********************************************************/

void name_box_del(GF_Box *s)
{
	GF_NameBox *name = (GF_NameBox *)s;
	if (name->string) gf_free(name->string);
	gf_free(name);
}
GF_Err name_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 length;
	GF_NameBox *ptr = (GF_NameBox *)s;

	length = (u32) (ptr->size);

	if (length >= (u32)0xFFFFFFFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid length %lu in name box\n", length));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->string = (char*)gf_malloc(sizeof(char) * (length+1));
	if (! ptr->string) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, ptr->string, length);
	ptr->string[length] = 0;
	return GF_OK;
}
GF_Box *name_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_QT_BOX_TYPE_NAME);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err name_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_NameBox *ptr = (GF_NameBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	if (gf_isom_box_is_full_box(s))
		e = gf_isom_full_box_write(s, bs);
	else
		e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	if (ptr->string) {
		//do not write the terminating 0
		gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string));
	}
	return GF_OK;
}
GF_Err name_box_size(GF_Box *s)
{
	GF_NameBox *ptr = (GF_NameBox *)s;
	//do not count the terminating 0
	if (ptr->string) ptr->size += strlen(ptr->string);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void tssy_box_del(GF_Box *s)
{
	gf_free(s);
}
GF_Err tssy_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
	ISOM_DECREASE_SIZE(ptr, 1)
	gf_bs_read_int(bs, 6);
	ptr->timestamp_sync = gf_bs_read_int(bs, 2);
	return GF_OK;
}
GF_Box *tssy_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TimeStampSynchronyBox, GF_ISOM_BOX_TYPE_TSSY);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tssy_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, 0, 6);
	gf_bs_write_int(bs, ptr->timestamp_sync, 2);
	return GF_OK;
}
GF_Err tssy_box_size(GF_Box *s)
{
	s->size += 1;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void srpp_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err srpp_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_SCHI:
		BOX_FIELD_ASSIGN(info, GF_SchemeInformationBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SCHM:
		BOX_FIELD_ASSIGN(scheme_type, GF_SchemeTypeBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err srpp_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;

	ISOM_DECREASE_SIZE(s, 16)
	ptr->encryption_algorithm_rtp = gf_bs_read_u32(bs);
	ptr->encryption_algorithm_rtcp = gf_bs_read_u32(bs);
	ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs);
	ptr->integrity_algorithm_rtcp = gf_bs_read_u32(bs);
	return gf_isom_box_array_read(s, bs);
}
GF_Box *srpp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err srpp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->encryption_algorithm_rtp);
	gf_bs_write_u32(bs, ptr->encryption_algorithm_rtcp);
	gf_bs_write_u32(bs, ptr->integrity_algorithm_rtp);
	gf_bs_write_u32(bs, ptr->integrity_algorithm_rtcp);

	return GF_OK;
}
GF_Err srpp_box_size(GF_Box *s)
{
	u32 pos = 0;
	GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
	s->size += 16;
	gf_isom_check_position(s, (GF_Box*)ptr->info, &pos);
	gf_isom_check_position(s, (GF_Box*)ptr->scheme_type, &pos);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/



void rssr_box_del(GF_Box *s)
{
	gf_free(s);
}
GF_Err rssr_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->ssrc = gf_bs_read_u32(bs);
	return GF_OK;
}
GF_Box *rssr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ReceivedSsrcBox, GF_ISOM_BOX_TYPE_RSSR);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rssr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->ssrc);
	return GF_OK;
}
GF_Err rssr_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/




void iods_box_del(GF_Box *s)
{
	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
	if (ptr == NULL) return;
	if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor);
	gf_free(ptr);
}


GF_Err iods_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 descSize;
	char *desc;
	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;

	//use the OD codec...
	descSize = (u32) (ptr->size);
	desc = (char*)gf_malloc(sizeof(char) * descSize);
	if (!desc) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, desc, descSize);
	e = gf_odf_desc_read(desc, descSize, &ptr->descriptor);
	//OK, free our desc
	gf_free(desc);

	if (e) return e;
	switch (ptr->descriptor->tag) {
	case GF_ODF_ISOM_OD_TAG:
	case GF_ODF_ISOM_IOD_TAG:
		break;
	default:
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor in iods, tag %u found but only %u or %u allowed\n", ptr->descriptor->tag, GF_ODF_ISOM_IOD_TAG, GF_ODF_ISOM_OD_TAG ));
		return GF_ISOM_INVALID_FILE;
	}
	return GF_OK;
}

GF_Box *iods_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err iods_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 descSize;
	u8 *desc;
	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//call our OD codec
	e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize);
	if (e) return e;
	gf_bs_write_data(bs, desc, descSize);
	//and free our stuff maybe!!
	gf_free(desc);
	return GF_OK;
}

GF_Err iods_box_size(GF_Box *s)
{
	GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;

	ptr->size += gf_odf_desc_size(ptr->descriptor);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void mdat_box_del(GF_Box *s)
{
	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
	if (!s) return;

	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}


GF_Err mdat_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	if (ptr->type==GF_ISOM_BOX_TYPE_IMDA) {
		ptr->type = GF_ISOM_BOX_TYPE_MDAT;
		ptr->is_imda = 1;
		ISOM_DECREASE_SIZE(s, 4)
		ptr->imda_id = gf_bs_read_u32(bs);
	}

	ptr->dataSize = s->size;
	ptr->bsOffset = gf_bs_get_position(bs);

	//store idat for rewrite
	if (ptr->type==GF_ISOM_BOX_TYPE_IDAT) {
		ptr->data = gf_malloc(sizeof(u8) * (size_t)ptr->dataSize);
		if (!ptr->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->data, (u32) ptr->dataSize);
		ptr->size = 0;
		return GF_OK;
	}

	//then skip these bytes
	gf_bs_skip_bytes(bs, ptr->dataSize);
	return GF_OK;
}

GF_Box *mdat_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mdat_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
	if (ptr->is_imda) {
		s->type = GF_ISOM_BOX_TYPE_IMDA;
		e = gf_isom_box_write_header(s, bs);
		s->type = GF_ISOM_BOX_TYPE_MDAT;
		if (e) return e;
		gf_bs_write_u32(bs, ptr->imda_id);
	} else {
		e = gf_isom_box_write_header(s, bs);
		if (e) return e;
	}

	//make sure we have some data ...
	//if not, we handle that independently (edit files)
	if (ptr->data) {
		gf_bs_write_data(bs, ptr->data, (u32) ptr->dataSize);
	}
	return GF_OK;
}

GF_Err mdat_box_size(GF_Box *s)
{
	GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
	ptr->size += ptr->dataSize;
	if (ptr->is_imda)
		ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void mdhd_box_del(GF_Box *s)
{
	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

// Mapping of QuickTime old language codes
// https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-34320
// to 3-letter codes (per ISO/IEC 639-2/T, https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
// NOTE that Media Info maps them to 2-letter codes, possibly with region codes https://github.com/MediaArea/MediaInfoLib/blob/72213574cbf2ca01c0fbb97d2239b53891ad7b9d/Source/MediaInfo/Multiple/File_Mpeg4.cpp#L754
// NOTE that FFmpeg mostly maps to ISO/IEC 639-2/B and sometimes 2-letter code
// (see https://ffmpeg.org/doxygen/trunk/isom_8c_source.html)
static const char* qtLanguages[] = {
	"eng", //  0 English
	"fra", //  1 French
	"deu", //  2 German
	"ita", //  3 Italian
	"nld", //  4 Dutch
	"swe", //  5 Swedish
	"spa", //  6 Spanish
	"dan", //  7 Danish
	"por", //  8 Portuguese
	"nor", //  9 Norwegian
	"heb", // 10 Hebrew
	"jpn", // 11 Japanese
	"ara", // 12 Arabic
	"fin", // 13 Finnish
	"ell", // 14 Greek
	"isl", // 15 Icelandic
	"mlt", // 16 Maltese
	"tur", // 17 Turkish
	"hrv", // 18 Croatian
	"zho", // 19 Traditional Chinese - general 3-letter code, ignoring the "Traditional" part
	"urd", // 20 Urdu
	"hin", // 21 Hindi
	"tha", // 22 Thai
	"kor", // 23 Korean
	"lit", // 24 Lithuanian
	"pol", // 25 Polish
	"hun", // 26 Hungarian
	"est", // 27 Estonian
	"lav", // 28 Lettish or Latvian
	"sme", // 29 Saami or Sami
	"fao", // 30 Faroese
	"fas", // 31 Farsi
	"rus", // 32 Russian
	"zho", // 33 Simplified Chinese - general 3-letter code, ignoring the "Simplified" part
	"nld", // 34 Flemish - using same code as Dutch
	"gle", // 35 Irish
	"sqi", // 36 Albanian
	"ron", // 37 Romanian
	"ces", // 38 Czech
	"slk", // 39 Slovak
	"slv", // 40 Slovenian
	"yid", // 41 Yiddish
	"srp", // 42 Serbian
	"mkd", // 43 Macedonian
	"bul", // 44 Bulgarian
	"ukr", // 45 Ukrainian
	"bel", // 46 Belarusian
	"uzb", // 47 Uzbek
	"kaz", // 48 Kazakh
	"aze", // 49 Azerbaijani
	"aze", // 50 AzerbaijanAr (Armenian-Azerbaijani) - using same code as Azerbaijani
	"hye", // 51 Armenian
	"kat", // 52 Georgian
	"ron", // 53 Moldavian
	"kir", // 54 Kirghiz
	"tgk", // 55 Tajik
	"tuk", // 56 Turkmen
	"mon", // 57 Mongolian
	"mon", // 58 MongolianCyr - using same code as Mongolian
	"pus", // 59 Pashto
	"kur", // 60 Kurdish
	"kas", // 61 Kashmiri
	"snd", // 62 Sindhi
	"bod", // 63 Tibetan
	"nep", // 64 Nepali
	"san", // 65 Sanskrit
	"mar", // 66 Marathi
	"ben", // 67 Bengali
	"asm", // 68 Assamese
	"guj", // 69 Gujarati
	"pan", // 70 Punjabi
	"ori", // 71 Oriya
	"mal", // 72 Malayalam
	"kan", // 73 Kannada
	"tam", // 74 Tamil
	"tel", // 75 Telugu
	"sin", // 76 Sinhala
	"mya", // 77 Burmese
	"khm", // 78 Khmer
	"lao", // 79 Lao
	"vie", // 80 Vietnamese
	"ind", // 81 Indonesian
	"tgl", // 82 Tagalog
	"msa", // 83 MalayRoman
	"msa", // 84 MalayArabic
	"amh", // 85 Amharic
	"   ", // 86 Empty
	"orm", // 87 Oromo
	"som", // 88 Somali
	"swa", // 89 Swahili
	"kin", // 90 Kinyarwanda
	"run", // 91 Rundi
	"nya", // 92 Nyanja
	"mlg", // 93 Malagasy
	"epo", // 94 Esperanto
	// Gap 95-127
	"cym", // 128 Welsh
	"eus", // 129 Basque
	"cat", // 130 Catalan
	"lat", // 131 Latin
	"que", // 132 Quechua
	"grn", // 133 Guarani
	"aym", // 134 Aymara
	"tat", // 135 Tatar
	"uig", // 136 Uighur
	"dzo", // 127 Dzongkha
	"jav"  // 138 Javanese
};
//static const u8 qtLanguagesSize = GF_ARRAY_LENGTH(qtLanguages);

GF_Err set_quicktime_lang(char lang[4], u8 code) {
	if (code > 138 || (code > 94 && code < 128) || code == 86) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid QuickTime Language Code %d\n", code));
		return GF_BAD_PARAM;
	}
	if (code > 94)
		code -=(128-94); // Gap in the list
	lang[0] = qtLanguages[code][0];
	lang[1] = qtLanguages[code][1];
	lang[2] = qtLanguages[code][2];
	lang[3] = qtLanguages[code][3];
	return GF_OK;
}

GF_Err mdhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;

	if (ptr->version == 1) {
		ISOM_DECREASE_SIZE(ptr, 28)
		ptr->creationTime = gf_bs_read_u64(bs);
		ptr->modificationTime = gf_bs_read_u64(bs);
		ptr->timeScale = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 16)
		ptr->creationTime = gf_bs_read_u32(bs);
		ptr->modificationTime = gf_bs_read_u32(bs);
		ptr->timeScale = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u32(bs);
	}
	if (!ptr->timeScale) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is 0 - defaulting to 90000\n" ));
		ptr->timeScale = 90000;
	}

	ptr->original_duration = ptr->duration;

	ISOM_DECREASE_SIZE(ptr, 4)
	u16 lang_code = gf_bs_read_u16(bs);
	ptr->packedLanguage[0] = (lang_code>>10) & 0x1F;
	ptr->packedLanguage[1] = (lang_code>>5) & 0x1F;
	ptr->packedLanguage[2] = (lang_code) & 0x1F;
	// QuickTime Language Codes
	if (lang_code < 0x400) {
		u8 code = (ptr->packedLanguage[0] << 16) | (ptr->packedLanguage[1] << 8) | ptr->packedLanguage[2];
		set_quicktime_lang(ptr->packedLanguage, code);
	} else {
		ptr->packedLanguage[0] += 0x60;
		ptr->packedLanguage[1] += 0x60;
		ptr->packedLanguage[2] += 0x60;
	}

	if (!ptr->packedLanguage[0] || !ptr->packedLanguage[1] || !ptr->packedLanguage[2]) {
		ptr->packedLanguage[0] = 'u';
		ptr->packedLanguage[1] = 'n';
		ptr->packedLanguage[2] = 'd';
	}
	ptr->reserved = gf_bs_read_u16(bs);
	return GF_OK;
}

GF_Box *mdhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);

	tmp->packedLanguage[0] = 'u';
	tmp->packedLanguage[1] = 'n';
	tmp->packedLanguage[2] = 'd';
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mdhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->version == 1) {
		gf_bs_write_u64(bs, ptr->creationTime);
		gf_bs_write_u64(bs, ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->timeScale);
		gf_bs_write_u64(bs, ptr->duration);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->creationTime);
		gf_bs_write_u32(bs, (u32) ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->timeScale);
		gf_bs_write_u32(bs, (u32) ptr->duration);
	}
	//SPECS: BIT(1) of padding
	gf_bs_write_int(bs, 0, 1);
	gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5);
	gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5);
	gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5);
	gf_bs_write_u16(bs, ptr->reserved);
	return GF_OK;
}

GF_Err mdhd_box_size(GF_Box *s)
{
	GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
	ptr->version = 0;

	if (ptr->duration!=(u64)-1 && (ptr->duration>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->creationTime!=(u64)-1 && (ptr->creationTime>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->modificationTime!=(u64)-1 && (ptr->modificationTime>0xFFFFFFFF)) ptr->version = 1;

	ptr->size += 4;
	ptr->size += (ptr->version == 1) ? 28 : 16;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void mdia_box_del(GF_Box *s)
{
	GF_MediaBox *ptr = (GF_MediaBox *)s;
	if (ptr == NULL) return;
	if (ptr->nalu_parser) gf_bs_del(ptr->nalu_parser);
	if (ptr->nalu_out_bs) gf_bs_del(ptr->nalu_out_bs);
	if (ptr->nalu_ps_bs) gf_bs_del(ptr->nalu_ps_bs);
	if (ptr->extracted_bs) gf_bs_del(ptr->extracted_bs);
	if (ptr->extracted_samp) gf_isom_sample_del(&ptr->extracted_samp);
	if (ptr->in_sample_buffer) gf_free(ptr->in_sample_buffer);
	if (ptr->tmp_nal_copy_buffer) gf_free(ptr->tmp_nal_copy_buffer);
	if (ptr->information && ptr->information->dataHandler) {
		gf_isom_datamap_del(ptr->information->dataHandler);
		ptr->information->dataHandler = NULL;
	}
	gf_free(ptr);
}


GF_Err mdia_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MediaBox *ptr = (GF_MediaBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_MDHD:
		BOX_FIELD_ASSIGN(mediaHeader, GF_MediaHeaderBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_HDLR:
		BOX_FIELD_ASSIGN(handler, GF_HandlerBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_MINF:
		BOX_FIELD_ASSIGN(information, GF_MediaInformationBox)
		return GF_OK;
	}
	return GF_OK;
}


GF_Err mdia_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u64 cookie = gf_bs_get_cookie(bs);
	cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK;
	gf_bs_set_cookie(bs, cookie);
	e = gf_isom_box_array_read(s, bs);
	gf_bs_set_cookie(bs, cookie);

	if (e) return e;
	if (!((GF_MediaBox *)s)->information) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaInformationBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!((GF_MediaBox *)s)->handler) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing HandlerBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!((GF_MediaBox *)s)->mediaHeader) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaHeaderBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	return GF_OK;
}

GF_Box *mdia_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mdia_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err mdia_box_size(GF_Box *s)
{
	u32 pos = 0;
	GF_MediaBox *ptr = (GF_MediaBox *)s;
	//Header first
	gf_isom_check_position(s, (GF_Box*)ptr->mediaHeader, &pos);
	//then handler
	gf_isom_check_position(s, (GF_Box*)ptr->handler, &pos);

#if 0
	//elng before info for CMAF info - we deactiveate for now, no specific errors raised and CMAF should not impose any order
	GF_Box *elng = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ELNG);
	if (elng)
		gf_isom_check_position(s, elng, &pos);
#endif

	//then info
	gf_isom_check_position(s, (GF_Box*)ptr->information, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void mfra_box_del(GF_Box *s)
{
	GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
	if (ptr == NULL) return;
	gf_list_del(ptr->tfra_list);
	gf_free(ptr);
}

GF_Box *mfra_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA);
	tmp->tfra_list = gf_list_new();
	return (GF_Box *)tmp;
}

GF_Err mfra_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_TFRA:
		BOX_FIELD_LIST_ASSIGN(tfra_list);
		return GF_OK;
	case GF_ISOM_BOX_TYPE_MFRO:
		BOX_FIELD_ASSIGN(mfro, GF_MovieFragmentRandomAccessOffsetBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err mfra_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mfra_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err mfra_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
	gf_isom_check_position_list(s, ptr->tfra_list, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->mfro, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void tfra_box_del(GF_Box *s)
{
	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
	if (ptr == NULL) return;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}

GF_Box *tfra_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA);
	return (GF_Box *)tmp;
}

GF_Err tfra_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_RandomAccessEntry *p = 0;
	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;

	ISOM_DECREASE_SIZE(ptr, 12);

	ptr->track_id = gf_bs_read_u32(bs);
	if (gf_bs_read_int(bs, 26) != 0)
		return GF_ISOM_INVALID_FILE;

	ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
	ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8;
	ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8;

	ptr->nb_entries = gf_bs_read_u32(bs);

	if (ptr->version == 1) {
		if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	} else {
		if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
	}

	if (ptr->nb_entries) {
		if ((u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(GF_RandomAccessEntry)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}
		p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
		if (!p) return GF_OUT_OF_MEM;
	}

	ptr->entries = p;

	for (i=0; i<ptr->nb_entries; i++) {
		memset(p, 0, sizeof(GF_RandomAccessEntry));

		if (ptr->version == 1) {
			p->time = gf_bs_read_u64(bs);
			p->moof_offset = gf_bs_read_u64(bs);
		} else {
			p->time = gf_bs_read_u32(bs);
			p->moof_offset = gf_bs_read_u32(bs);
		}
		p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
		p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
		p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);

		++p;
	}

	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tfra_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, sap_nb_entries;
	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->track_id);
	gf_bs_write_int(bs, 0, 26);

	gf_bs_write_int(bs, ptr->traf_bits/8 - 1, 2);
	gf_bs_write_int(bs, ptr->trun_bits/8 - 1, 2);
	gf_bs_write_int(bs, ptr->sample_bits/8 - 1, 2);

	sap_nb_entries = 0;
	for (i=0; i<ptr->nb_entries; i++) {
		GF_RandomAccessEntry *p = &ptr->entries[i];
		//no sap found, do not store
		if (p->trun_number) sap_nb_entries++;
	}

	gf_bs_write_u32(bs, sap_nb_entries);

	for (i=0; i<ptr->nb_entries; i++) {
		GF_RandomAccessEntry *p = &ptr->entries[i];
		//no sap found, do not store
		if (!p->trun_number) continue;
		if (ptr->version==1) {
			gf_bs_write_u64(bs, p->time);
			gf_bs_write_u64(bs, p->moof_offset);
		} else {
			gf_bs_write_u32(bs, (u32) p->time);
			gf_bs_write_u32(bs, (u32) p->moof_offset);
		}
		gf_bs_write_int(bs, p->traf_number, ptr->traf_bits);
		gf_bs_write_int(bs, p->trun_number, ptr->trun_bits);
		gf_bs_write_int(bs, p->sample_number, ptr->sample_bits);
	}
	return GF_OK;
}

GF_Err tfra_box_size(GF_Box *s)
{
	u32 i;
	GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
	ptr->size += 12;

	for (i=0; i<ptr->nb_entries; i++) {
		GF_RandomAccessEntry *p = &ptr->entries[i];
		//no sap found, do not store
		if (!p->trun_number) continue;
		ptr->size +=  ((ptr->version==1) ? 16 : 8 ) + ptr->traf_bits/8 + ptr->trun_bits/8 + ptr->sample_bits/8;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void mfro_box_del(GF_Box *s)
{
	GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Box *mfro_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessOffsetBox, GF_ISOM_BOX_TYPE_MFRO);
	return (GF_Box *)tmp;
}

GF_Err mfro_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->container_size = gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mfro_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->container_size);
	return GF_OK;
}

GF_Err mfro_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void elng_box_del(GF_Box *s)
{
	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
	if (ptr == NULL) return;
	if (ptr->extended_language) gf_free(ptr->extended_language);
	gf_free(ptr);
}

GF_Err elng_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;

	if (ptr && ptr->size > GF_UINT_MAX)
		return GF_ISOM_INVALID_FILE;

	if (ptr->size) {
		ptr->extended_language = (char*)gf_malloc((u32) ptr->size);
		if (ptr->extended_language == NULL) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->extended_language, (u32) ptr->size);
		/*safety check in case the string is not null-terminated*/
		if (ptr->extended_language[ptr->size-1]) {
			char *str = (char*)gf_malloc((u32) ptr->size + 1);
			if (!str) return GF_OUT_OF_MEM;
			memcpy(str, ptr->extended_language, (u32) ptr->size);
			str[ptr->size] = 0;
			gf_free(ptr->extended_language);
			ptr->extended_language = str;
		}
	}
	return GF_OK;
}

GF_Box *elng_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err elng_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->extended_language) {
		gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language)+1));
	}
	return GF_OK;
}

GF_Err elng_box_size(GF_Box *s)
{
	GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;

	if (ptr->extended_language) {
		ptr->size += strlen(ptr->extended_language)+1;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void mfhd_box_del(GF_Box *s)
{
	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err mfhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->sequence_number = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *mfhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err mfhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->sequence_number);
	return GF_OK;
}

GF_Err mfhd_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}



#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


void minf_box_del(GF_Box *s)
{
	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
	if (ptr == NULL) return;

	//if we have a Handler not self-contained, delete it (the self-contained belongs to the movie)
	if (ptr->dataHandler) {
		gf_isom_datamap_close(ptr);
	}
	gf_free(ptr);
}

GF_Err minf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_NMHD:
	case GF_ISOM_BOX_TYPE_STHD:
	case GF_ISOM_BOX_TYPE_VMHD:
	case GF_ISOM_BOX_TYPE_SMHD:
	case GF_ISOM_BOX_TYPE_HMHD:
	case GF_ISOM_BOX_TYPE_GMHD:
		BOX_FIELD_ASSIGN(InfoHeader, GF_Box)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_DINF:
		BOX_FIELD_ASSIGN(dataInformation, GF_DataInformationBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_STBL:
		BOX_FIELD_ASSIGN(sampleTable, GF_SampleTableBox)
		return GF_OK;
	}
	return GF_OK;
}


GF_Err minf_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
	GF_Err e;

	e = gf_isom_box_array_read(s, bs);

	if (!e && ! ptr->dataInformation) {
		GF_Box *url;
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing DataInformationBox\n"));
		//commented on purpose, we are still able to handle the file, we only throw an error but keep processing
//		e = GF_ISOM_INVALID_FILE;

		//add a dinf box to avoid any access to a null dinf
		ptr->dataInformation = (GF_DataInformationBox *) gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DINF);
		if (!ptr->dataInformation) return GF_OUT_OF_MEM;

		ptr->dataInformation->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&ptr->dataInformation->child_boxes, GF_ISOM_BOX_TYPE_DREF);
		if (!ptr->dataInformation->dref) return GF_OUT_OF_MEM;

		url = gf_isom_box_new_parent(&ptr->dataInformation->dref->child_boxes, GF_ISOM_BOX_TYPE_URL);
		if (!url) return GF_OUT_OF_MEM;
		((GF_FullBox*)url)->flags = 1;
	}
	return e;
}

GF_Box *minf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err minf_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err minf_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
	//Header first
	gf_isom_check_position(s, (GF_Box *)ptr->InfoHeader, &pos);
	//then dataInfo
	gf_isom_check_position(s, (GF_Box *)ptr->dataInformation, &pos);
	gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_MVCI), &pos);
	//then sampleTable
	gf_isom_check_position(s, (GF_Box *)ptr->sampleTable, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void moof_box_del(GF_Box *s)
{
	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
	if (ptr == NULL) return;

	gf_list_del(ptr->TrackList);
	if (ptr->PSSHs) gf_list_del(ptr->PSSHs);
	if (ptr->mdat) gf_free(ptr->mdat);
	//happens if error while fragmenting, the emsg boxes are not part of the moof hierarchy !
	if (ptr->emsgs) {
		while (1) {
			GF_Box *emsg = gf_list_pop_front(ptr->emsgs);
			if (!emsg) break;
			gf_isom_box_del(emsg);
		}
		gf_list_del(ptr->emsgs);
	}
	gf_list_del(ptr->trun_list);
	gf_free(ptr);
}

GF_Err moof_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_MFHD:
		BOX_FIELD_ASSIGN(mfhd, GF_MovieFragmentHeaderBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TRAF:
		BOX_FIELD_LIST_ASSIGN(TrackList)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_PSSH:
		BOX_FIELD_LIST_ASSIGN(PSSHs)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err moof_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *moof_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
	tmp->TrackList = gf_list_new();
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err moof_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err moof_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *) s;
	if (!s) return GF_BAD_PARAM;
	//Header First
	gf_isom_check_position(s, (GF_Box *)ptr->mfhd, &pos);
	//then PSSH
	gf_isom_check_position_list(s, ptr->PSSHs, &pos);
	//then the track list
	gf_isom_check_position_list(s, ptr->TrackList, &pos);
	return GF_OK;
}


#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/

void moov_box_del(GF_Box *s)
{
	GF_MovieBox *ptr = (GF_MovieBox *)s;
	if (ptr == NULL) return;
	gf_list_del(ptr->trackList);
	gf_free(ptr);
}

GF_Err moov_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MovieBox *ptr = (GF_MovieBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_IODS:
		BOX_FIELD_ASSIGN(iods, GF_ObjectDescriptorBox)
		//if no IOD, delete the box
		if (ptr->iods && !ptr->iods->descriptor) {
			ptr->iods = NULL;
			gf_isom_box_del_parent(&s->child_boxes, a);
		}
		return GF_OK;

	case GF_ISOM_BOX_TYPE_MVHD:
		BOX_FIELD_ASSIGN(mvhd, GF_MovieHeaderBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_UDTA:
		BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
		return GF_OK;

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	case GF_ISOM_BOX_TYPE_MVEX:
		BOX_FIELD_ASSIGN(mvex, GF_MovieExtendsBox)
		if (ptr->mvex)
			ptr->mvex->mov = ptr->mov;
		return GF_OK;
#endif

	case GF_ISOM_BOX_TYPE_META:
		BOX_FIELD_ASSIGN(meta, GF_MetaBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_TRAK:
	case GF_ISOM_BOX_TYPE_EXTK:
		if (is_rem) {
			gf_list_del_item(ptr->trackList, a);
			return GF_OK;
		}
		{
			GF_TrackBox *tk = (GF_TrackBox *)a;
			//set our pointer to this obj
			tk->moov = ptr;
			if (tk->References) {
				GF_TrackReferenceTypeBox *dpnd=NULL;
				Track_FindRef(tk, GF_ISOM_REF_BASE, &dpnd);
				if (dpnd)
					tk->nb_base_refs = dpnd->trackIDCount;
			}
		}
		return gf_list_add(ptr->trackList, a);
	case GF_QT_BOX_TYPE_CMVD:
		ptr->has_cmvd = 1;
		break;
	case GF_ISOM_BOX_TYPE_UNKNOWN:
		if (((GF_UnknownBox*)a)->original_4cc == GF_QT_BOX_TYPE_CMOV) {
			ptr->has_cmvd = 2;
			break;
		}
	}
	return GF_OK;
}


GF_Err moov_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *moov_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
	tmp->trackList = gf_list_new();
	if (!tmp->trackList) {
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err moov_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

static void moov_check_tracks_position(GF_MovieBox *s, GF_List *childlist, u32 *pos)
{
	u32 i, k, count;
	if (!s || (s->internal_flags & GF_ISOM_ORDER_FREEZE))
		return;

	if (!s->mov) {
		gf_isom_check_position_list((GF_Box*)s, childlist, pos);
		return;
	}
	if (!s->mov->auto_reorder_tracks) {
		//no specific mux index set
		if (!s->mov->tracks_use_mux_index) {
			gf_isom_check_position_list((GF_Box*)s, childlist, pos);
			return;
		}
		GF_List *all_tracks = gf_list_new();
		count = gf_list_count(childlist);
		for (i=0; i<count; i++) {
			GF_TrackBox *tk = (GF_TrackBox*)gf_list_get(childlist, i);
			u32 mux_index = tk->mux_index;
			//mux index not set on this track , use list index
			if (!mux_index) mux_index = i+1;

			//resort by mux index
			for (k=0; k<gf_list_count(all_tracks); k++) {
				GF_TrackBox *a_tk = (GF_TrackBox*)gf_list_get(all_tracks, k);
				u32 atk_mux_index = a_tk->mux_index;
				if (!atk_mux_index) atk_mux_index = k+1;
				if ((atk_mux_index > mux_index)
					//if we have a mux index on current track but not on target insertion track, we insert before
					|| (!a_tk->mux_index && tk->mux_index && (atk_mux_index == mux_index))
				) {
					gf_list_insert(all_tracks, tk, k);
					tk = NULL;
					break;
				}
			}
			if (tk) gf_list_add(all_tracks, tk);
		}
		gf_isom_check_position_list((GF_Box*)s, all_tracks, pos);
		gf_list_del(all_tracks);
		return;
	}
	count = gf_list_count(childlist);
	GF_List *v_tracks=gf_list_new();
	GF_List *a_tracks=gf_list_new();
	GF_List *t_tracks=gf_list_new();
	GF_List *o_tracks=gf_list_new();

	for (i=0; i<count; i++) {
		GF_TrackBox *tk = (GF_TrackBox*)gf_list_get(childlist, i);
		switch (tk->Media->handler->handlerType) {
		case GF_ISOM_MEDIA_VISUAL:
		case GF_ISOM_MEDIA_AUXV:
		case GF_ISOM_MEDIA_PICT:
			gf_list_add(v_tracks, tk);
			break;
		case GF_ISOM_MEDIA_AUDIO:
			gf_list_add(a_tracks, tk);
			break;
		case GF_ISOM_MEDIA_TEXT:
		case GF_ISOM_MEDIA_SUBT:
		case GF_ISOM_MEDIA_SUBPIC:
		case GF_ISOM_MEDIA_MPEG_SUBT:
		case GF_ISOM_MEDIA_CLOSED_CAPTION:
			gf_list_add(t_tracks, tk);
			break;
		default:
			gf_list_add(o_tracks, tk);
			break;
		}
	}
	for (k=0; k<4;k++) {
		GF_List *src = NULL;
		switch (k) {
		case 0: src = v_tracks; break;
		case 1: src = a_tracks; break;
		case 2: src = t_tracks; break;
		case 3: src = o_tracks; break;
		}
		count = gf_list_count(src);
		for (i=0; i<count; i++) {
			GF_Box *child = gf_list_get(src, i);
			gf_isom_check_position((GF_Box*)s, child, pos);
		}
		gf_list_del(src);
	}
}

GF_Err moov_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MovieBox *ptr = (GF_MovieBox *)s;

	gf_isom_check_position(s, (GF_Box *) ptr->mvhd, &pos);
	gf_isom_check_position(s, (GF_Box *) ptr->iods, &pos);
	gf_isom_check_position(s, (GF_Box *) ptr->meta, &pos);
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->mvex && !ptr->mvex_after_traks) {
		gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
	}
#endif
	moov_check_tracks_position(ptr, ptr->trackList, &pos);

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->mvex && ptr->mvex_after_traks) {
		gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos);
	}
#endif
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void audio_sample_entry_box_del(GF_Box *s)
{
	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
	gf_free(ptr);
}

GF_Err audio_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_UnknownBox *wave = NULL;
	Bool drop_wave=GF_FALSE;
	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;

	switch (a->type) {
	case GF_ISOM_BOX_TYPE_ESDS:
		BOX_FIELD_ASSIGN(esd, GF_ESDBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;

	case GF_ISOM_BOX_TYPE_DAMR:
	case GF_ISOM_BOX_TYPE_DEVC:
	case GF_ISOM_BOX_TYPE_DQCP:
	case GF_ISOM_BOX_TYPE_DSMV:
		BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
		/*for 3GP config, remember sample entry type in config*/
		ptr->cfg_3gpp->cfg.type = ptr->type;
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;

	case GF_ISOM_BOX_TYPE_DOPS:
		BOX_FIELD_ASSIGN(cfg_opus, GF_OpusSpecificBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;
	case GF_ISOM_BOX_TYPE_IACB:
		BOX_FIELD_ASSIGN(cfg_iamf, GF_IAConfigurationBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;
	case GF_ISOM_BOX_TYPE_DAC3:
		BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;
	case GF_ISOM_BOX_TYPE_DEC3:
		BOX_FIELD_ASSIGN(cfg_ac3, GF_AC3ConfigBox)
		break;
	case GF_ISOM_BOX_TYPE_DAC4:
		BOX_FIELD_ASSIGN(cfg_ac4, GF_AC4ConfigBox)
		break;
	case GF_ISOM_BOX_TYPE_DMLP:
		BOX_FIELD_ASSIGN(cfg_mlp, GF_TrueHDConfigBox)
		break;
	case GF_ISOM_BOX_TYPE_MHAC:
		BOX_FIELD_ASSIGN(cfg_mha, GF_MHAConfigBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;
	case GF_ISOM_BOX_TYPE_DFLA:
		BOX_FIELD_ASSIGN(cfg_flac, GF_FLACConfigBox)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		break;

	case GF_ISOM_BOX_TYPE_UNKNOWN:
		wave = (GF_UnknownBox *)a;
		/*HACK for QT files: get the esds box from the track*/
		if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
			if (is_rem) {
				return GF_OK;
			}
			if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
			//wave subboxes may have been properly parsed
 			if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
 				u32 i;
				for (i =0; i<gf_list_count(wave->child_boxes); i++) {
					GF_Box *inner_box = (GF_Box *)gf_list_get(wave->child_boxes, i);
					if (inner_box->type == GF_ISOM_BOX_TYPE_ESDS) {
						ptr->esd = (GF_ESDBox *)inner_box;
 						if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
							gf_list_rem(a->child_boxes, i);
							drop_wave=GF_TRUE;
							ptr->compression_id = 0;
							gf_list_add(ptr->child_boxes, inner_box);
						}
					}
				}
				if (drop_wave) {
					gf_isom_box_del_parent(&ptr->child_boxes, a);
					ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
					ptr->version = 0;
					return GF_OK;
				}
				ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
				return GF_OK;
			}
			gf_isom_box_del_parent(&ptr->child_boxes, a);
			return GF_ISOM_INVALID_MEDIA;

		}
 		ptr->qtff_mode &= ~GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;

 		if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) {
			ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;
		}
		return GF_OK;
	case GF_QT_BOX_TYPE_WAVE:
	{
		u32 subtype = 0;
		GF_Box **cfg_ptr = NULL;
		if (s->type == GF_ISOM_BOX_TYPE_MP4A) {
			cfg_ptr = (GF_Box **) &ptr->esd;
			subtype = GF_ISOM_BOX_TYPE_ESDS;
		}
		else if (s->type == GF_ISOM_BOX_TYPE_AC3) {
			cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
			subtype = GF_ISOM_BOX_TYPE_DAC3;
		}
		else if (s->type == GF_ISOM_BOX_TYPE_EC3) {
			cfg_ptr = (GF_Box **) &ptr->cfg_ac3;
			subtype = GF_ISOM_BOX_TYPE_DEC3;
		}
		else if (s->type == GF_ISOM_BOX_TYPE_AC4) {
			cfg_ptr = (GF_Box **) &ptr->cfg_ac4;
			subtype = GF_ISOM_BOX_TYPE_DAC4;
		}
		else if (s->type == GF_ISOM_BOX_TYPE_OPUS) {
			cfg_ptr = (GF_Box **) &ptr->cfg_opus;
			subtype = GF_ISOM_BOX_TYPE_DOPS;
		}
		else if ((s->type == GF_ISOM_BOX_TYPE_MHA1)
			|| (s->type == GF_ISOM_BOX_TYPE_MHA2)
			|| (s->type == GF_ISOM_BOX_TYPE_MHM1)
			|| (s->type == GF_ISOM_BOX_TYPE_MHM2)
		) {
			cfg_ptr = (GF_Box **) &ptr->cfg_mha;
			subtype = GF_ISOM_BOX_TYPE_MHAC;
		}
		else if (s->type == GF_ISOM_BOX_TYPE_MLPA) {
			cfg_ptr = (GF_Box **) &ptr->cfg_mlp;
			subtype = GF_ISOM_BOX_TYPE_DMLP;
		}

		if (cfg_ptr) {
			if (is_rem) {
				*cfg_ptr = NULL;
				return GF_OK;
			}
			if (*cfg_ptr) ERROR_ON_DUPLICATED_BOX(a, ptr)

			//wave subboxes may have been properly parsed
 			if (gf_list_count(a->child_boxes)) {
 				u32 i;
				for (i =0; i<gf_list_count(a->child_boxes); i++) {
					GF_Box *inner_box = (GF_Box *)gf_list_get(a->child_boxes, i);
					if (inner_box->type == subtype) {
						*cfg_ptr = inner_box;
 						if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) {
							gf_list_rem(a->child_boxes, i);
							drop_wave=GF_TRUE;
							gf_list_add(ptr->child_boxes, inner_box);
						}
						break;
					}
				}
				if (drop_wave) {
					gf_isom_box_del_parent(&ptr->child_boxes, a);
					ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
					ptr->compression_id = 0;
					ptr->version = 0;
					return GF_OK;
				}
				ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
				return GF_OK;
			}
		}
	}
 		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID;
		return GF_OK;
	}
	return GF_OK;
}
GF_Err audio_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MPEGAudioSampleEntryBox *ptr;
	char *data;
	u8 a, b, c, d;
	u32 i, size, v, nb_alnum;
	GF_Err e;
	u64 pos, start;

	ptr = (GF_MPEGAudioSampleEntryBox *)s;

	start = gf_bs_get_position(bs);
	v = gf_bs_peek_bits(bs, 16, 8);
	if (v)
		ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT;

	//try to disambiguate QTFF v1 and MP4 v1 audio sample entries ...
	if (v==1) {
		//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
		gf_bs_skip_bytes(bs, 8 + 20 + 4);
		a = gf_bs_read_u8(bs);
		b = gf_bs_read_u8(bs);
		c = gf_bs_read_u8(bs);
		d = gf_bs_read_u8(bs);
		nb_alnum = 0;
		if (isalnum(a)) nb_alnum++;
		if (isalnum(b)) nb_alnum++;
		if (isalnum(c)) nb_alnum++;
		if (isalnum(d)) nb_alnum++;
		if (nb_alnum>2) ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE;
		gf_bs_seek(bs, start);
	}

	e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
	if (e) return e;
	pos = gf_bs_get_position(bs);
	size = (u32) s->size;

	//when cookie is set on bs, always convert qtff-style mp4a to isobmff-style
	//since the conversion is done in addBox and we don't have the bitstream there (arg...), flag the box
 	if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_QT_CONV) {
 		ptr->qtff_mode |= GF_ISOM_AUDIO_QTFF_CONVERT_FLAG;
 	}

	e = gf_isom_box_array_read(s, bs);
	if (!e) {
		if (s->type==GF_ISOM_BOX_TYPE_ENCA) {
			GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);

			if (sinf && sinf->original_format) {
				u32 type = sinf->original_format->data_format;
				switch (type) {
				case GF_ISOM_SUBTYPE_3GP_AMR:
				case GF_ISOM_SUBTYPE_3GP_AMR_WB:
				case GF_ISOM_SUBTYPE_3GP_EVRC:
				case GF_ISOM_SUBTYPE_3GP_QCELP:
				case GF_ISOM_SUBTYPE_3GP_SMV:
					if (ptr->cfg_3gpp) ptr->cfg_3gpp->cfg.type = type;
					break;
				}
			}
		}
		return GF_OK;
	}
	if (size<8) return GF_ISOM_INVALID_FILE;


	/*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/
	gf_bs_seek(bs, pos);
	data = (char*)gf_malloc(sizeof(char) * size);
	if (!data) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, data, size);
	for (i=0; i<size-8; i++) {
		if (GF_4CC((u32)data[i+4], (u8)data[i+5], (u8)data[i+6], (u8)data[i+7]) == GF_ISOM_BOX_TYPE_ESDS) {
			GF_BitStream *mybs = gf_bs_new(data + i, size - i, GF_BITSTREAM_READ);
			gf_bs_set_cookie(mybs, GF_ISOM_BS_COOKIE_NO_LOGS);
			if (ptr->esd) {

				gf_list_del_item(ptr->child_boxes, (GF_Box *)ptr->esd);

				for (u32 i=0; i<gf_list_count(ptr->child_boxes); i++) {
					GF_Box *inner_box = (GF_Box *)gf_list_get(ptr->child_boxes, i);
					if (inner_box->child_boxes) {
						gf_list_del_item(inner_box->child_boxes, (GF_Box *)ptr->esd);
					}
				}

				gf_isom_box_del((GF_Box *)ptr->esd);
			}
			ptr->esd = NULL;
			e = gf_isom_box_parse((GF_Box **)&ptr->esd, mybs);
			gf_bs_del(mybs);

			if ((e==GF_OK) && ptr->esd && (ptr->esd->type == GF_ISOM_BOX_TYPE_ESDS)) {
				if (!ptr->child_boxes) ptr->child_boxes = gf_list_new();
				gf_list_add(ptr->child_boxes, ptr->esd);
			} else if (ptr->esd) {
				gf_isom_box_del((GF_Box *)ptr->esd);
				ptr->esd = NULL;
			}
			e = GF_OK;
			break;
		}
	}
	gf_free(data);
	return e;
}

GF_Box *audio_sample_entry_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}

GF_Box *enca_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA);
	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err audio_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
	return GF_OK;
}

GF_Err audio_sample_entry_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
	if (ptr->qtff_mode)
		return GF_OK;

	if (ptr->version) {
		gf_isom_check_position(s, gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SRAT), &pos);
		gf_isom_check_position(s, gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_CHNL), &pos);
	}

	gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_mha, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_opus, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_ac3, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_flac, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_mlp, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_iamf, &pos);

	if (!ptr->version) {
		gf_isom_check_position(s, gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SRAT), &pos);
		gf_isom_check_position(s, gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_CHNL), &pos);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void gen_sample_entry_box_del(GF_Box *s)
{
	GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
	gf_free(ptr);
}


GF_Err gen_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs);
	if (e) return e;
	ISOM_DECREASE_SIZE(s, 8);
	return gf_isom_box_array_read(s, bs);
}

GF_Box *gen_sample_entry_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleEntryBox, GF_QT_SUBTYPE_C608);//type will be overwritten
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err gen_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_data(bs, ptr->reserved, 6);
	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
	return GF_OK;
}

GF_Err gen_sample_entry_box_size(GF_Box *s)
{
	GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s;
	ptr->size += 8;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void mp4s_box_del(GF_Box *s)
{
	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
	gf_free(ptr);
}

GF_Err mp4s_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_ESDS:
		BOX_FIELD_ASSIGN(esd, GF_ESDBox)
		break;
	}
	return GF_OK;
}

GF_Err mp4s_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;

	e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
	if (e) return e;

	ISOM_DECREASE_SIZE(ptr, 8);
	return gf_isom_box_array_read(s, bs);
}

GF_Box *mp4s_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	tmp->internal_type = GF_ISOM_SAMPLE_ENTRY_MP4S;
	return (GF_Box *)tmp;
}

GF_Box *encs_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS);
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	tmp->internal_type = GF_ISOM_SAMPLE_ENTRY_MP4S;
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mp4s_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, ptr->reserved, 6);
	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
	return GF_OK;
}

GF_Err mp4s_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
	s->size += 8;
	gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void video_sample_entry_box_del(GF_Box *s)
{
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);

	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
	/*for publishing*/
	if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);
	gf_free(ptr);
}

GF_Err video_sample_entry_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_ESDS:
		BOX_FIELD_ASSIGN(esd, GF_ESDBox)
		break;
	case GF_ISOM_BOX_TYPE_RINF:
		BOX_FIELD_ASSIGN(rinf, GF_RestrictedSchemeInfoBox)
		break;
	case GF_ISOM_BOX_TYPE_AVCC:
		BOX_FIELD_ASSIGN(avc_config, GF_AVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_HVCC:
		BOX_FIELD_ASSIGN(hevc_config, GF_HEVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_VVCC:
		BOX_FIELD_ASSIGN(vvc_config, GF_VVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_SVCC:
		BOX_FIELD_ASSIGN(svc_config, GF_AVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_MVCC:
		BOX_FIELD_ASSIGN(mvc_config, GF_AVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_LHVC:
		BOX_FIELD_ASSIGN(lhvc_config, GF_HEVCConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_AV1C:
		BOX_FIELD_ASSIGN(av1_config, GF_AV1ConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_VPCC:
		BOX_FIELD_ASSIGN(vp_config, GF_VPConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_AV3C:
		BOX_FIELD_ASSIGN(avs3v_config, GF_AVS3VConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_DVCC:
	case GF_ISOM_BOX_TYPE_DVVC:
		BOX_FIELD_ASSIGN(dovi_config, GF_DOVIConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_UUID:
		if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) {
			BOX_FIELD_ASSIGN(ipod_ext, GF_UnknownUUIDBox)
		} else {
			return GF_OK;
		}
		break;
	case GF_ISOM_BOX_TYPE_D263:
		BOX_FIELD_ASSIGN(cfg_3gpp, GF_3GPPConfigBox)
		/*for 3GP config, remember sample entry type in config*/
		if (ptr->cfg_3gpp)
			ptr->cfg_3gpp->cfg.type = ptr->type;
		break;

	case GF_ISOM_BOX_TYPE_JP2H:
		BOX_FIELD_ASSIGN(jp2h, GF_J2KHeaderBox)
		return GF_OK;

	case GF_ISOM_BOX_TYPE_PASP:
	case GF_ISOM_BOX_TYPE_CLAP:
	case GF_ISOM_BOX_TYPE_COLR:
	case GF_ISOM_BOX_TYPE_MDCV:
	case GF_ISOM_BOX_TYPE_CLLI:
	case GF_ISOM_BOX_TYPE_CCST:
	case GF_ISOM_BOX_TYPE_AUXI:
	case GF_ISOM_BOX_TYPE_RVCC:
	case GF_ISOM_BOX_TYPE_M4DS:
	case GF_ISOM_BOX_TYPE_VEXU:
		if (!is_rem && !gf_isom_box_check_unique(s->child_boxes, a)) {
			ERROR_ON_DUPLICATED_BOX(a, ptr)
		}
		return GF_OK;
	}
	return GF_OK;
}

GF_Err video_sample_entry_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
	GF_Err e;
	e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
	if (e) return e;
	e = gf_isom_box_array_read(s, bs);
	if (e) return e;
	/*this is an AVC sample desc*/
	if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config)
		AVC_RewriteESDescriptor(mp4v);
	/*this is an HEVC sample desc*/
	if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1))
		HEVC_RewriteESDescriptor(mp4v);
	/*this is an AV1 sample desc*/
	if (mp4v->av1_config)
		AV1_RewriteESDescriptor(mp4v);
	/*this is a VP8-9 sample desc*/
	if (mp4v->vp_config)
		VP9_RewriteESDescriptor(mp4v);

	if (s->type==GF_ISOM_BOX_TYPE_ENCV) {
		GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF);

		if (sinf && sinf->original_format) {
			u32 type = sinf->original_format->data_format;
			switch (type) {
			case GF_ISOM_SUBTYPE_3GP_H263:
				if (mp4v->cfg_3gpp) mp4v->cfg_3gpp->cfg.type = type;
				break;
			}
		}
	}
	return GF_OK;
}

GF_Box *video_sample_entry_box_new()
{
	GF_MPEGVisualSampleEntryBox *tmp;
	GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox);
	if (tmp == NULL) return NULL;

	gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err video_sample_entry_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
	return GF_OK;
}

GF_Err video_sample_entry_box_size(GF_Box *s)
{
	GF_Box *b;
	u32 pos=0;
	GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);

	/*make sure we write the config box first, we don't care about the rest*/

	/*mp4v*/
	gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos);
	/*avc / SVC + MVC*/
	gf_isom_check_position(s, (GF_Box *)ptr->avc_config, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->svc_config, &pos);
	if (ptr->mvc_config) {
		gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_VWID), &pos);
		gf_isom_check_position(s, (GF_Box *)ptr->mvc_config, &pos);
	}

	/*HEVC*/
	gf_isom_check_position(s, (GF_Box *)ptr->hevc_config, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->lhvc_config, &pos);

	/*VVC*/
	gf_isom_check_position(s, (GF_Box *)ptr->vvc_config, &pos);

	/*AV1*/
	gf_isom_check_position(s, (GF_Box *)ptr->av1_config, &pos);

	/*VPx*/
	gf_isom_check_position(s, (GF_Box *)ptr->vp_config, &pos);

	/*JP2H*/
	gf_isom_check_position(s, (GF_Box *)ptr->jp2h, &pos);

	/*DolbyVision*/
	gf_isom_check_position(s, (GF_Box *)ptr->dovi_config, &pos);

	b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_ST3D);
	if (b) gf_isom_check_position(s, b, &pos);

	b = gf_isom_box_find_child(ptr->child_boxes, GF_ISOM_BOX_TYPE_SV3D);
	if (b) gf_isom_check_position(s, b, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void mvex_box_del(GF_Box *s)
{
	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
	if (ptr == NULL) return;
	gf_list_del(ptr->TrackExList);
	gf_list_del(ptr->TrackExPropList);
	gf_free(ptr);
}


GF_Err mvex_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;

	switch (a->type) {
	case GF_ISOM_BOX_TYPE_TREX:
		BOX_FIELD_LIST_ASSIGN(TrackExList)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TREP:
		BOX_FIELD_LIST_ASSIGN(TrackExPropList)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_MEHD:
		BOX_FIELD_ASSIGN(mehd, GF_MovieExtendsHeaderBox)
		return GF_OK;
	}
	return GF_OK;
}



GF_Err mvex_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *mvex_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
	tmp->TrackExList = gf_list_new();
	if (!tmp->TrackExList) {
		gf_free(tmp);
		return NULL;
	}
	tmp->TrackExPropList = gf_list_new();
	if (!tmp->TrackExPropList) {
		gf_list_del(tmp->TrackExList);
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err mvex_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err mvex_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *) s;
	gf_isom_check_position(s, (GF_Box *)ptr->mehd, &pos);
	gf_isom_check_position_list(s, ptr->TrackExList, &pos);
	gf_isom_check_position_list(s, ptr->TrackExPropList, &pos);
	return GF_OK;
}



#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *mehd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
	return (GF_Box *)tmp;
}
void mehd_box_del(GF_Box *s)
{
	gf_free(s);
}
GF_Err mehd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;

	if (ptr->version==1) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->fragment_duration = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->fragment_duration = (u64) gf_bs_read_u32(bs);
	}
	return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mehd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
	GF_Err e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->version == 1) {
		gf_bs_write_u64(bs, ptr->fragment_duration);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->fragment_duration);
	}
	return GF_OK;
}
GF_Err mehd_box_size(GF_Box *s)
{
	GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
	ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0;
	s->size += (ptr->version == 1) ? 8 : 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


void mvhd_box_del(GF_Box *s)
{
	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err mvhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	if (ptr->version == 1) {
		ISOM_DECREASE_SIZE(ptr, 28);
		ptr->creationTime = gf_bs_read_u64(bs);
		ptr->modificationTime = gf_bs_read_u64(bs);
		ptr->timeScale = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 16);
		ptr->creationTime = gf_bs_read_u32(bs);
		ptr->modificationTime = gf_bs_read_u32(bs);
		ptr->timeScale = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u32(bs);
	}
	if (!ptr->timeScale) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n" ));
		ptr->timeScale = 600;
	}
	ISOM_DECREASE_SIZE(ptr, 80);
	ptr->preferredRate = gf_bs_read_u32(bs);
	ptr->preferredVolume = gf_bs_read_u16(bs);
	gf_bs_read_data(bs, ptr->reserved, 10);
	ptr->matrixA = gf_bs_read_u32(bs);
	ptr->matrixB = gf_bs_read_u32(bs);
	ptr->matrixU = gf_bs_read_u32(bs);
	ptr->matrixC = gf_bs_read_u32(bs);
	ptr->matrixD = gf_bs_read_u32(bs);
	ptr->matrixV = gf_bs_read_u32(bs);
	ptr->matrixX = gf_bs_read_u32(bs);
	ptr->matrixY = gf_bs_read_u32(bs);
	ptr->matrixW = gf_bs_read_u32(bs);
	ptr->previewTime = gf_bs_read_u32(bs);
	ptr->previewDuration = gf_bs_read_u32(bs);
	ptr->posterTime = gf_bs_read_u32(bs);
	ptr->selectionTime = gf_bs_read_u32(bs);
	ptr->selectionDuration = gf_bs_read_u32(bs);
	ptr->currentTime = gf_bs_read_u32(bs);
	ptr->nextTrackID = gf_bs_read_u32(bs);
	ptr->original_duration = ptr->duration;
	return GF_OK;
}

GF_Box *mvhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);

	tmp->preferredRate = (1<<16);
	tmp->preferredVolume = (1<<8);

	tmp->matrixA = (1<<16);
	tmp->matrixD = (1<<16);
	tmp->matrixW = (1<<30);

	tmp->nextTrackID = 1;

	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mvhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->version == 1) {
		gf_bs_write_u64(bs, ptr->creationTime);
		gf_bs_write_u64(bs, ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->timeScale);
		gf_bs_write_u64(bs, ptr->duration);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->creationTime);
		gf_bs_write_u32(bs, (u32) ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->timeScale);
		gf_bs_write_u32(bs, (u32) ptr->duration);
	}
	gf_bs_write_u32(bs, ptr->preferredRate);
	gf_bs_write_u16(bs, ptr->preferredVolume);
	gf_bs_write_data(bs, ptr->reserved, 10);
	gf_bs_write_u32(bs, ptr->matrixA);
	gf_bs_write_u32(bs, ptr->matrixB);
	gf_bs_write_u32(bs, ptr->matrixU);
	gf_bs_write_u32(bs, ptr->matrixC);
	gf_bs_write_u32(bs, ptr->matrixD);
	gf_bs_write_u32(bs, ptr->matrixV);
	gf_bs_write_u32(bs, ptr->matrixX);
	gf_bs_write_u32(bs, ptr->matrixY);
	gf_bs_write_u32(bs, ptr->matrixW);
	gf_bs_write_u32(bs, ptr->previewTime);
	gf_bs_write_u32(bs, ptr->previewDuration);
	gf_bs_write_u32(bs, ptr->posterTime);
	gf_bs_write_u32(bs, ptr->selectionTime);
	gf_bs_write_u32(bs, ptr->selectionDuration);
	gf_bs_write_u32(bs, ptr->currentTime);
	gf_bs_write_u32(bs, ptr->nextTrackID);
	return GF_OK;
}

GF_Err mvhd_box_size(GF_Box *s)
{
	GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
	ptr->version = 0;

	if (ptr->duration!=(u64)-1 && (ptr->duration>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->creationTime!=(u64)-1 && (ptr->creationTime>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->modificationTime!=(u64)-1 && (ptr->modificationTime>0xFFFFFFFF)) ptr->version = 1;


	ptr->size += (ptr->version == 1) ? 28 : 16;
	ptr->size += 80;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void nmhd_box_del(GF_Box *s)
{
	GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}



GF_Err nmhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	return GF_OK;
}

GF_Box *nmhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err nmhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err nmhd_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void padb_box_del(GF_Box *s)
{
	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
	if (ptr == NULL) return;
	if (ptr->padbits) gf_free(ptr->padbits);
	gf_free(ptr);
}


GF_Err padb_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->SampleCount = gf_bs_read_u32(bs);
	if (ptr->size < ptr->SampleCount/2) //half byte per sample
		return GF_ISOM_INVALID_FILE;

	ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount);
	if (!ptr->padbits) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->SampleCount; i += 2) {
		gf_bs_read_int(bs, 1);
		if (i+1 < ptr->SampleCount) {
			ptr->padbits[i+1] = gf_bs_read_int(bs, 3);
		} else {
			gf_bs_read_int(bs, 3);
		}
		gf_bs_read_int(bs, 1);
		ptr->padbits[i] = gf_bs_read_int(bs, 3);
	}
	return GF_OK;
}

GF_Box *padb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err padb_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, ptr->SampleCount, 32);

	for (i=0 ; i<ptr->SampleCount; i += 2) {
		gf_bs_write_int(bs, 0, 1);
		if (i+1 < ptr->SampleCount) {
			gf_bs_write_int(bs, ptr->padbits[i+1], 3);
		} else {
			gf_bs_write_int(bs, 0, 3);
		}
		gf_bs_write_int(bs, 0, 1);
		gf_bs_write_int(bs, ptr->padbits[i], 3);
	}
	return GF_OK;
}

GF_Err padb_box_size(GF_Box *s)
{
	GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
	ptr->size += 4;
	if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2;

	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void rely_box_del(GF_Box *s)
{
	GF_RelyHintBox *rely = (GF_RelyHintBox *)s;
	gf_free(rely);
}

GF_Err rely_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
	ISOM_DECREASE_SIZE(ptr, 1);
	ptr->reserved = gf_bs_read_int(bs, 6);
	ptr->preferred = gf_bs_read_int(bs, 1);
	ptr->required = gf_bs_read_int(bs, 1);
	return GF_OK;
}

GF_Box *rely_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rely_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, ptr->reserved, 6);
	gf_bs_write_int(bs, ptr->preferred, 1);
	gf_bs_write_int(bs, ptr->required, 1);
	return GF_OK;
}

GF_Err rely_box_size(GF_Box *s)
{
	s->size += 1;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void rtpo_box_del(GF_Box *s)
{
	GF_RTPOBox *rtpo = (GF_RTPOBox *)s;
	gf_free(rtpo);
}

GF_Err rtpo_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_RTPOBox *ptr = (GF_RTPOBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->timeOffset = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *rtpo_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
	return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rtpo_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_RTPOBox *ptr = (GF_RTPOBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	//here we have no pb, just remembed that some entries will have to
	//be 4-bytes aligned ...
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->timeOffset);
	return GF_OK;
}

GF_Err rtpo_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

void smhd_box_del(GF_Box *s)
{
	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
	if (ptr == NULL ) return;
	gf_free(ptr);
}


GF_Err smhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->balance = gf_bs_read_u16(bs);
	ptr->reserved = gf_bs_read_u16(bs);
	return GF_OK;
}

GF_Box *smhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err smhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u16(bs, ptr->balance);
	gf_bs_write_u16(bs, ptr->reserved);
	return GF_OK;
}

GF_Err smhd_box_size(GF_Box *s)
{
	GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;

	ptr->reserved = 0;
	ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void snro_box_del(GF_Box *s)
{
	GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s;
	gf_free(snro);
}

GF_Err snro_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->SeqOffset = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *snro_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err snro_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->SeqOffset);
	return GF_OK;
}

GF_Err snro_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stbl_box_del(GF_Box *s)
{
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
	if (ptr == NULL) return;

	if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
	if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
	if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
	if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
	if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
	if (ptr->traf_map) {
		if (ptr->traf_map->frag_starts) {
			u32 i;
			for (i=0; i<ptr->traf_map->nb_entries; i++) {
				if (ptr->traf_map->frag_starts[i].moof_template)
					gf_free(ptr->traf_map->frag_starts[i].moof_template);
			}
			gf_free(ptr->traf_map->frag_starts);
		}
		gf_free(ptr->traf_map);
	}
	gf_free(ptr);
}

GF_Err stbl_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
	if (!a) return GF_OK;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_STTS:
		BOX_FIELD_ASSIGN(TimeToSample, GF_TimeToSampleBox)
		break;
	case GF_ISOM_BOX_TYPE_CTTS:
		BOX_FIELD_ASSIGN(CompositionOffset, GF_CompositionOffsetBox)
		break;
	case GF_ISOM_BOX_TYPE_CSLG:
		BOX_FIELD_ASSIGN(CompositionToDecode, GF_CompositionToDecodeBox)
		break;
	case GF_ISOM_BOX_TYPE_STSS:
		BOX_FIELD_ASSIGN(SyncSample, GF_SyncSampleBox)
		break;
	case GF_ISOM_BOX_TYPE_STSD:
		BOX_FIELD_ASSIGN(SampleDescription, GF_SampleDescriptionBox)
		break;
	case GF_ISOM_BOX_TYPE_STZ2:
	case GF_ISOM_BOX_TYPE_STSZ:
		BOX_FIELD_ASSIGN(SampleSize, GF_SampleSizeBox)
		break;
	case GF_ISOM_BOX_TYPE_STSC:
		BOX_FIELD_ASSIGN(SampleToChunk, GF_SampleToChunkBox)
		break;
	case GF_ISOM_BOX_TYPE_PADB:
		BOX_FIELD_ASSIGN(PaddingBits, GF_PaddingBitsBox)
		break;

	//WARNING: AS THIS MAY CHANGE DYNAMICALLY DURING EDIT,
	case GF_ISOM_BOX_TYPE_CO64:
	case GF_ISOM_BOX_TYPE_STCO:
		BOX_FIELD_ASSIGN(ChunkOffset, GF_Box)
		break;
	case GF_ISOM_BOX_TYPE_STSH:
		BOX_FIELD_ASSIGN(ShadowSync, GF_ShadowSyncBox)
		break;
	case GF_ISOM_BOX_TYPE_STDP:
		BOX_FIELD_ASSIGN(DegradationPriority, GF_DegradationPriorityBox)
		break;
	case GF_ISOM_BOX_TYPE_SDTP:
		BOX_FIELD_ASSIGN(SampleDep, GF_SampleDependencyTypeBox)
		break;

	case GF_ISOM_BOX_TYPE_SUBS:
		BOX_FIELD_LIST_ASSIGN(sub_samples)
		//check subsample box
		if (!is_rem) {
			GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a;
			GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0);
			if (!ent) {
				gf_list_rem(subs->Samples, 0);
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable is invalid\n"));
			}
			else if (ent->sample_delta==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"));
				ent->sample_delta = 1;
			}
		}
		break;

	case GF_ISOM_BOX_TYPE_SBGP:
	case GF_ISOM_BOX_TYPE_CSGP:
		BOX_FIELD_LIST_ASSIGN(sampleGroups)
		break;
	case GF_ISOM_BOX_TYPE_SGPD:
		BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
		break;
	case GF_ISOM_BOX_TYPE_SAIZ:
		BOX_FIELD_LIST_ASSIGN(sai_sizes)
		break;
	case GF_ISOM_BOX_TYPE_SAIO:
		BOX_FIELD_LIST_ASSIGN(sai_offsets)
		break;
	case GF_GPAC_BOX_TYPE_SREF:
	case GF_ISOM_BOX_TYPE_CDRF:
		BOX_FIELD_ASSIGN(SampleRefs, GF_SampleReferences)
		break;
	}
	return GF_OK;
}




GF_Err stbl_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	//we need to parse DegPrior in a special way
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;

	e = gf_isom_box_array_read(s, bs);
	if (e) return e;

	if (!ptr->SyncSample)
		ptr->no_sync_found = 1;

	ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription);
	ptr->nb_stbl_boxes = gf_list_count(ptr->child_boxes);

	if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_CLONE_TRACK)
		return GF_OK;
//	return GF_OK;

#define CHECK_BOX(_name) \
	if (!ptr->_name) {\
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Mandatory box %s is missing\n", #_name)); \
		return GF_ISOM_INVALID_FILE; \
	}

	CHECK_BOX(SampleToChunk)
	CHECK_BOX(SampleSize)
	CHECK_BOX(ChunkOffset)
	CHECK_BOX(TimeToSample)

	//sanity check
	if (ptr->SampleSize->sampleCount) {
		if (!ptr->TimeToSample->nb_entries || !ptr->SampleToChunk->nb_entries)
			return GF_ISOM_INVALID_FILE;
		//safety check : get info for last sample, if error consider file is invalid
		u64 sample_offset;
		u32 di, chunk;
		e = stbl_GetSampleInfos(ptr, ptr->SampleSize->sampleCount, &sample_offset, &chunk, &di, NULL);
		if (e) return e;
		e = stbl_GetSampleDTS(ptr->TimeToSample, ptr->SampleSize->sampleCount, &sample_offset);
		if (e) return e;
	}
	u32 i, max_chunks=0;
	if (ptr->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) {
		max_chunks = ((GF_ChunkOffsetBox *)ptr->ChunkOffset)->nb_entries;
	}
	else if (ptr->ChunkOffset->type == GF_ISOM_BOX_TYPE_CO64) {
		max_chunks = ((GF_ChunkOffsetBox *)ptr->ChunkOffset)->nb_entries;
	}

	//sanity check on stsc vs chunk offset tables
	for (i=0; i<ptr->SampleToChunk->nb_entries; i++) {
		GF_StscEntry *ent = &ptr->SampleToChunk->entries[i];
		if (!i && (ent->firstChunk!=1)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] first_chunk of first entry shall be 1 but is %u\n", ent->firstChunk));
			return GF_ISOM_INVALID_FILE;
		}
		if (ptr->SampleToChunk->entries[i].firstChunk > max_chunks) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] first_chunk is %u but number of chunks defined %u\n", ptr->SampleToChunk->entries[i].firstChunk, max_chunks));
			return GF_ISOM_INVALID_FILE;
		}
		if (i+1 == ptr->SampleToChunk->nb_entries) break;
		GF_StscEntry *next_ent = &ptr->SampleToChunk->entries[i+1];
		if (next_ent->firstChunk < ent->firstChunk) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] first_chunk (%u) for entry %u is greater than first_chunk (%u) for entry %u\n", i+1, ent->firstChunk, i+2, next_ent->firstChunk));
			return GF_ISOM_INVALID_FILE;
		}
	}
	return GF_OK;
}

GF_Box *stbl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
	//maxSamplePer chunk is 10 by default
	tmp->MaxSamplePerChunk = 10;
	tmp->groupID = 1;
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stbl_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err stbl_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;

	gf_isom_check_position(s, (GF_Box *)ptr->SampleDescription, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->TimeToSample, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->CompositionOffset, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->CompositionToDecode, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->SyncSample, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->ShadowSync, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->SampleToChunk, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->SampleSize, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->ChunkOffset, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->DegradationPriority, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->SampleDep, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->PaddingBits, &pos);

	if (ptr->sub_samples) {
		gf_isom_check_position_list(s, ptr->sub_samples, &pos);
	}
	if (ptr->sampleGroupsDescription) {
		gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
	}
	if (ptr->sampleGroups) {
		gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
	}
	if (ptr->sai_sizes) {
		gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
	}
	if (ptr->sai_offsets) {
		gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stco_box_del(GF_Box *s)
{
	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
	if (ptr == NULL) return;
	if (ptr->offsets) gf_free(ptr->offsets);
	gf_free(ptr);
}


GF_Err stco_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 entries;
	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nb_entries = gf_bs_read_u32(bs);
	if (ptr->nb_entries > ptr->size / 4 || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(u32)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stco\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	if (ptr->nb_entries) {
		ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) );
		if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
		ptr->alloc_size = ptr->nb_entries;

		for (entries = 0; entries < ptr->nb_entries; entries++) {
			ptr->offsets[entries] = gf_bs_read_u32(bs);
		}
	}
	return GF_OK;
}

GF_Box *stco_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stco_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i = 0; i < ptr->nb_entries; i++) {
		gf_bs_write_u32(bs, ptr->offsets[i]);
	}
	return GF_OK;
}


GF_Err stco_box_size(GF_Box *s)
{
	GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;

	ptr->size += 4 + (4 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void stdp_box_del(GF_Box *s)
{
	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
	if (ptr == NULL ) return;
	if (ptr->priorities) gf_free(ptr->priorities);
	gf_free(ptr);
}

//this is called through stbl_read...
GF_Err stdp_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 entry;
	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;

	/*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/
	if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2;
	else if (ptr->nb_entries > ptr->size / 2) return GF_ISOM_INVALID_FILE;

	ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16));
	if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
	for (entry = 0; entry < ptr->nb_entries; entry++) {
		ptr->priorities[entry] = gf_bs_read_u16(bs);
	}
	ISOM_DECREASE_SIZE(ptr, (2*ptr->nb_entries) );
	return GF_OK;
}

GF_Box *stdp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stdp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	for (i = 0; i < ptr->nb_entries; i++) {
		gf_bs_write_u16(bs, ptr->priorities[i]);
	}
	return GF_OK;
}

GF_Err stdp_box_size(GF_Box *s)
{
	GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;

	ptr->size += (2 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stsc_box_del(GF_Box *s)
{
	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
	if (ptr == NULL) return;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}


GF_Err stsc_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nb_entries = gf_bs_read_u32(bs);

	if (ptr->nb_entries > ptr->size / 12 || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(GF_StscEntry)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsc\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->alloc_size = ptr->nb_entries;
	ptr->entries = NULL;
	if (ptr->nb_entries) {
		ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size);
		if (!ptr->entries) return GF_OUT_OF_MEM;
	}

	for (i = 0; i < ptr->nb_entries; i++) {
		ptr->entries[i].firstChunk = gf_bs_read_u32(bs);
		ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs);
		ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs);
		ptr->entries[i].isEdited = 0;
		ptr->entries[i].nextChunk = 0;
		if (!ptr->entries[i].firstChunk) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] invalid first chunk 0 in stsc entry\n", ptr->nb_entries));
			return GF_ISOM_INVALID_FILE;
		}

		//update the next chunk in the previous entry
		if (i) ptr->entries[i-1].nextChunk = ptr->entries[i].firstChunk;
	}
	ptr->currentIndex = 0;
	ptr->firstSampleInCurrentChunk = 0;
	ptr->currentChunk = 0;
	ptr->ghostNumber = 0;
	return GF_OK;
}

GF_Box *stsc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stsc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i=0; i<ptr->nb_entries; i++) {
		gf_bs_write_u32(bs, ptr->entries[i].firstChunk);
		gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk);
		gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex);
	}
	return GF_OK;
}

GF_Err stsc_box_size(GF_Box *s)
{
	GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;

	ptr->size += 4 + (12 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void stsd_box_del(GF_Box *s)
{
	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err stsd_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_UnknownBox *def;
	if (!a) return GF_OK;

	if (is_rem || gf_box_valid_in_parent(a, "stsd")) {
		return GF_OK;
	}
	switch (a->type) {
	//unknown sample description: we need a specific box to handle the data ref index
	//rather than a default box ...
	case GF_ISOM_BOX_TYPE_UNKNOWN:
		def = (GF_UnknownBox *)a;
		/*we need at least 8 bytes for unknown sample entries*/
		if (def->dataSize < 8) {
			gf_isom_box_del_parent(&s->child_boxes, a);
			return GF_ISOM_INVALID_MEDIA;
		}
		return GF_OK;

	default:
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type)));
		return GF_ISOM_INVALID_FILE;
	}
}


GF_Err stsd_box_read(GF_Box *s, GF_BitStream *bs)
{
	ISOM_DECREASE_SIZE(s, 4)
	gf_bs_read_u32(bs);

	return gf_isom_box_array_read(s, bs);
}

GF_Box *stsd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
	tmp->child_boxes = gf_list_new();
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stsd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 nb_entries;
	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	nb_entries = gf_list_count(ptr->child_boxes);
	gf_bs_write_u32(bs, nb_entries);
	return GF_OK;
}

GF_Err stsd_box_size(GF_Box *s)
{
	GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
	ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stsh_box_del(GF_Box *s)
{
	u32 i = 0;
	GF_StshEntry *ent;
	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
	if (ptr == NULL) return;
	while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) {
		gf_free(ent);
	}
	gf_list_del(ptr->entries);
	gf_free(ptr);
}



GF_Err stsh_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 count, i;
	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;

	ISOM_DECREASE_SIZE(s, 4)
	count = gf_bs_read_u32(bs);
	if (ptr->size / 8 < count)
		return GF_ISOM_INVALID_FILE;

	for (i = 0; i < count; i++) {
		GF_StshEntry *ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry));
		if (!ent) return GF_OUT_OF_MEM;
		ent->shadowedSampleNumber = gf_bs_read_u32(bs);
		ent->syncSampleNumber = gf_bs_read_u32(bs);
		e = gf_list_add(ptr->entries, ent);
		if (e) return e;
	}
	return GF_OK;
}

GF_Box *stsh_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);

	tmp->entries = gf_list_new();
	if (!tmp->entries) {
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stsh_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_StshEntry *ent;
	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, gf_list_count(ptr->entries));
	i=0;
	while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
		gf_bs_write_u32(bs, ent->shadowedSampleNumber);
		gf_bs_write_u32(bs, ent->syncSampleNumber);
	}
	return GF_OK;
}

GF_Err stsh_box_size(GF_Box *s)
{
	GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
	ptr->size += 4 + (8 * gf_list_count(ptr->entries));
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void stss_box_del(GF_Box *s)
{
	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
	if (ptr == NULL) return;
	if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers);
	gf_free(ptr);
}

GF_Err stss_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nb_entries = gf_bs_read_u32(bs);
	if (ptr->size / 4 <  ptr->nb_entries || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(u32)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stss\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->alloc_size = ptr->nb_entries;
	ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32));
	if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM;

	for (i = 0; i < ptr->nb_entries; i++) {
		ptr->sampleNumbers[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

GF_Box *stss_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
	return (GF_Box*)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stss_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i = 0; i < ptr->nb_entries; i++) {
		gf_bs_write_u32(bs, ptr->sampleNumbers[i]);
	}
	return GF_OK;
}

GF_Err stss_box_size(GF_Box *s)
{
	GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
	ptr->size += 4 + (4 * ptr->nb_entries);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stsz_box_del(GF_Box *s)
{
	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
	if (ptr == NULL) return;
	if (ptr->sizes) gf_free(ptr->sizes);
	gf_free(ptr);
}


GF_Err stsz_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, estSize;
	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	//support for CompactSizes
	if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->sampleSize = gf_bs_read_u32(bs);
		ptr->sampleCount = gf_bs_read_u32(bs);
	} else {
		//24-reserved
		ISOM_DECREASE_SIZE(ptr, 8);
		gf_bs_read_int(bs, 24);
		i = gf_bs_read_u8(bs);
		ptr->sampleCount = gf_bs_read_u32(bs);
		switch (i) {
		case 4:
		case 8:
		case 16:
			ptr->sampleSize = i;
			break;
		default:
			//try to fix the file
			//no samples, no parsing pb
			if (!ptr->sampleCount) {
				ptr->sampleSize = 16;
				return GF_OK;
			}
			estSize = (u32) (ptr->size) / ptr->sampleCount;
			if (!estSize && ((ptr->sampleCount+1)/2 == (ptr->size)) ) {
				ptr->sampleSize = 4;
				break;
			} else if (estSize == 1 || estSize == 2) {
				ptr->sampleSize = 8 * estSize;
			} else {
				return GF_ISOM_INVALID_FILE;
			}
		}
	}
	if (ptr->sampleCount && (u64)ptr->sampleCount > (u64)SIZE_MAX/sizeof(u32)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
		return GF_ISOM_INVALID_FILE;
	}
	if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
		if (! ptr->sampleSize && ptr->sampleCount) {
			if (ptr->sampleCount > ptr->size / 4) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
				return GF_ISOM_INVALID_FILE;
			}
			ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
			if (! ptr->sizes) return GF_OUT_OF_MEM;
			ptr->alloc_size = ptr->sampleCount;
			for (i = 0; i < ptr->sampleCount; i++) {
				ptr->sizes[i] = gf_bs_read_u32(bs);
				if (ptr->max_size < ptr->sizes[i])
					ptr->max_size = ptr->sizes[i];
				ptr->total_size += ptr->sizes[i];
				ptr->total_samples++;
			}
		}
	} else {
		if (ptr->sampleSize==4) {
			if (ptr->sampleCount / 2 > ptr->size) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
				return GF_ISOM_INVALID_FILE;
			}
		} else {
			if (ptr->sampleCount > ptr->size / (ptr->sampleSize/8)) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
				return GF_ISOM_INVALID_FILE;
			}
		}
		//note we could optimize the mem usage by keeping the table compact
		//in memory. But that would complicate both caching and editing
		//we therefore keep all sizes as u32 and uncompress the table
		ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
		if (! ptr->sizes) return GF_OUT_OF_MEM;
		ptr->alloc_size = ptr->sampleCount;

		for (i = 0; i < ptr->sampleCount; ) {
			u32 s_size;
			switch (ptr->sampleSize) {
			case 4:
				s_size = ptr->sizes[i] = gf_bs_read_int(bs, 4);
				if (ptr->max_size < s_size)
					ptr->max_size = s_size;
				ptr->total_size += s_size;
				ptr->total_samples++;
				if (i+1 < ptr->sampleCount) {
					s_size = ptr->sizes[i+1] = gf_bs_read_int(bs, 4);
					if (ptr->max_size < s_size)
						ptr->max_size = s_size;
					ptr->total_size += s_size;
					ptr->total_samples++;
				} else {
					//0 padding in odd sample count
					gf_bs_read_int(bs, 4);
				}
				i += 2;
				break;
			default:
				s_size = ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize);
				if (ptr->max_size < s_size)
					ptr->max_size = s_size;
				ptr->total_size += s_size;
				ptr->total_samples++;
				i += 1;
				break;
			}
		}
	}
	return GF_OK;
}

GF_Box *stsz_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);

	//type is unknown here, can be regular or compact table
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stsz_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	//in both versions this is still valid
	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
		gf_bs_write_u32(bs, ptr->sampleSize);
	} else {
		gf_bs_write_u24(bs, 0);
		gf_bs_write_u8(bs, ptr->sampleSize);
	}
	gf_bs_write_u32(bs, ptr->sampleCount);

	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
		if (ptr->sampleSize) return GF_OK;
		for (i = 0; i < ptr->sampleCount; i++) {
			gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0);
		}
	} else {
		if (!ptr->sizes) return GF_ISOM_INVALID_FILE;
		for (i = 0; i < ptr->sampleCount; ) {
			switch (ptr->sampleSize) {
			case 4:
				gf_bs_write_int(bs, ptr->sizes[i], 4);
				if (i+1 < ptr->sampleCount) {
					gf_bs_write_int(bs, ptr->sizes[i+1], 4);
				} else {
					//0 padding in odd sample count
					gf_bs_write_int(bs, 0, 4);
				}
				i += 2;
				break;
			default:
				gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize);
				i += 1;
				break;
			}
		}
	}
	return GF_OK;
}

GF_Err stsz_box_size(GF_Box *s)
{
	u32 i, fieldSize, size;
	GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;

	ptr->size += 8;
	if (!ptr->sampleCount) return GF_OK;

	//regular table
	if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
		if (ptr->sampleSize) return GF_OK;
		ptr->size += (4 * ptr->sampleCount);
		return GF_OK;
	}
	if (!ptr->sizes) return GF_ISOM_INVALID_FILE;

	//compact size table
	fieldSize = 4;
	size = ptr->sizes[0];

	for (i=0; i < ptr->sampleCount; i++) {
		if (ptr->sizes[i] <= 0xF) {
		}
		//switch to 8-bit table
		else if (ptr->sizes[i] <= 0xFF) {
			fieldSize = 8;
		}
		//switch to 16-bit table
		else if (ptr->sizes[i] <= 0xFFFF) {
			fieldSize = 16;
		}
		//switch to 32-bit table
		else {
			fieldSize = 32;
		}

		//check the size
		if (size != ptr->sizes[i]) size = 0;
	}
	//if all samples are of the same size, switch to regular (more compact)
	if (size) {
		ptr->type = GF_ISOM_BOX_TYPE_STSZ;
		ptr->sampleSize = size;
		gf_free(ptr->sizes);
		ptr->sizes = NULL;
		return GF_OK;
	}

	if (fieldSize == 32) {
		//oops, doesn't fit in a compact table
		ptr->type = GF_ISOM_BOX_TYPE_STSZ;
		ptr->size += (4 * ptr->sampleCount);
		return GF_OK;
	}

	//make sure we are a compact table (no need to change the mem representation)
	ptr->type = GF_ISOM_BOX_TYPE_STZ2;
	ptr->sampleSize = fieldSize;
	if (fieldSize == 4) {
		//do not forget the 0 padding field for odd count
		ptr->size += (ptr->sampleCount + 1) / 2;
	} else {
		ptr->size += (ptr->sampleCount) * (fieldSize/8);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void stts_box_del(GF_Box *s)
{
	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}


GF_Err stts_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	u32 nb_patches=0, needs_patch = 0;
	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;

#ifndef GPAC_DISABLE_ISOM_WRITE
	ptr->w_LastDTS = 0;
#endif

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->nb_entries = gf_bs_read_u32(bs);
	if (ptr->size / 8 < ptr->nb_entries || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(GF_SttsEntry)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stts\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->alloc_size = ptr->nb_entries;
	ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size);
	if (!ptr->entries) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->nb_entries; i++) {
		ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
		ptr->entries[i].sampleDelta = gf_bs_read_u32(bs);

		//check for 0-duration
		if (!ptr->entries[i].sampleDelta
			//forbiden if not last sample
			&& ((i+1 < ptr->nb_entries) || (ptr->entries[i].sampleCount>1))
		) {
			needs_patch += ptr->entries[i].sampleCount;
			if (i + 1 == ptr->nb_entries) needs_patch --;
			ptr->entries[i].sampleDelta = 1;
			nb_patches++;
		}

		//cf issue 1644: some media streams may have sample duration > 2^31 (ttml mostly), we cannot patch this
		//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
#if 0
		else if ((s32) ptr->entries[i].sampleDelta < 0) {
			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 re-importing raw media)\n", i, (s32) ptr->entries[i].sampleDelta ));
			ptr->entries[i].sampleDelta = 1;
		}
#endif

		//we patch exitsing sample_delta=0 to sample_delta=1 but we want to avoid breaking the timing of following samples
		//accumulate the ticks added due to patching and remove them from previous entries - cf #3319
		if (needs_patch) {
			s64 k;
			//walk down the previous samples and try to shorten the duration
			for (k=i; k>=0; k--) {
				if (ptr->entries[k].sampleDelta == 1) continue;
				//we only try to locate entries with a delta larger than the accumulated number of patches
				if (ptr->entries[k].sampleDelta <= needs_patch) continue;

				if (ptr->entries[k].sampleCount == 1) {
					ptr->entries[k].sampleDelta -= needs_patch;
					needs_patch = 0;
					break;
				}
				//split entry in two
				if (ptr->nb_entries>=ptr->alloc_size) {
					ptr->alloc_size += 1;
					ptr->entries = gf_realloc(ptr->entries, sizeof(GF_SttsEntry) * ptr->alloc_size);
				}
				memmove(&ptr->entries[k+2], &ptr->entries[k+1], sizeof(GF_SttsEntry) * (ptr->nb_entries - k - 1) );
				ptr->entries[k].sampleCount -= 1;
				ptr->entries[k+1].sampleCount = 1;
				ptr->entries[k+1].sampleDelta = ptr->entries[k].sampleDelta - needs_patch;
				i++;
				ptr->nb_entries++;
				needs_patch = 0;
				break;
			}
		}
		//needs_patch may still be non-0 if we couldn't find an entry, we'll adjust ts of next entries


#ifndef GPAC_DISABLE_ISOM_WRITE
		ptr->w_currentSampleNum += ptr->entries[i].sampleCount;
		ptr->w_LastDTS += (u64)ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta;
#endif
		if (ptr->max_ts_delta<ptr->entries[i].sampleDelta)
			ptr->max_ts_delta = ptr->entries[i].sampleDelta;

	}
	ISOM_DECREASE_SIZE(ptr, ptr->nb_entries*8);

	if (nb_patches) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found %u stts entries with forbidden sample_delta=0 - patching to 1\n", nb_patches));
		if (needs_patch) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %u stts patches failed\n", needs_patch));
		}
	}

	//remove the last sample delta.
#ifndef GPAC_DISABLE_ISOM_WRITE
	if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta;
#endif
	return GF_OK;
}

GF_Box *stts_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stts_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->nb_entries);
	for (i=0; i<ptr->nb_entries; i++) {
		gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
		gf_bs_write_u32(bs, ptr->entries[i].sampleDelta);
	}
	return GF_OK;
}

GF_Err stts_box_size(GF_Box *s)
{
	GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
	ptr->size += 4 + (8 * ptr->nb_entries);
	return GF_OK;
}


#endif /*GPAC_DISABLE_ISOM_WRITE*/


#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void tfhd_box_del(GF_Box *s)
{
	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err tfhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->trackID = gf_bs_read_u32(bs);

	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->base_data_offset = gf_bs_read_u64(bs);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->sample_desc_index = gf_bs_read_u32(bs);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->def_sample_duration = gf_bs_read_u32(bs);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->def_sample_size = gf_bs_read_u32(bs);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->def_sample_flags = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

GF_Box *tfhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
	//NO FLAGS SET BY DEFAULT
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err tfhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->trackID);

	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
		gf_bs_write_u64(bs, ptr->base_data_offset);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
		gf_bs_write_u32(bs, ptr->sample_desc_index);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
		gf_bs_write_u32(bs, ptr->def_sample_duration);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
		gf_bs_write_u32(bs, ptr->def_sample_size);
	}
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
		gf_bs_write_u32(bs, ptr->def_sample_flags);
	}
	return GF_OK;
}

GF_Err tfhd_box_size(GF_Box *s)
{
	GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
	ptr->size += 4;

	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8;
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


void tims_box_del(GF_Box *s)
{
	GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
	gf_free(tims);
}

GF_Err tims_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->timeScale = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *tims_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tims_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->timeScale);
	return GF_OK;
}

GF_Err tims_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void tkhd_box_del(GF_Box *s)
{
	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
	return;
}


GF_Err tkhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;

	if (ptr->version == 1) {
		ISOM_DECREASE_SIZE(ptr, 32);
		ptr->creationTime = gf_bs_read_u64(bs);
		ptr->modificationTime = gf_bs_read_u64(bs);
		ptr->trackID = gf_bs_read_u32(bs);
		ptr->reserved1 = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 20);
		ptr->creationTime = gf_bs_read_u32(bs);
		ptr->modificationTime = gf_bs_read_u32(bs);
		ptr->trackID = gf_bs_read_u32(bs);
		ptr->reserved1 = gf_bs_read_u32(bs);
		ptr->duration = gf_bs_read_u32(bs);
	}
	ptr->initial_duration = ptr->duration;

	ISOM_DECREASE_SIZE(ptr, 60);
	ptr->reserved2[0] = gf_bs_read_u32(bs);
	ptr->reserved2[1] = gf_bs_read_u32(bs);
	ptr->layer = gf_bs_read_u16(bs);
	ptr->alternate_group = gf_bs_read_u16(bs);
	ptr->volume = gf_bs_read_u16(bs);
	ptr->reserved3 = gf_bs_read_u16(bs);
	ptr->matrix[0] = gf_bs_read_u32(bs);
	ptr->matrix[1] = gf_bs_read_u32(bs);
	ptr->matrix[2] = gf_bs_read_u32(bs);
	ptr->matrix[3] = gf_bs_read_u32(bs);
	ptr->matrix[4] = gf_bs_read_u32(bs);
	ptr->matrix[5] = gf_bs_read_u32(bs);
	ptr->matrix[6] = gf_bs_read_u32(bs);
	ptr->matrix[7] = gf_bs_read_u32(bs);
	ptr->matrix[8] = gf_bs_read_u32(bs);
	ptr->width = gf_bs_read_u32(bs);
	ptr->height = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *tkhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
	tmp->matrix[0] = 0x00010000;
	tmp->matrix[4] = 0x00010000;
	tmp->matrix[8] = 0x40000000;
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tkhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->version == 1) {
		gf_bs_write_u64(bs, ptr->creationTime);
		gf_bs_write_u64(bs, ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->trackID);
		gf_bs_write_u32(bs, ptr->reserved1);
		gf_bs_write_u64(bs, ptr->duration);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->creationTime);
		gf_bs_write_u32(bs, (u32) ptr->modificationTime);
		gf_bs_write_u32(bs, ptr->trackID);
		gf_bs_write_u32(bs, ptr->reserved1);
		gf_bs_write_u32(bs, (u32) ptr->duration);
	}
	gf_bs_write_u32(bs, ptr->reserved2[0]);
	gf_bs_write_u32(bs, ptr->reserved2[1]);
	gf_bs_write_u16(bs, ptr->layer);
	gf_bs_write_u16(bs, ptr->alternate_group);
	gf_bs_write_u16(bs, ptr->volume);
	gf_bs_write_u16(bs, ptr->reserved3);
	gf_bs_write_u32(bs, ptr->matrix[0]);
	gf_bs_write_u32(bs, ptr->matrix[1]);
	gf_bs_write_u32(bs, ptr->matrix[2]);
	gf_bs_write_u32(bs, ptr->matrix[3]);
	gf_bs_write_u32(bs, ptr->matrix[4]);
	gf_bs_write_u32(bs, ptr->matrix[5]);
	gf_bs_write_u32(bs, ptr->matrix[6]);
	gf_bs_write_u32(bs, ptr->matrix[7]);
	gf_bs_write_u32(bs, ptr->matrix[8]);
	gf_bs_write_u32(bs, ptr->width);
	gf_bs_write_u32(bs, ptr->height);
	return GF_OK;
}

GF_Err tkhd_box_size(GF_Box *s)
{
	GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;

	ptr->version = 0;

	if (ptr->duration!=(u64)-1 && (ptr->duration>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->creationTime!=(u64)-1 && (ptr->creationTime>0xFFFFFFFF)) ptr->version = 1;
	if (ptr->modificationTime!=(u64)-1 && (ptr->modificationTime>0xFFFFFFFF)) ptr->version = 1;

	ptr->size += (ptr->version == 1) ? 32 : 20;
	ptr->size += 60;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void traf_box_del(GF_Box *s)
{
	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
	if (ptr == NULL) return;
	if (ptr->sub_samples) gf_list_del(ptr->sub_samples);
	gf_list_del(ptr->TrackRuns);
	if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups);
	if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription);
	if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes);
	if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets);
	gf_free(ptr);
}

GF_Err traf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;

	switch (a->type) {
	case GF_ISOM_BOX_TYPE_TFHD:
		BOX_FIELD_ASSIGN(tfhd, GF_TrackFragmentHeaderBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TRUN:
		BOX_FIELD_LIST_ASSIGN(TrackRuns)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SDTP:
		BOX_FIELD_ASSIGN(sdtp, GF_SampleDependencyTypeBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TFDT:
		BOX_FIELD_ASSIGN(tfdt, GF_TFBaseMediaDecodeTimeBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_RSOT:
		BOX_FIELD_ASSIGN(rsot, GF_TFOriginalDurationBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SUBS:
		BOX_FIELD_LIST_ASSIGN(sub_samples)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SBGP:
	case GF_ISOM_BOX_TYPE_CSGP:
		BOX_FIELD_LIST_ASSIGN(sampleGroups)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SGPD:
		BOX_FIELD_LIST_ASSIGN(sampleGroupsDescription)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SAIZ:
		BOX_FIELD_LIST_ASSIGN(sai_sizes)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SAIO:
		BOX_FIELD_LIST_ASSIGN(sai_offsets)
		return GF_OK;
	//we will throw an error if both PIFF_PSEC and SENC are found. Not such files seen yet
	case GF_ISOM_BOX_TYPE_UUID:
		if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) {
			BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
			if (!is_rem)
				ptr->sample_encryption->traf = ptr;
			return GF_OK;
		} else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFXD) {
			BOX_FIELD_ASSIGN(tfxd, GF_MSSTimeExtBox)
			return GF_OK;
		} else if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_TFRF) {
			BOX_FIELD_ASSIGN(tfrf, GF_MSSTimeRefBox)
			return GF_OK;
		} else {
			return GF_OK;
		}
	case GF_ISOM_BOX_TYPE_SENC:
		BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
		if (!is_rem)
			ptr->sample_encryption->traf = ptr;
		return GF_OK;
	case GF_GPAC_BOX_TYPE_SREF:
	case GF_ISOM_BOX_TYPE_CDRF:
		BOX_FIELD_ASSIGN(SampleRefs, GF_SampleReferences)
		return GF_OK;
	}
	return GF_OK;
}


GF_Err traf_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
	GF_Err e = gf_isom_box_array_read(s, bs);
	if (e) return e;

	if (!ptr->tfhd) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackFragmentHeaderBox \n"));
		return GF_ISOM_INVALID_FILE;
	}
	return GF_OK;
}

GF_Box *traf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
	tmp->TrackRuns = gf_list_new();

	if (gf_sys_old_arch_compat())
		tmp->no_sdtp_first_flags = 1;
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err traf_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err traf_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *) s;

	//Header first
	gf_isom_check_position(s, (GF_Box *)ptr->tfhd, &pos);
	gf_isom_check_position_list(s, ptr->sub_samples, &pos);

	gf_isom_check_position(s, (GF_Box *)ptr->tfdt, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->rsot, &pos);

	//cmaf-like
	if (ptr->truns_first) {
		gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
		gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
		gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
		//senc MUST be after saio in GPAC, as senc writing uses info from saio writing
		gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
		gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
		gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
		//subsamples will be last
	} else {
		gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos);
		gf_isom_check_position_list(s, ptr->sampleGroups, &pos);
		gf_isom_check_position_list(s, ptr->sai_sizes, &pos);
		gf_isom_check_position_list(s, ptr->sai_offsets, &pos);
		gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos);
		gf_isom_check_position_list(s, ptr->TrackRuns, &pos);
	}

	//when sdtp is present (smooth-like) write it after the trun box
	gf_isom_check_position(s, (GF_Box *)ptr->sdtp, &pos);

	//tfxd should be last ...
	if (ptr->tfxd)
		gf_isom_check_position(s, (GF_Box *)ptr->tfxd, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *tfxd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID);
	tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD;
	tmp->version = 1;
	return (GF_Box *)tmp;
}

void tfxd_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err tfxd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);

	if (ptr->version == 0x01) {
		ISOM_DECREASE_SIZE(ptr, 16);
		ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs);
		ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs);
		ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
	}

	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tfxd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, 0);
	if (ptr->version) {
		gf_bs_write_u64(bs, ptr->absolute_time_in_track_timescale);
		gf_bs_write_u64(bs, ptr->fragment_duration_in_track_timescale);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->absolute_time_in_track_timescale);
		gf_bs_write_u32(bs, (u32) ptr->fragment_duration_in_track_timescale);
	}
	return GF_OK;
}

GF_Err tfxd_box_size(GF_Box *s)
{
	GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)s;
	s->size += 4 + (ptr->version ? 16 : 8);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE



GF_Box *tfrf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MSSTimeRefBox, GF_ISOM_BOX_TYPE_UUID);
	tmp->internal_4cc = GF_ISOM_BOX_UUID_TFRF;
	return (GF_Box *)tmp;
}

void tfrf_box_del(GF_Box *s)
{
	GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
	if (ptr->frags) gf_free(ptr->frags);
	gf_free(s);
}


GF_Err tfrf_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox *)s;
	ISOM_DECREASE_SIZE(ptr, 5);
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	ptr->frags_count = gf_bs_read_u8(bs);
	ptr->frags = gf_malloc(sizeof(GF_MSSTimeEntry) * ptr->frags_count);
	if (!ptr->frags) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->frags_count; i++) {
		if (ptr->version == 0x01) {
			ISOM_DECREASE_SIZE(ptr, 16);
			ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u64(bs);
			ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
		} else {
			ISOM_DECREASE_SIZE(ptr, 8);
			ptr->frags[i].absolute_time_in_track_timescale = gf_bs_read_u32(bs);
			ptr->frags[i].fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
		}
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tfrf_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, 0);
	gf_bs_write_u8(bs, ptr->frags_count);
	for (i=0; i<ptr->frags_count; i++) {
		if (ptr->version==0x01) {
			gf_bs_write_u64(bs, ptr->frags[i].absolute_time_in_track_timescale);
			gf_bs_write_u64(bs, ptr->frags[i].fragment_duration_in_track_timescale);
		} else {
			gf_bs_write_u32(bs, (u32) ptr->frags[i].absolute_time_in_track_timescale);
			gf_bs_write_u32(bs, (u32) ptr->frags[i].fragment_duration_in_track_timescale);
		}
	}
	return GF_OK;
}

GF_Err tfrf_box_size(GF_Box *s)
{
	GF_MSSTimeRefBox *ptr = (GF_MSSTimeRefBox*)s;
	s->size += 5;
	if (ptr->version) s->size += 16 * ptr->frags_count;
	else s->size += 8 * ptr->frags_count;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


void trak_box_del(GF_Box *s)
{
#ifndef GPAC_DISABLE_ISOM_WRITE
	GF_TrackBox *ptr = (GF_TrackBox *)s;
	if (ptr->chunk_cache)
		gf_bs_del(ptr->chunk_cache);
#endif
	gf_free(s);
}

static void stsd_switch_box(GF_BitStream *bs, GF_Box *box, GF_UnknownBox *a, u8 **data, u32 *data_size, u32 *EntryType, GF_SampleDescriptionBox *stsd, u32 stsd_idx)
{
	if (gf_bs_available(bs)) {
		GF_Err e;
		u32 count_subb;
		gf_bs_set_cookie(bs, GF_ISOM_BS_COOKIE_NO_LOGS);
		e = gf_isom_box_array_read(box, bs);
		count_subb = box->child_boxes ? gf_list_count(box->child_boxes) : 0;
		if (count_subb && !e) {
			u32 i;
			GF_BitStream *new_dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			//serialize all unknown boxes
			for (i=0; i<count_subb; i++) {
				GF_UnknownBox *priv = gf_list_get(box->child_boxes, i);
				if (priv->type != GF_ISOM_BOX_TYPE_UNKNOWN) continue;
				gf_bs_write_u32(new_dsi, 8 + priv->dataSize);
				gf_bs_write_u32(new_dsi, priv->original_4cc);
				gf_bs_write_data(new_dsi, priv->data, priv->dataSize);
				gf_list_rem(box->child_boxes, i);
				gf_isom_box_del((GF_Box*)priv);
				count_subb--;
				i--;
			}
			if (*data) gf_free(*data);
			gf_bs_get_content(new_dsi, data, data_size);
			gf_bs_del(new_dsi);
		} else {
			*data_size = 0;
		}
	}
	gf_bs_del(bs);
	if (!*data_size && *data) {
		gf_free(*data);
		*data = NULL;
	}
	box->size = 0;
	*EntryType = a->original_4cc;
	gf_list_rem(stsd->child_boxes, stsd_idx);
	gf_isom_box_del((GF_Box *)a);
	gf_list_insert(stsd->child_boxes, box, stsd_idx);
}


static GF_Err gf_isom_check_sample_desc(GF_TrackBox *trak)
{
	GF_BitStream *bs;
	GF_UnknownBox *a;
	u32 i;
	GF_Err e;
	GF_SampleTableBox *stbl;

	if (!trak->Media || !trak->Media->information) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" ));
		return GF_OK;
	}
	if (!trak->Media->information->sampleTable) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" ));
		trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new_parent(&trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_STBL);
	}
	stbl = trak->Media->information->sampleTable;

	if (!stbl->SampleDescription) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" ));
		stbl->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new_parent(&stbl->child_boxes, GF_ISOM_BOX_TYPE_STSD);
		return GF_OK;
	}

	i=0;
	while ((a = (GF_UnknownBox*)gf_list_enum(stbl->SampleDescription->child_boxes, &i))) {
		GF_ProtectionSchemeInfoBox *sinf;
		u32 base_ent_type = 0;
		u32 type = a->type;
		u32 sinf_type = GF_ISOM_BOX_TYPE_SINF;
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_RESV:
			sinf_type = GF_ISOM_BOX_TYPE_RINF;
		case GF_ISOM_BOX_TYPE_ENCS:
		case GF_ISOM_BOX_TYPE_ENCA:
		case GF_ISOM_BOX_TYPE_ENCV:
		case GF_ISOM_BOX_TYPE_ENCT:
			sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(a->child_boxes, sinf_type);
			if (!sinf || !sinf->original_format) return GF_ISOM_INVALID_FILE;
			type = sinf->original_format->data_format;
			base_ent_type = ((GF_SampleEntryBox *)a)->internal_type;
			break;
		}

		switch (type) {
		case GF_ISOM_BOX_TYPE_MP4S:
			if (base_ent_type && (base_ent_type != GF_ISOM_SAMPLE_ENTRY_MP4S)) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Protected sample entry %s uses incompatible sample description %s\n", gf_4cc_to_str(a->type), gf_4cc_to_str(type) ));

				return GF_ISOM_INVALID_FILE;
			}
			continue;

		case GF_ISOM_SUBTYPE_3GP_AMR:
		case GF_ISOM_SUBTYPE_3GP_AMR_WB:
		case GF_ISOM_SUBTYPE_3GP_EVRC:
		case GF_ISOM_SUBTYPE_3GP_QCELP:
		case GF_ISOM_SUBTYPE_3GP_SMV:
		case GF_ISOM_BOX_TYPE_MP4A:
		case GF_ISOM_BOX_TYPE_MP3:
		case GF_ISOM_BOX_TYPE_MHA1:
		case GF_ISOM_BOX_TYPE_MHA2:
		case GF_ISOM_BOX_TYPE_MHM1:
		case GF_ISOM_BOX_TYPE_MHM2:
		case GF_ISOM_BOX_TYPE_OPUS:
		case GF_ISOM_BOX_TYPE_AC3:
		case GF_ISOM_BOX_TYPE_EC3:
		case GF_ISOM_BOX_TYPE_AC4:
		case GF_QT_SUBTYPE_RAW_AUD:
		case GF_QT_SUBTYPE_TWOS:
		case GF_QT_SUBTYPE_SOWT:
		case GF_QT_SUBTYPE_FL32:
		case GF_QT_SUBTYPE_FL64:
		case GF_QT_SUBTYPE_IN24:
		case GF_QT_SUBTYPE_IN32:
		case GF_QT_SUBTYPE_ULAW:
		case GF_QT_SUBTYPE_ALAW:
		case GF_QT_SUBTYPE_ADPCM:
		case GF_QT_SUBTYPE_IMA_ADPCM:
		case GF_QT_SUBTYPE_DVCA:
		case GF_QT_SUBTYPE_QDMC:
		case GF_QT_SUBTYPE_QDMC2:
		case GF_QT_SUBTYPE_QCELP:
		case GF_QT_SUBTYPE_kMP3:
		case GF_ISOM_BOX_TYPE_IPCM:
		case GF_ISOM_BOX_TYPE_FPCM:
			if (base_ent_type && (base_ent_type != GF_ISOM_SAMPLE_ENTRY_AUDIO))
				return GF_ISOM_INVALID_FILE;
			continue;

		case GF_ISOM_BOX_TYPE_MP4V:
		case GF_ISOM_SUBTYPE_3GP_H263:
		case GF_ISOM_BOX_TYPE_AVC1:
		case GF_ISOM_BOX_TYPE_AVC2:
		case GF_ISOM_BOX_TYPE_AVC3:
		case GF_ISOM_BOX_TYPE_AVC4:
		case GF_ISOM_BOX_TYPE_SVC1:
		case GF_ISOM_BOX_TYPE_MVC1:
		case GF_ISOM_BOX_TYPE_HVC1:
		case GF_ISOM_BOX_TYPE_HEV1:
		case GF_ISOM_BOX_TYPE_HVC2:
		case GF_ISOM_BOX_TYPE_HEV2:
		case GF_ISOM_BOX_TYPE_HVT1:
		case GF_ISOM_BOX_TYPE_LHV1:
		case GF_ISOM_BOX_TYPE_LHE1:
		case GF_ISOM_BOX_TYPE_AV01:
		case GF_ISOM_BOX_TYPE_VP08:
		case GF_ISOM_BOX_TYPE_VP09:
		case GF_ISOM_BOX_TYPE_VP10:
		case GF_ISOM_BOX_TYPE_AV1C:
		case GF_ISOM_BOX_TYPE_AV3C:
		case GF_ISOM_BOX_TYPE_AVS3:
		case GF_ISOM_BOX_TYPE_JPEG:
		case GF_ISOM_BOX_TYPE_PNG:
		case GF_ISOM_BOX_TYPE_JP2K:
		case GF_ISOM_BOX_TYPE_MJP2:
		case GF_QT_SUBTYPE_APCH:
		case GF_QT_SUBTYPE_APCO:
		case GF_QT_SUBTYPE_APCN:
		case GF_QT_SUBTYPE_APCS:
		case GF_QT_SUBTYPE_AP4X:
		case GF_QT_SUBTYPE_AP4H:
		case GF_ISOM_BOX_TYPE_VVC1:
		case GF_ISOM_BOX_TYPE_VVI1:
		case GF_QT_SUBTYPE_RAW_VID:
		case GF_QT_SUBTYPE_YUYV:
		case GF_QT_SUBTYPE_UYVY:
		case GF_QT_SUBTYPE_YUV444:
		case GF_QT_SUBTYPE_YUVA444:
		case GF_QT_SUBTYPE_YUV422_10:
		case GF_QT_SUBTYPE_YUV444_10:
		case GF_QT_SUBTYPE_YUV422_16:
		case GF_QT_SUBTYPE_YUV420:
		case GF_QT_SUBTYPE_I420:
		case GF_QT_SUBTYPE_IYUV:
		case GF_QT_SUBTYPE_YV12:
		case GF_QT_SUBTYPE_YVYU:
		case GF_QT_SUBTYPE_RGBA:
		case GF_QT_SUBTYPE_ABGR:
		case GF_ISOM_BOX_TYPE_DVHE:
		case GF_ISOM_BOX_TYPE_DVH1:
		case GF_ISOM_BOX_TYPE_DVA1:
		case GF_ISOM_BOX_TYPE_DVAV:
		case GF_ISOM_BOX_TYPE_DAV1:
			if (base_ent_type && (base_ent_type != GF_ISOM_SAMPLE_ENTRY_VIDEO))
				return GF_ISOM_INVALID_FILE;
			continue;


		case GF_ISOM_BOX_TYPE_METX:
		case GF_ISOM_BOX_TYPE_METT:
		case GF_ISOM_BOX_TYPE_STXT:
		case GF_ISOM_BOX_TYPE_TX3G:
		case GF_ISOM_BOX_TYPE_TEXT:
		case GF_ISOM_BOX_TYPE_GHNT:
		case GF_ISOM_BOX_TYPE_RTP_STSD:
		case GF_ISOM_BOX_TYPE_SRTP_STSD:
		case GF_ISOM_BOX_TYPE_FDP_STSD:
		case GF_ISOM_BOX_TYPE_RRTP_STSD:
		case GF_ISOM_BOX_TYPE_RTCP_STSD:
		case GF_ISOM_BOX_TYPE_DIMS:
		case GF_ISOM_BOX_TYPE_LSR1:
		case GF_ISOM_BOX_TYPE_WVTT:
		case GF_ISOM_BOX_TYPE_STPP:
		case GF_ISOM_BOX_TYPE_SBTT:
			if (base_ent_type && (base_ent_type != GF_ISOM_SAMPLE_ENTRY_GENERIC))
				return GF_ISOM_INVALID_FILE;
			continue;


		case GF_ISOM_BOX_TYPE_UNKNOWN:
			break;
		default:
			if (gf_box_valid_in_parent((GF_Box *) a, "stsd")) {
				continue;
			}
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type)));
			continue;
		}
		//we are sure to have an unknown box here
		if (a->type!=GF_ISOM_BOX_TYPE_UNKNOWN) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s not supported\n", gf_4cc_to_str(a->type) ));
			continue;
		}

		if (!a->data || (a->dataSize<8) ) {
			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) ));
			continue;
		}
		else if (a->dataSize > a->size) {
			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));
			continue;
		}

		/*only process visual or audio
		note: no need for new_box_parent here since we always store sample descriptions in child_boxes*/
		switch (trak->Media->handler->handlerType) {
		case GF_ISOM_MEDIA_VISUAL:
		case GF_ISOM_MEDIA_AUXV:
		case GF_ISOM_MEDIA_PICT:
		{
			GF_GenericVisualSampleEntryBox *genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
			genv->size = a->size-8;
			e = gnrv_box_read((GF_Box *) genv, bs);
			if (e) {
				gf_bs_del(bs);
				gnrv_box_del((GF_Box *)genv);
				return e;
			}

			stsd_switch_box(bs, (GF_Box *) genv, a, &genv->data, &genv->data_size, &genv->EntryType, trak->Media->information->sampleTable->SampleDescription, i-1);
		}
		break;
		case GF_ISOM_MEDIA_AUDIO:
		{
			GF_GenericAudioSampleEntryBox *gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
			gena->size = a->size-8;
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
			e = gnra_box_read((GF_Box *) gena, bs);
			if (e) {
				gf_bs_del(bs);
				gnra_box_del((GF_Box *)gena);
				return e;
			}

			stsd_switch_box(bs, (GF_Box *) gena, a, &gena->data, &gena->data_size, &gena->EntryType, trak->Media->information->sampleTable->SampleDescription, i-1);
		}
		break;

		default:
		{
			GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
			genm->size = a->size-8;
			bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);

			e = gnrm_box_read((GF_Box *)genm, bs);
			if (e) {
				gf_bs_del(bs);
				gnrm_box_del((GF_Box *)genm);
				return e;
			}

			stsd_switch_box(bs, (GF_Box *) genm, a, &genm->data, &genm->data_size, &genm->EntryType, trak->Media->information->sampleTable->SampleDescription, i-1);
		}
		break;
		}
	}
	return GF_OK;
}


GF_Err trak_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_TrackBox *ptr = (GF_TrackBox *)s;
	if (!a) return GF_OK;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_TKHD:
		BOX_FIELD_ASSIGN(Header, GF_TrackHeaderBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_EXTL:
		BOX_FIELD_ASSIGN(extl, GF_ExternalTrackLocationBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_EDTS:
		BOX_FIELD_ASSIGN(editBox, GF_EditBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_UDTA:
		BOX_FIELD_ASSIGN(udta, GF_UserDataBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_META:
		BOX_FIELD_ASSIGN(meta, GF_MetaBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TREF:
		BOX_FIELD_ASSIGN(References, GF_TrackReferenceBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_MDIA:
		BOX_FIELD_ASSIGN(Media, GF_MediaBox)
		if (!is_rem)
			((GF_MediaBox *)a)->mediaTrack = ptr;
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TRGR:
		BOX_FIELD_ASSIGN(groups, GF_TrackGroupBox)
		return GF_OK;
	case GF_QT_BOX_TYPE_TAPT:
		BOX_FIELD_ASSIGN(Aperture, GF_Box)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SENC:
		BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_UUID:
		if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
			BOX_FIELD_ASSIGN(sample_encryption, GF_SampleEncryptionBox)
			return GF_OK;
		}
	}
	return GF_OK;
}


GF_Err trak_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrackBox *ptr = (GF_TrackBox *)s;
	e = gf_isom_box_array_read(s, bs);
	if (e) return e;
	if (!ptr->Header) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (ptr->extl) return GF_OK;

	e = gf_isom_check_sample_desc(ptr);
	if (e) return e;

	if (!ptr->Media) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!ptr->Media->information || !ptr->Media->information->sampleTable) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid MediaBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	if (!ptr->Media->information->sampleTable->SampleSize || (ptr->Media->information->sampleTable->SampleSize->sampleCount==0)) {
		if (ptr->Header->initial_duration) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Track with no samples but duration defined, ignoring duration\n"));
			ptr->Header->initial_duration = 0;
		}
	}

	for (i=0; i<gf_list_count(ptr->Media->information->sampleTable->child_boxes); i++) {
		GF_Box *a = gf_list_get(ptr->Media->information->sampleTable->child_boxes, i);
		if ((a->type ==GF_ISOM_BOX_TYPE_UUID) && (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC)) {
			ptr->sample_encryption = (struct __sample_encryption_box *) a;
			break;
		}
		else if (a->type == GF_ISOM_BOX_TYPE_SENC) {
			ptr->sample_encryption = (struct __sample_encryption_box *)a;
			break;
		}
	}
	return e;
}

GF_Box *trak_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err trak_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err trak_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_TrackBox *ptr = (GF_TrackBox *)s;

	if (ptr->sample_encryption && ptr->sample_encryption->load_needed) {
		if (!ptr->moov || !ptr->moov->mov || !ptr->moov->mov->movieFileMap)
			return GF_ISOM_INVALID_FILE;
		GF_Err e = senc_Parse(ptr->moov->mov->movieFileMap->bs, ptr, NULL, ptr->sample_encryption, 0);
		if (e) return e;
	}
	gf_isom_check_position(s, (GF_Box *)ptr->extl, &pos);

	gf_isom_check_position(s, (GF_Box *)ptr->Header, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->Aperture, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->References, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->editBox, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->Media, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->meta, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->groups, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->udta, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void stri_box_del(GF_Box *s)
{
	GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
	if (ptr == NULL) return;
	if (ptr->attribute_list) gf_free(ptr->attribute_list);
	gf_free(ptr);
}

GF_Err stri_box_read(GF_Box *s, GF_BitStream *bs)
{
	size_t i;
	GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
	ISOM_DECREASE_SIZE(ptr, 8)
	ptr->switch_group = gf_bs_read_u16(bs);
	ptr->alternate_group = gf_bs_read_u16(bs);
	ptr->sub_track_id = gf_bs_read_u32(bs);
	ptr->attribute_count = ptr->size / 4;
	if ((u64)ptr->attribute_count > (u64)SIZE_MAX/sizeof(u32)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in stri\n", ptr->size));
		return GF_ISOM_INVALID_FILE;
	}
	GF_SAFE_ALLOC_N(ptr->attribute_list, (size_t)ptr->attribute_count, u32);
	if (!ptr->attribute_list) return GF_OUT_OF_MEM;
	for (i = 0; i < ptr->attribute_count; i++) {
		ISOM_DECREASE_SIZE(ptr, 4)
		ptr->attribute_list[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

GF_Box *stri_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SubTrackInformationBox, GF_ISOM_BOX_TYPE_STRI);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stri_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u16(bs, ptr->switch_group);
	gf_bs_write_u16(bs, ptr->alternate_group);
	gf_bs_write_u32(bs, ptr->sub_track_id);
	for (i = 0; i < ptr->attribute_count; i++) {
		gf_bs_write_u32(bs, ptr->attribute_list[i]);
	}
	return GF_OK;
}

GF_Err stri_box_size(GF_Box *s)
{
	GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;

	ptr->size += 8 + 4 * ptr->attribute_count;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void stsg_box_del(GF_Box *s)
{
	GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
	if (ptr == NULL) return;
	if (ptr->group_description_index) gf_free(ptr->group_description_index);
	gf_free(ptr);
}

GF_Err stsg_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
	ISOM_DECREASE_SIZE(s, 6);
	ptr->grouping_type = gf_bs_read_u32(bs);
	ptr->nb_groups = gf_bs_read_u16(bs);
	ISOM_DECREASE_SIZE(s, ptr->nb_groups*4);
	GF_SAFE_ALLOC_N(ptr->group_description_index, ptr->nb_groups, u32);
	if (!ptr->group_description_index) return GF_OUT_OF_MEM;
	for (i = 0; i < ptr->nb_groups; i++) {
		ptr->group_description_index[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

GF_Box *stsg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SubTrackSampleGroupBox, GF_ISOM_BOX_TYPE_STSG);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stsg_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->grouping_type);
	gf_bs_write_u16(bs, ptr->nb_groups);
	for (i = 0; i < ptr->nb_groups; i++) {
		gf_bs_write_u32(bs, ptr->group_description_index[i]);
	}
	return GF_OK;
}

GF_Err stsg_box_size(GF_Box *s)
{
	GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
	ptr->size += 6 + 4 * ptr->nb_groups;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void strk_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err strk_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
	if (!a) return GF_OK;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_STRI:
		BOX_FIELD_ASSIGN(info, GF_SubTrackInformationBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_STRD:
		BOX_FIELD_ASSIGN(strd, GF_Box)
		return GF_OK;
	}
	return GF_OK;
}


GF_Err strk_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
	e = gf_isom_box_array_read(s, bs);
	if (e) return e;

	if (!ptr->info) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing SubTrackInformationBox\n"));
		return GF_ISOM_INVALID_FILE;
	}
	return GF_OK;
}

GF_Box *strk_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SubTrackBox, GF_ISOM_BOX_TYPE_STRK);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err strk_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err strk_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void tref_box_del(GF_Box *s)
{
	GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err tref_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *tref_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tref_box_write(GF_Box *s, GF_BitStream *bs)
{
//	GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
	return gf_isom_box_write_header(s, bs);
}

GF_Err tref_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void reftype_box_del(GF_Box *s)
{
	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
	if (!ptr) return;
	if (ptr->trackIDs) gf_free(ptr->trackIDs);
	gf_free(ptr);
}


GF_Err reftype_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 bytesToRead;
	u32 i;
	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;

	bytesToRead = (u32) (ptr->size);
	if (!bytesToRead) return GF_OK;

	ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32);
	ptr->trackIDs = (GF_ISOTrackID *) gf_malloc(ptr->trackIDCount * sizeof(GF_ISOTrackID));
	if (!ptr->trackIDs) return GF_OUT_OF_MEM;

	for (i = 0; i < ptr->trackIDCount; i++) {
		ptr->trackIDs[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

GF_Box *reftype_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
	return (GF_Box *)tmp;
}


GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, GF_ISOTrackID trackID, u16 *outRefIndex)
{
	u32 i;
	if (!ref || !trackID) return GF_BAD_PARAM;

	if (outRefIndex) *outRefIndex = 0;
	//don't add a dep if already here !!
	for (i = 0; i < ref->trackIDCount; i++) {
		if (ref->trackIDs[i] == trackID) {
			if (outRefIndex) *outRefIndex = i+1;
			return GF_OK;
		}
	}

	ref->trackIDs = (GF_ISOTrackID *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(GF_ISOTrackID) );
	if (!ref->trackIDs) return GF_OUT_OF_MEM;
	ref->trackIDs[ref->trackIDCount] = trackID;
	ref->trackIDCount++;
	if (outRefIndex) *outRefIndex = ref->trackIDCount;
	return GF_OK;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err reftype_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
	if (ptr->reference_type == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	ptr->type = ptr->reference_type;
	e = gf_isom_box_write_header(s, bs);
	ptr->type = GF_ISOM_BOX_TYPE_REFT;
	if (e) return e;
	for (i = 0; i < ptr->trackIDCount; i++) {
		gf_bs_write_u32(bs, ptr->trackIDs[i]);
	}
	return GF_OK;
}


GF_Err reftype_box_size(GF_Box *s)
{
	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
	if (ptr->trackIDCount)
		ptr->size += (ptr->trackIDCount * sizeof(u32));
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void trex_box_del(GF_Box *s)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err trex_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;

	ISOM_DECREASE_SIZE(ptr, 20);
	ptr->trackID = gf_bs_read_u32(bs);
	ptr->def_sample_desc_index = gf_bs_read_u32(bs);
	ptr->def_sample_duration = gf_bs_read_u32(bs);
	ptr->def_sample_size = gf_bs_read_u32(bs);
	ptr->def_sample_flags = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *trex_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err trex_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->trackID);
	//we always write 1 in trex default sample desc as using 0 breaks chrome/opera/...
	gf_bs_write_u32(bs, ptr->def_sample_desc_index ? ptr->def_sample_desc_index : 1);
	gf_bs_write_u32(bs, ptr->def_sample_duration);
	gf_bs_write_u32(bs, ptr->def_sample_size);
	gf_bs_write_u32(bs, ptr->def_sample_flags);
	return GF_OK;
}

GF_Err trex_box_size(GF_Box *s)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
	ptr->size += 20;
	return GF_OK;
}



#endif /*GPAC_DISABLE_ISOM_WRITE*/



void trep_box_del(GF_Box *s)
{
	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err trep_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->trackID = gf_bs_read_u32(bs);

	return gf_isom_box_array_read(s, bs);
}

GF_Box *trep_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP);
	tmp->child_boxes = gf_list_new();
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err trep_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->trackID);
	return GF_OK;
}

GF_Err trep_box_size(GF_Box *s)
{
	GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
	ptr->size += 4;
	return GF_OK;
}



#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/



#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS

void trun_box_del(GF_Box *s)
{
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
	if (ptr == NULL) return;

	if (ptr->samples) gf_free(ptr->samples);
	if (ptr->cache) gf_bs_del(ptr->cache);
	if (ptr->sample_order) gf_free(ptr->sample_order);
	if (ptr->sample_refs) {
		while (gf_list_count(ptr->sample_refs)) {
			GF_TrafSampleRef *sref = gf_list_pop_back(ptr->sample_refs);
			if (!sref->ref) gf_free(sref->data);
			gf_free(sref);
		}
		gf_list_del(ptr->sample_refs);
	}
	gf_free(ptr);
}

#ifdef GF_ENABLE_CTRN

static u32 ctrn_field_size(u32 field_idx)
{
	if (field_idx==3) return 4;
	return field_idx;
}

u32 gf_isom_ctrn_field_size_bits(u32 field_idx)
{
	if (field_idx==3) return 32;
	return field_idx*8;
}
static u32 ctrn_read_flags(GF_BitStream *bs, u32 nbbits)
{
	u32 val = gf_bs_read_int(bs, nbbits);
	if (nbbits==16) val <<= 16;
	else if (nbbits==8) val <<= 24;
	return val;
}

static GF_Err ctrn_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, count, flags, first_idx=0;
	Bool inherit_dur, inherit_size, inherit_flags, inherit_ctso;
	GF_TrunEntry *ent;
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
	flags = ptr->flags;
	ptr->ctrn_flags = flags;
	ptr->flags = 0;

	ptr->sample_count = gf_bs_read_u16(bs);
	ISOM_DECREASE_SIZE(ptr, 2);

	if (flags & GF_ISOM_TRUN_DATA_OFFSET) {
		if (flags & GF_ISOM_CTRN_DATAOFFSET_16) {
			ptr->data_offset = gf_bs_read_u16(bs);
			ISOM_DECREASE_SIZE(ptr, 2);
		} else {
			ptr->data_offset = gf_bs_read_u32(bs);
			ISOM_DECREASE_SIZE(ptr, 4);
		}
		ptr->flags |= GF_ISOM_TRUN_DATA_OFFSET;
	}
	if (flags & GF_ISOM_CTRN_CTSO_MULTIPLIER) {
		ptr->ctso_multiplier = gf_bs_read_u16(bs);
		ISOM_DECREASE_SIZE(ptr, 2);
	}
	/*no sample dur/sample_flag/size/ctso for first or following, create a pack sample */
	if (! (flags & 0x00FFFF00)) {
		GF_SAFEALLOC(ent, GF_TrunEntry);
		if (!ent) return GF_OUT_OF_MEM;
		ent->nb_pack = ptr->sample_count;
		gf_list_add(ptr->entries, ent);
		return GF_OK;
	}
	/*allocate all entries*/
	for (i=0; i<ptr->sample_count; i++) {
		GF_SAFEALLOC(ent, GF_TrunEntry);
		if (!ent) return GF_OUT_OF_MEM;
		gf_list_add(ptr->entries, ent);
	}
	//unpack flags
	ptr->ctrn_first_dur = (flags>>22) & 0x3;
	ptr->ctrn_first_size = (flags>>20) & 0x3;
	ptr->ctrn_first_sample_flags = (flags>>18) & 0x3;
	ptr->ctrn_first_ctts = (flags>>16) & 0x3;
	ptr->ctrn_dur = (flags>>14) & 0x3;
	ptr->ctrn_size = (flags>>12) & 0x3;
	ptr->ctrn_sample_flags = (flags>>10) & 0x3;
	ptr->ctrn_ctts = (flags>>8) & 0x3;

	inherit_dur = flags & GF_ISOM_CTRN_INHERIT_DUR;
	inherit_size = flags & GF_ISOM_CTRN_INHERIT_SIZE;
	inherit_flags = flags & GF_ISOM_CTRN_INHERIT_FLAGS;
	inherit_ctso = flags & GF_ISOM_CTRN_INHERIT_CTSO;

	if (flags & GF_ISOM_CTRN_FIRST_SAMPLE) {
		ent = gf_list_get(ptr->entries, 0);
		first_idx = 1;
		if (!inherit_dur && ptr->ctrn_first_dur) {
			ent->Duration = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_dur) );
			ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_dur) );
		}
		if (!inherit_size && ptr->ctrn_first_size) {
			ent->size = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_size) );
			ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_size) );
		}
		if (!inherit_flags && ptr->ctrn_first_sample_flags) {
			ent->flags = ctrn_read_flags(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_sample_flags) );
			ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_sample_flags) );
		}
		if (!inherit_ctso && ptr->ctrn_first_ctts) {
			ent->CTS_Offset = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_ctts) );
			ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_ctts) );
			if (ptr->ctso_multiplier)
				ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
		}
	}
	count = ptr->sample_count - first_idx;
	if (!inherit_dur && ptr->ctrn_dur) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_dur);
		ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
		for (i=first_idx; i<ptr->sample_count; i++) {
			ent = gf_list_get(ptr->entries, i);
			ent->Duration = gf_bs_read_int(bs, nbbits);
		}
	}
	if (!inherit_size && ptr->ctrn_size) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_size);
		ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
		for (i=first_idx; i<ptr->sample_count; i++) {
			ent = gf_list_get(ptr->entries, i);
			ent->size = gf_bs_read_int(bs, nbbits);
		}
	}
	if (!inherit_flags && ptr->ctrn_sample_flags) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_sample_flags);
		ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
		for (i=first_idx; i<ptr->sample_count; i++) {
			ent = gf_list_get(ptr->entries, i);
			ent->flags = ctrn_read_flags(bs, nbbits);
		}
	}
	if (!inherit_ctso && ptr->ctrn_ctts) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_ctts);
		ISOM_DECREASE_SIZE(ptr, count * nbbits / 8);
		for (i=first_idx; i<ptr->sample_count; i++) {
			ent = gf_list_get(ptr->entries, i);
			ent->CTS_Offset = gf_bs_read_int(bs, nbbits);
			if (ptr->ctso_multiplier)
				ent->CTS_Offset *= (s32) ptr->ctso_multiplier;
		}
	}

	return GF_OK;
}
#endif

GF_Err trun_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;

#ifdef GF_ENABLE_CTRN
	if (ptr->type == GF_ISOM_BOX_TYPE_CTRN) {
		ptr->type = GF_ISOM_BOX_TYPE_TRUN;
		ptr->use_ctrn = GF_TRUE;
		return ctrn_box_read(s, bs);
	}
#endif

	//check this is a good file
	if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS))
		return GF_ISOM_INVALID_FILE;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->sample_count = gf_bs_read_u32(bs);

	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->data_offset = gf_bs_read_u32(bs);
	}
	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->first_sample_flags = gf_bs_read_u32(bs);
	}
	if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
		ptr->samples = gf_malloc(sizeof(GF_TrunEntry));
		if (!ptr->samples) return GF_OUT_OF_MEM;
		//memset to 0 !!
		memset(ptr->samples, 0, sizeof(GF_TrunEntry));
		ptr->sample_alloc = ptr->nb_samples = 1;
		ptr->samples[0].nb_pack = ptr->sample_count;
	} else {
		u32 base_size=0;
		//check size
		if (ptr->flags & GF_ISOM_TRUN_DURATION) base_size+=4;
		if (ptr->flags & GF_ISOM_TRUN_SIZE) base_size+=4;
		if (ptr->flags & GF_ISOM_TRUN_FLAGS) base_size+=4;
		if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) base_size+=4;

		if ((u64) ptr->sample_count * base_size > ptr->size) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of samples %u in trun for box size %u\n", ptr->sample_count, ptr->size));
			return GF_ISOM_INVALID_FILE;
		}
		if ((u64)ptr->sample_count > (u64)SIZE_MAX/sizeof(GF_TrunEntry)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of samples %u in trun\n", ptr->sample_count));
			return GF_ISOM_INVALID_FILE;
		}
		ptr->samples = gf_malloc(sizeof(GF_TrunEntry) * ptr->sample_count);
		if (!ptr->samples) return GF_OUT_OF_MEM;
		ptr->sample_alloc = ptr->nb_samples = ptr->sample_count;
		//memset to 0 upfront
		memset(ptr->samples, 0, ptr->sample_count * sizeof(GF_TrunEntry));

		//read each entry (even though nothing may be written)
		for (i=0; i<ptr->sample_count; i++) {
			u32 trun_size = 0;
			GF_TrunEntry *p = &ptr->samples[i];

			if (ptr->flags & GF_ISOM_TRUN_DURATION) {
				p->Duration = gf_bs_read_u32(bs);
				trun_size += 4;

				if (!ptr->min_duration || (ptr->min_duration>p->Duration))
					ptr->min_duration = p->Duration;
			}
			if (ptr->flags & GF_ISOM_TRUN_SIZE) {
				p->size = gf_bs_read_u32(bs);
				trun_size += 4;
			}
			//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
			if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
				p->flags = gf_bs_read_u32(bs);
				trun_size += 4;
			}
			if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
				if (ptr->version==0) {
					p->CTS_Offset = (u32) gf_bs_read_u32(bs);
				} else {
					p->CTS_Offset = (s32) gf_bs_read_u32(bs);
				}
				trun_size += 4;
			}
			ISOM_DECREASE_SIZE(ptr, trun_size);
		}
	}
	/*todo parse sample reorder*/
	if (ptr->size) {
		gf_bs_skip_bytes(bs, ptr->size);
		ptr->size = 0;
	}
	return GF_OK;
}

GF_Box *trun_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
	//NO FLAGS SET BY DEFAULT
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

#ifdef GF_ENABLE_CTRN
static void ctrn_write_sample_flags(GF_BitStream *bs, u32 flags, u32 field_size)
{
	if (!field_size) return;

	if (field_size==8) flags = flags>>24;
	else if (field_size==16) flags = flags>>16;
	gf_bs_write_int(bs, flags, field_size);
}


static void ctrn_write_ctso(GF_TrackFragmentRunBox *ctrn, GF_BitStream *bs, u32 ctso, u32 field_size)
{
	if (!field_size) return;

	if (ctrn->ctso_multiplier) {
		gf_bs_write_int(bs, ctso / ctrn->ctso_multiplier, field_size);
	} else {
		gf_bs_write_int(bs, ctso, field_size);
	}
}

GF_Err ctrn_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, count, flags;
	GF_TrunEntry *ent;
	GF_TrackFragmentRunBox *ctrn = (GF_TrackFragmentRunBox *) s;
	if (!s) return GF_BAD_PARAM;
	flags = ctrn->flags;
	ctrn->flags = ctrn->ctrn_flags;
	ctrn->type = GF_ISOM_BOX_TYPE_CTRN;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	ctrn->flags = flags;
	ctrn->type = GF_ISOM_BOX_TYPE_TRUN;

	gf_bs_write_u16(bs, ctrn->sample_count);
	if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
		if (ctrn->ctrn_flags & GF_ISOM_CTRN_DATAOFFSET_16) {
			gf_bs_write_u16(bs, ctrn->data_offset);
		} else {
			gf_bs_write_u32(bs, ctrn->data_offset);
		}
	}
	if (ctrn->ctso_multiplier) {
		gf_bs_write_u16(bs, ctrn->ctso_multiplier);
	}
	/*we always write first sample using first flags*/
	ent = gf_list_get(ctrn->entries, 0);
	gf_bs_write_int(bs, ent->Duration, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_dur) );
	gf_bs_write_int(bs, ent->size, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_size) );
	ctrn_write_sample_flags(bs, ent->flags, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_sample_flags) );
	ctrn_write_ctso(ctrn,bs, ent->CTS_Offset, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_ctts) );

	count = gf_list_count(ctrn->entries);
	if (ctrn->ctrn_dur) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_dur);
		for (i=1; i<count; i++) {
			GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
			gf_bs_write_int(bs, a_ent->Duration, nbbits);
		}
	}
	if (ctrn->ctrn_size) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_size);
		for (i=1; i<count; i++) {
			GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
			gf_bs_write_int(bs, a_ent->size, nbbits);
		}
	}
	if (ctrn->ctrn_sample_flags) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_sample_flags);
		for (i=1; i<count; i++) {
			GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
			ctrn_write_sample_flags(bs, a_ent->flags, nbbits);
		}
	}
	if (ctrn->ctrn_ctts) {
		u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_ctts);
		for (i=1; i<count; i++) {
			GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
			ctrn_write_ctso(ctrn, bs, a_ent->CTS_Offset, nbbits);
		}
	}

	return GF_OK;
}
#endif

GF_Err trun_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *) s;
	if (!s) return GF_BAD_PARAM;

#ifdef GF_ENABLE_CTRN
	if (ptr->use_ctrn)
		return ctrn_box_write(s, bs);
#endif

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->sample_count);

	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
		gf_bs_write_u32(bs, ptr->data_offset);
	}
	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
		gf_bs_write_u32(bs, ptr->first_sample_flags);
	}

	if (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) )  {
		for (i=0; i<ptr->nb_samples; i++) {
			GF_TrunEntry *p = &ptr->samples[i];

			if (ptr->flags & GF_ISOM_TRUN_DURATION) {
				gf_bs_write_u32(bs, p->Duration);
			}
			if (ptr->flags & GF_ISOM_TRUN_SIZE) {
				gf_bs_write_u32(bs, p->size);
			}
			//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
			if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
				gf_bs_write_u32(bs, p->flags);
			}
			if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
				if (ptr->version==0) {
					gf_bs_write_u32(bs, p->CTS_Offset);
				} else {
					gf_bs_write_u32(bs, (u32) p->CTS_Offset);
				}
			}
		}
	}

	if (ptr->sample_order) {
		u32 nb_bits = 8;
		if (ptr->sample_count>0xFFFFFF) nb_bits = 32;
		else if (ptr->sample_count>0xFFFF) nb_bits = 24;
		else if (ptr->sample_count>0xFF) nb_bits = 16;

		for (i=0; i<ptr->sample_count; i++) {
			gf_bs_write_int(bs, ptr->sample_order[i], nb_bits);
		}
	}
	return GF_OK;
}

#ifdef GF_ENABLE_CTRN
static u32 ctrn_sample_flags_to_index(u32 val)
{
	if (!val) return 0;
	if (val & 0x0000FFFF)
		return 3;
	if (val & 0x00FF0000)
		return 2;
	return 1;
}
static u32 ctrn_u32_to_index(u32 val)
{
	if (!val) return 0;
	if (val<=255) return 1;
	if (val<=65535) return 2;
	return 3;
}
static u32 ctrn_s32_to_index(s32 val)
{
	if (!val) return 0;
	if (ABS(val)<=127) return 1;
	if (ABS(val)<=32767) return 2;
	return 3;
}
static u32 ctrn_ctts_to_index(GF_TrackFragmentRunBox *ctrn, s32 ctts)
{
	if (!(ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET))
		return 0;

	if (!ctts) return 0;

	if (ctrn->version) {
		if (ctrn->ctso_multiplier) return ctrn_s32_to_index(ctts / ctrn->ctso_multiplier);
		return ctrn_s32_to_index(ctts);
	}
	gf_assert(ctts>0);
	if (ctrn->ctso_multiplier) return ctrn_u32_to_index((u32)ctts / ctrn->ctso_multiplier);
	return ctrn_s32_to_index((u32)ctts);
}

static GF_Err ctrn_box_size(GF_TrackFragmentRunBox *ctrn)
{
	Bool use_ctso_multi = GF_TRUE;
	u32 i, count;
	GF_TrunEntry *ent;

	ctrn->ctrn_flags = 0;
	ctrn->ctrn_first_dur = ctrn->ctrn_first_size = ctrn->ctrn_first_sample_flags = ctrn->ctrn_first_ctts = 0;
	ctrn->ctrn_dur = ctrn->ctrn_size = ctrn->ctrn_sample_flags = ctrn->ctrn_ctts = 0;

	ctrn->size += 2; //16 bits for sample count
	if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) {
		ctrn->ctrn_flags |= GF_ISOM_TRUN_DATA_OFFSET;
		if (ABS(ctrn->data_offset) < 32767) {
			ctrn->size += 2;
			ctrn->ctrn_flags |= GF_ISOM_CTRN_DATAOFFSET_16;
		} else
			ctrn->size += 4;
	}

	count = gf_list_count(ctrn->entries);
	if (ctrn->ctso_multiplier && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET) && (ctrn->ctso_multiplier<=0xFFFF) ) {
		for (i=0; i<count; i++) {
			GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);
			if (a_ent->CTS_Offset % ctrn->ctso_multiplier) {
				use_ctso_multi = GF_FALSE;
				break;
			}
		}
	} else {
		use_ctso_multi = GF_FALSE;
	}
	if (ctrn->use_inherit) {
		use_ctso_multi = GF_FALSE;
		ctrn->ctrn_flags |= 0xB0; //duration=1,size=0,flags=1,cts=1 << 4
	}

	if (use_ctso_multi) {
		ctrn->size += 2;
		ctrn->ctrn_flags |= GF_ISOM_CTRN_CTSO_MULTIPLIER;
	} else {
		ctrn->ctso_multiplier = 0;
	}

	/*we always write first sample using first flags*/
	ent = gf_list_get(ctrn->entries, 0);
	ctrn->ctrn_flags |= GF_ISOM_CTRN_FIRST_SAMPLE;

	if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
		ctrn->ctrn_first_dur = ctrn_u32_to_index(ent->Duration);
		if (ctrn->ctrn_first_dur) {
			ctrn->size += ctrn_field_size(ctrn->ctrn_first_dur);
			ctrn->ctrn_flags |= ctrn->ctrn_first_dur<<22;
		}
	}

	if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
		ctrn->ctrn_first_size = ctrn_u32_to_index(ent->size);
		if (ctrn->ctrn_first_size) {
			ctrn->size += ctrn_field_size(ctrn->ctrn_first_size);
			ctrn->ctrn_flags |= ctrn->ctrn_first_size<<20;
		}
	}

	if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
		ctrn->ctrn_first_sample_flags = ctrn_sample_flags_to_index(ent->flags);
		if (ctrn->ctrn_first_sample_flags) {
			ctrn->size += ctrn_field_size(ctrn->ctrn_first_sample_flags);
			ctrn->ctrn_flags |= ctrn->ctrn_first_sample_flags<<18;
		}
	}
	if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET)) {
		ctrn->ctrn_first_ctts = ctrn_ctts_to_index(ctrn, ent->CTS_Offset);
		if (ctrn->ctrn_first_ctts) {
			ctrn->size += ctrn_field_size(ctrn->ctrn_first_ctts);
			ctrn->ctrn_flags |= ctrn->ctrn_first_ctts<<16;
		}
	}

	for (i=1; i<count; i++) {
		u8 field_idx;
		GF_TrunEntry *a_ent = gf_list_get(ctrn->entries, i);

		if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) {
			field_idx = ctrn_u32_to_index(a_ent->Duration);
			if (ctrn->ctrn_dur < field_idx)
				ctrn->ctrn_dur = field_idx;
		}
		if (ctrn->flags & GF_ISOM_TRUN_SIZE) {
			field_idx = ctrn_u32_to_index(a_ent->size);
			if (ctrn->ctrn_size < field_idx)
				ctrn->ctrn_size = field_idx;
		}
		if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) {
			field_idx = ctrn_sample_flags_to_index(a_ent->flags);
			if (ctrn->ctrn_sample_flags < field_idx)
				ctrn->ctrn_sample_flags = field_idx;
		}
		if (!ctrn->use_inherit) {
			field_idx = ctrn_ctts_to_index(ctrn, a_ent->CTS_Offset);
			if (ctrn->ctrn_ctts < field_idx)
				ctrn->ctrn_ctts = field_idx;
		}
	}
	count-=1;
	if (ctrn->ctrn_dur) {
		ctrn->size += count * ctrn_field_size(ctrn->ctrn_dur);
		ctrn->ctrn_flags |= ctrn->ctrn_dur<<14;
	}
	if (ctrn->ctrn_size) {
		ctrn->size += count * ctrn_field_size(ctrn->ctrn_size);
		ctrn->ctrn_flags |= ctrn->ctrn_size<<12;
	}
	if (ctrn->ctrn_sample_flags) {
		ctrn->size += count * ctrn_field_size(ctrn->ctrn_sample_flags);
		ctrn->ctrn_flags |= ctrn->ctrn_sample_flags<<10;
	}
	if (ctrn->ctrn_ctts) {
		ctrn->size += count * ctrn_field_size(ctrn->ctrn_ctts);
		ctrn->ctrn_flags |= ctrn->ctrn_ctts<<8;
	}
	return GF_OK;
}
#endif

GF_Err trun_box_size(GF_Box *s)
{
	GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;

#ifdef GF_ENABLE_CTRN
	if (ptr->use_ctrn)
		return ctrn_box_size(ptr);
#endif

	ptr->size += 4;
	//The rest depends on the flags
	if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
	if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;

	if (ptr->sample_order) {
		u32 nb_bytes = 1;
		if (ptr->sample_count>0xFFFFFF) nb_bytes = 4;
		else if (ptr->sample_count>0xFFFF) nb_bytes = 3;
		else if (ptr->sample_count>0xFF) nb_bytes = 2;
		ptr->size += ptr->sample_count*nb_bytes;
	}

	if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) {
		return GF_OK;
	}

	//if nothing to do, this will be skipped automatically
	if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4*ptr->nb_samples;
	if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4*ptr->nb_samples;
	//SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED
	if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4*ptr->nb_samples;
	if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4*ptr->nb_samples;

	return GF_OK;
}



#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


void tsro_box_del(GF_Box *s)
{
	GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s;
	gf_free(tsro);
}

GF_Err tsro_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->TimeOffset = gf_bs_read_u32(bs);
	return GF_OK;
}

GF_Box *tsro_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tsro_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->TimeOffset);
	return GF_OK;
}

GF_Err tsro_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void udta_box_del(GF_Box *s)
{
	u32 i;
	GF_UserDataMap *map;
	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
	if (ptr == NULL) return;
	i=0;
	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
		gf_isom_box_array_del(map->boxes);
		gf_free(map);
	}
	gf_list_del(ptr->recordList);
	gf_free(ptr);
}

GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid)
{
	u32 i;
	GF_UserDataMap *map;
	if (ptr == NULL) return NULL;
	i=0;
	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
		if (map->boxType == box_type) {
			if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map;
			if (!memcmp(map->uuid, *uuid, 16)) return map;
		}
	}
	return NULL;
}

GF_Err udta_on_child_box_ex(GF_Box *s, GF_Box *a, Bool is_rem, Bool rem_same_type)
{
	GF_Err e;
	u32 box_type;
	GF_UserDataMap *map;
	GF_UserDataBox *ptr = (GF_UserDataBox *)s;
	if (!ptr) return GF_BAD_PARAM;
	if (!a) return GF_OK;

	//detach from parent list if any
	gf_list_del_item(ptr->child_boxes, a);

	/* for unknown udta boxes, we reference them by their original box type */
	box_type = a->type;
	if (box_type == GF_ISOM_BOX_TYPE_UNKNOWN) {
		GF_UnknownBox* unkn = (GF_UnknownBox *)a;
		box_type = unkn->original_4cc;
	}

	map = udta_getEntry(ptr, box_type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL);
	if (map == NULL) {
		if (is_rem) return GF_OK;

		map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap));
		if (map == NULL) return GF_OUT_OF_MEM;
		memset(map, 0, sizeof(GF_UserDataMap));

		map->boxType = box_type;
		if (a->type == GF_ISOM_BOX_TYPE_UUID)
			memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
		map->boxes = gf_list_new();
		if (!map->boxes) {
			gf_free(map);
			return GF_OUT_OF_MEM;
		}
		e = gf_list_add(ptr->recordList, map);
		if (e) return e;
	}
	if (is_rem) {
		gf_list_del_item(map->boxes, a);
		return GF_OK;
	}

	if (rem_same_type) {
		u32 i, count = gf_list_count(map->boxes);
		for (i=0; i<count; i++) {
			GF_Box *b = gf_list_get(map->boxes, i);
			u32 btype = b->type;
			if (b->type==GF_ISOM_BOX_TYPE_UNKNOWN) btype = ((GF_UnknownBox*)b)->original_4cc;
			if (btype != box_type) continue;
			if (box_type == GF_ISOM_BOX_TYPE_UUID) {
				if (memcmp( ((GF_UUIDBox *)a)->uuid, ((GF_UUIDBox *)b)->uuid, 16)) continue;
			}
			gf_isom_box_del(b);
			gf_list_rem(map->boxes, i);
			break;
		}
	}

	return gf_list_add(map->boxes, a);
}
GF_Err udta_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	return udta_on_child_box_ex(s, a, is_rem, GF_FALSE);
}

GF_Err udta_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e = gf_isom_box_array_read(s, bs);
	if (e) return e;
	if (s->size==4) {
		u32 val = gf_bs_read_u32(bs);
		s->size = 0;
		if (val) {
			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));
		}
	}
	return GF_OK;
}

GF_Box *udta_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
	tmp->recordList = gf_list_new();
	if (!tmp->recordList) {
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err udta_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_UserDataMap *map;
	GF_UserDataBox *ptr = (GF_UserDataBox *)s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	i=0;
	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
		//warning: here we are not passing the actual "parent" of the list
		//but the UDTA box. The parent itself is not an box, we don't care about it
		e = gf_isom_box_array_write(s, map->boxes, bs);
		if (e) return e;
	}
	return GF_OK;
}

GF_Err udta_box_size(GF_Box *s)
{
	GF_Err e;
	u32 i;
	GF_UserDataMap *map;
	GF_UserDataBox *ptr = (GF_UserDataBox *)s;

	i=0;
	while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
		//warning: here we are not passing the actual "parent" of the list
		//but the UDTA box. The parent itself is not an box, we don't care about it
		e = gf_isom_box_array_size(s, map->boxes);
		if (e) return e;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void vmhd_box_del(GF_Box *s)
{
	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err vmhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->reserved = gf_bs_read_u64(bs);
	return GF_OK;
}

GF_Box *vmhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
	tmp->flags = 1;
	return (GF_Box *)tmp;
}



#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err vmhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u64(bs, ptr->reserved);
	return GF_OK;
}

GF_Err vmhd_box_size(GF_Box *s)
{
	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
	ptr->size += 8;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void void_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err void_box_read(GF_Box *s, GF_BitStream *bs)
{
	if (s->size) return GF_ISOM_INVALID_FILE;
	return GF_OK;
}

GF_Box *void_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
	return tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err void_box_write(GF_Box *s, GF_BitStream *bs)
{
	gf_bs_write_u32(bs, 0);
	return GF_OK;
}

GF_Err void_box_size(GF_Box *s)
{
	s->size = 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *pdin_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
	return (GF_Box *)tmp;
}


void pdin_box_del(GF_Box *s)
{
	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
	if (ptr == NULL) return;
	if (ptr->rates) gf_free(ptr->rates);
	if (ptr->times) gf_free(ptr->times);
	gf_free(ptr);
}


GF_Err pdin_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;

	ptr->count = (u32) (ptr->size) / 8;
	ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count);
	if (!ptr->rates) return GF_OUT_OF_MEM;
	ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count);
	if (!ptr->times) return GF_OUT_OF_MEM;
	for (i=0; i<ptr->count; i++) {
		ptr->rates[i] = gf_bs_read_u32(bs);
		ptr->times[i] = gf_bs_read_u32(bs);
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err pdin_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	for (i=0; i<ptr->count; i++) {
		gf_bs_write_u32(bs, ptr->rates[i]);
		gf_bs_write_u32(bs, ptr->times[i]);
	}
	return GF_OK;
}

GF_Err pdin_box_size(GF_Box *s)
{
	GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
	ptr->size += 8*ptr->count;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/




GF_Box *sdtp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
	return (GF_Box *)tmp;
}


void sdtp_box_del(GF_Box *s)
{
	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
	if (ptr == NULL) return;
	if (ptr->sample_info) gf_free(ptr->sample_info);
	gf_free(ptr);
}


GF_Err sdtp_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;

	/*out-of-order sdtp, assume no padding at the end*/
	if (!ptr->sampleCount) ptr->sampleCount = (u32) ptr->size;
	else if (ptr->sampleCount > (u32) ptr->size) return GF_ISOM_INVALID_FILE;

	ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount);
	if (!ptr->sample_info) return GF_OUT_OF_MEM;
	ptr->sample_alloc = ptr->sampleCount;
	gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
	ISOM_DECREASE_SIZE(ptr, ptr->sampleCount);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err sdtp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
	return GF_OK;
}

GF_Err sdtp_box_size(GF_Box *s)
{
	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
	ptr->size += ptr->sampleCount;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *pasp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
	return (GF_Box *)tmp;
}


void pasp_box_del(GF_Box *s)
{
	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err pasp_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->hSpacing = gf_bs_read_u32(bs);
	ptr->vSpacing = gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err pasp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->hSpacing);
	gf_bs_write_u32(bs, ptr->vSpacing);
	return GF_OK;
}

GF_Err pasp_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *clap_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP);
	return (GF_Box *)tmp;
}


void clap_box_del(GF_Box *s)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err clap_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s;
	ISOM_DECREASE_SIZE(ptr, 32);
	ptr->cleanApertureWidthN = gf_bs_read_u32(bs);
	ptr->cleanApertureWidthD = gf_bs_read_u32(bs);
	ptr->cleanApertureHeightN = gf_bs_read_u32(bs);
	ptr->cleanApertureHeightD = gf_bs_read_u32(bs);
	ptr->horizOffN = (s32) gf_bs_read_u32(bs);
	ptr->horizOffD = gf_bs_read_u32(bs);
	ptr->vertOffN = (s32) gf_bs_read_u32(bs);
	ptr->vertOffD = gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err clap_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_CleanApertureBox *ptr = (GF_CleanApertureBox *)s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->cleanApertureWidthN);
	gf_bs_write_u32(bs, ptr->cleanApertureWidthD);
	gf_bs_write_u32(bs, ptr->cleanApertureHeightN);
	gf_bs_write_u32(bs, ptr->cleanApertureHeightD);
	gf_bs_write_u32(bs, (u32) ptr->horizOffN);
	gf_bs_write_u32(bs, ptr->horizOffD);
	gf_bs_write_u32(bs, (u32) ptr->vertOffN);
	gf_bs_write_u32(bs, ptr->vertOffD);
	return GF_OK;
}

GF_Err clap_box_size(GF_Box *s)
{
	s->size += 32;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/




GF_Box *metx_box_new()
{
	//type is overridden by the box constructor
	ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, GF_ISOM_BOX_TYPE_METX);
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}


void metx_box_del(GF_Box *s)
{
	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);

	if (ptr->content_encoding) gf_free(ptr->content_encoding);
	if (ptr->xml_namespace) gf_free(ptr->xml_namespace);
	if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
	if (ptr->mime_type) gf_free(ptr->mime_type);
	gf_free(ptr);
}


GF_Err metx_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_TXTC:
		//we allow the config box on metx
		BOX_FIELD_ASSIGN(config, GF_TextConfigBox)
		break;
	}
	return GF_OK;
}

GF_Err metx_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 size, i;
	GF_Err e;
	char *str;
	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;

	e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
	if (e) return e;
	ISOM_DECREASE_SIZE(ptr, 8);

	if (ptr->size > (u64)SIZE_MAX) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size "LLU" in metx\n", ptr->size));
		return GF_ISOM_INVALID_FILE;
	}

	size = (u32) ptr->size;
	str = gf_malloc(sizeof(char)*size);
	if (!str) return GF_OUT_OF_MEM;
	i=0;

	while (size) {
		str[i] = gf_bs_read_u8(bs);
		size--;
		if (!str[i]) {
			i++;
			break;
		}
		i++;
	}
	if (!size && i>1 && str[i-1]) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
		gf_free(str);
		return GF_ISOM_INVALID_FILE;
	}
	if (i>1) {
		if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
			ptr->xml_namespace = gf_strdup(str);
		} else {
			ptr->content_encoding = gf_strdup(str);
		}
	}

	i=0;
	while (size) {
		str[i] = gf_bs_read_u8(bs);
		size--;
		if (!str[i]) {
			i++;
			break;
		}
		i++;
	}
	if (!size && i>1 && str[i-1]) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
		gf_free(str);
		return GF_ISOM_INVALID_FILE;
	}
	if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
		if (i>1) {
			if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
				ptr->xml_schema_loc = gf_strdup(str);
			} else {
				ptr->xml_namespace = gf_strdup(str);
			}
		}

		i=0;
		while (size) {
			str[i] = gf_bs_read_u8(bs);
			size--;
			if (!str[i]) {
				i++;
				break;
			}
			i++;
		}
		if (!size && i>1 && str[i-1]) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n"));
			gf_free(str);
			return GF_ISOM_INVALID_FILE;
		}
		if (i>1) {
			if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
				ptr->mime_type = gf_strdup(str);
			} else {
				ptr->xml_schema_loc = gf_strdup(str);
			}
		}
	}
	//mett, sbtt, stxt, stpp
	else {
		if (i>1) ptr->mime_type = gf_strdup(str);
	}
	ptr->size = size;
	gf_free(str);
	return gf_isom_box_array_read(s, bs);
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err metx_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_data(bs, ptr->reserved, 6);
	gf_bs_write_u16(bs, ptr->dataReferenceIndex);

	if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
		if (ptr->content_encoding)
			gf_bs_write_data(bs, ptr->content_encoding, (u32) strlen(ptr->content_encoding));
		gf_bs_write_u8(bs, 0);
	}

	if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
		if (ptr->xml_namespace)
			gf_bs_write_data(bs, ptr->xml_namespace, (u32) strlen(ptr->xml_namespace));

		gf_bs_write_u8(bs, 0);

		if (ptr->xml_schema_loc)
			gf_bs_write_data(bs, ptr->xml_schema_loc, (u32) strlen(ptr->xml_schema_loc));
		gf_bs_write_u8(bs, 0);

		if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
			if (ptr->mime_type)
				gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));

			gf_bs_write_u8(bs, 0);
		}
	}
	//mett, sbtt, stxt
	else {
		if (ptr->mime_type)
			gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));

		gf_bs_write_u8(bs, 0);
	}

	return GF_OK;
}

GF_Err metx_box_size(GF_Box *s)
{
	GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
	ptr->size += 8;

	if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
		if (ptr->content_encoding)
			ptr->size += strlen(ptr->content_encoding);
		ptr->size++;
	}

	if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {

		if (ptr->xml_namespace)
			ptr->size += strlen(ptr->xml_namespace);
		ptr->size++;

		if (ptr->xml_schema_loc)
			ptr->size += strlen(ptr->xml_schema_loc);
		ptr->size++;

		if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
			if (ptr->mime_type)
				ptr->size += strlen(ptr->mime_type);
			ptr->size++;
		}

	}
	//mett, sbtt, stxt
	else {
		if (ptr->mime_type)
			ptr->size += strlen(ptr->mime_type);
		ptr->size++;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


/* SimpleTextSampleEntry */
GF_Box *txtc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC);
	return (GF_Box *)tmp;
}


void txtc_box_del(GF_Box *s)
{
	GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
	if (ptr == NULL) return;

	if (ptr->config) gf_free(ptr->config);
	gf_free(ptr);
}

GF_Err txtc_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
	if ((u32)ptr->size >= (u32)0xFFFFFFFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in txtc box\n", ptr->size));
		return GF_ISOM_INVALID_FILE;
	}
	ptr->config = (char *)gf_malloc(sizeof(char)*((u32) ptr->size+1));
	if (!ptr->config) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->config, (u32) ptr->size);
	ptr->config[ptr->size] = 0;
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err txtc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
	GF_Err e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->config)
		gf_bs_write_data(bs, ptr->config, (u32) strlen(ptr->config));
	gf_bs_write_u8(bs, 0);
	return GF_OK;
}

GF_Err txtc_box_size(GF_Box *s)
{
	GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
	if (ptr->config)
		ptr->size += strlen(ptr->config);
	ptr->size++;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *dac3_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
	return (GF_Box *)tmp;
}

GF_Box *dec3_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
	tmp->cfg.is_ec3 = 1;
	return (GF_Box *)tmp;
}

void dac3_box_del(GF_Box *s)
{
	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
	gf_free(ptr);
}


GF_Err dac3_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos;
	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	pos = gf_bs_get_position(bs);
	e = gf_odf_ac3_cfg_parse_bs(bs, ptr->cfg.is_ec3, &ptr->cfg);
	if (e) return e;
	pos = gf_bs_get_position(bs) - pos;
	ISOM_DECREASE_SIZE(ptr, pos);

	if (ptr->size>=2) {
		ptr->size-=2;
		gf_bs_read_int(bs, 7);
		ptr->cfg.atmos_ec3_ext = gf_bs_read_int(bs, 1);
		ptr->cfg.complexity_index_type = gf_bs_read_u8(bs);
	}
	//the rest is reserved
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dac3_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;

	if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
	e = gf_isom_box_write_header(s, bs);
	if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
	if (e) return e;

	e = gf_odf_ac3_cfg_write_bs(&ptr->cfg, bs);
	if (e) return e;

	if (ptr->cfg.atmos_ec3_ext || ptr->cfg.complexity_index_type) {
		gf_bs_write_int(bs, 0, 7);
		gf_bs_write_int(bs, ptr->cfg.atmos_ec3_ext, 1);
		gf_bs_write_u8(bs, ptr->cfg.complexity_index_type);
	}
	return GF_OK;
}

GF_Err dac3_box_size(GF_Box *s)
{
	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;

	if (ptr->cfg.is_ec3) {
		u32 i;
		s->size += 2;
		for (i=0; i<ptr->cfg.nb_streams; i++) {
			s->size += 3;
			if (ptr->cfg.streams[i].nb_dep_sub)
				s->size += 1;
		}
	} else {
		s->size += 3;
	}
	if (ptr->cfg.atmos_ec3_ext || ptr->cfg.complexity_index_type) {
		s->size += 2;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *dac4_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AC4ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
	return (GF_Box *)tmp;
}

void dac4_box_del(GF_Box *s)
{
	GF_AC4ConfigBox *ptr = (GF_AC4ConfigBox *)s;
	gf_odf_ac4_cfg_clean_list(&ptr->cfg);
	gf_free(ptr);
}


GF_Err dac4_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos;
	GF_AC4ConfigBox *ptr = (GF_AC4ConfigBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;

	pos = gf_bs_get_position(bs);
	e = gf_odf_ac4_cfg_parse_bs(bs, &ptr->cfg);
	if (e) return e;

	pos = gf_bs_get_position(bs) - pos;
	ISOM_DECREASE_SIZE(ptr, pos);

	//the rest is reserved
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dac4_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AC4ConfigBox *ptr = (GF_AC4ConfigBox *)s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	e = gf_odf_ac4_cfg_write_bs(&ptr->cfg, bs);
	if (e) return e;

	return GF_OK;
}

GF_Err dac4_box_size(GF_Box *s)
{
	GF_AC4ConfigBox *ptr = (GF_AC4ConfigBox *)s;

	s->size += gf_odf_ac4_cfg_size(&ptr->cfg);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void lsrc_box_del(GF_Box *s)
{
	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
	if (ptr == NULL) return;
	if (ptr->hdr) gf_free(ptr->hdr);
	gf_free(ptr);
}


GF_Err lsrc_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
	ptr->hdr_size = (u32) ptr->size;
	ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size);
	if (!ptr->hdr) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size);
	return GF_OK;
}

GF_Box *lsrc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err lsrc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size);
	return GF_OK;
}

GF_Err lsrc_box_size(GF_Box *s)
{
	GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
	ptr->size += ptr->hdr_size;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void lsr1_box_del(GF_Box *s)
{
	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
	if (ptr == NULL) return;
	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
	if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
	gf_free(ptr);
}

GF_Err lsr1_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_LSRC:
		BOX_FIELD_ASSIGN(lsr_config, GF_LASERConfigurationBox)
		break;
	case GF_ISOM_BOX_TYPE_M4DS:
		BOX_FIELD_ASSIGN(descr, GF_MPEG4ExtensionDescriptorsBox)
		break;
	}
	return GF_OK;
}

GF_Err lsr1_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s;

	e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
	if (e) return e;

	ISOM_DECREASE_SIZE(ptr, 8);

	return gf_isom_box_array_read(s, bs);
}

GF_Box *lsr1_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
	gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err lsr1_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_data(bs, ptr->reserved, 6);
	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
	return GF_OK;
}

GF_Err lsr1_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
	s->size += 8;
	gf_isom_check_position(s, (GF_Box *)ptr->lsr_config, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void sidx_box_del(GF_Box *s)
{
	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s;
	if (ptr == NULL) return;
	if (ptr->refs) gf_free(ptr->refs);
	gf_free(ptr);
}

GF_Err sidx_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->reference_ID = gf_bs_read_u32(bs);
	ptr->timescale = gf_bs_read_u32(bs);

	if (ptr->version==0) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->earliest_presentation_time = gf_bs_read_u32(bs);
		ptr->first_offset = gf_bs_read_u32(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 16);
		ptr->earliest_presentation_time = gf_bs_read_u64(bs);
		ptr->first_offset = gf_bs_read_u64(bs);
	}
	ISOM_DECREASE_SIZE(ptr, 4);
	gf_bs_read_u16(bs); /* reserved */
	ptr->nb_refs = gf_bs_read_u16(bs);

	if ((u64)ptr->nb_refs > ptr->size / 12 || (u64)ptr->nb_refs > (u64)SIZE_MAX / sizeof(GF_SIDXReference)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of references %u in sidx\n", ptr->nb_refs));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs);
	if (!ptr->refs) return GF_OUT_OF_MEM;
	for (i=0; i<ptr->nb_refs; i++) {
		ptr->refs[i].reference_type = gf_bs_read_int(bs, 1);
		ptr->refs[i].reference_size = gf_bs_read_int(bs, 31);
		ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs);
		ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1);
		ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3);
		ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28);

		ISOM_DECREASE_SIZE(ptr, 12);
	}
	return GF_OK;
}

GF_Box *sidx_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err sidx_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->reference_ID);
	gf_bs_write_u32(bs, ptr->timescale);
	if (ptr->version==0) {
		gf_bs_write_u32(bs, (u32) ptr->earliest_presentation_time);
		gf_bs_write_u32(bs, (u32) ptr->first_offset);
	} else {
		gf_bs_write_u64(bs, ptr->earliest_presentation_time);
		gf_bs_write_u64(bs, ptr->first_offset);
	}
	gf_bs_write_u16(bs, 0);
	gf_bs_write_u16(bs, ptr->nb_refs);
	for (i=0; i<ptr->nb_refs; i++ ) {
		gf_bs_write_int(bs, ptr->refs[i].reference_type, 1);
		gf_bs_write_int(bs, ptr->refs[i].reference_size, 31);
		gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration);
		gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1);
		gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3);
		gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28);
	}
	return GF_OK;
}

GF_Err sidx_box_size(GF_Box *s)
{
	GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;

	ptr->size += 12;
	if (ptr->version==0) {
		ptr->size += 8;
	} else {
		ptr->size += 16;
	}
	ptr->size += ptr->nb_refs * 12;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ssix_box_del(GF_Box *s)
{
	u32 i;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s;
	if (ptr == NULL) return;
	if (ptr->subsegments) {
		for (i = 0; i < ptr->subsegment_alloc; i++) {
			GF_SubsegmentInfo *subsegment = &ptr->subsegments[i];
			if (subsegment->ranges) gf_free(subsegment->ranges);
		}
		gf_free(ptr->subsegments);
	}
	gf_free(ptr);
}

GF_Err ssix_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i,j;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;

	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->subsegment_count = gf_bs_read_u32(bs);
	//each subseg has at least one range_count (4 bytes), abort if not enough bytes (broken box)
	if (ptr->size / 4 < ptr->subsegment_count || (u64)ptr->subsegment_count > (u64)SIZE_MAX/sizeof(GF_SubsegmentInfo))
		return GF_ISOM_INVALID_FILE;

	ptr->subsegment_alloc = ptr->subsegment_count;
	GF_SAFE_ALLOC_N(ptr->subsegments, ptr->subsegment_count, GF_SubsegmentInfo);
	if (!ptr->subsegments)
		return GF_OUT_OF_MEM;
	for (i = 0; i < ptr->subsegment_count; i++) {
		GF_SubsegmentInfo *subseg = &ptr->subsegments[i];
		ISOM_DECREASE_SIZE(ptr, 4)
		subseg->range_count = gf_bs_read_u32(bs);
		//each range is 4 bytes, abort if not enough bytes
		if (ptr->size / 4 < subseg->range_count || (u64)subseg->range_count > (u64)SIZE_MAX/sizeof(GF_SubsegmentRangeInfo))
			return GF_ISOM_INVALID_FILE;
		subseg->ranges = (GF_SubsegmentRangeInfo*) gf_malloc(sizeof(GF_SubsegmentRangeInfo) * subseg->range_count);
		if (!subseg->ranges) return GF_OUT_OF_MEM;
		for (j = 0; j < subseg->range_count; j++) {
			ISOM_DECREASE_SIZE(ptr, 4)
			subseg->ranges[j].level = gf_bs_read_u8(bs);
			subseg->ranges[j].range_size = gf_bs_read_u24(bs);
		}
	}
	return GF_OK;
}

GF_Box *ssix_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SubsegmentIndexBox, GF_ISOM_BOX_TYPE_SSIX);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ssix_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, j;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->subsegment_count);
	for (i = 0; i<ptr->subsegment_count; i++) {
		gf_bs_write_u32(bs, ptr->subsegments[i].range_count);
		for (j = 0; j < ptr->subsegments[i].range_count; j++) {
			gf_bs_write_u8(bs, ptr->subsegments[i].ranges[j].level);
			gf_bs_write_u24(bs, ptr->subsegments[i].ranges[j].range_size);
		}
	}
	return GF_OK;
}

GF_Err ssix_box_size(GF_Box *s)
{
	u32 i;
	GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;

	ptr->size += 4;
	for (i = 0; i < ptr->subsegment_count; i++) {
		ptr->size += 4 + 4 * ptr->subsegments[i].range_count;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void leva_box_del(GF_Box *s)
{
	GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox *)s;
	if (ptr == NULL) return;
	if (ptr->levels) gf_free(ptr->levels);
	gf_free(ptr);
}

GF_Err leva_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;

	ISOM_DECREASE_SIZE(ptr, 1)
	ptr->level_count = gf_bs_read_u8(bs);
	//each level is at least 5 bytes
	if (ptr->size / 5 < ptr->level_count)
		return GF_ISOM_INVALID_FILE;

	GF_SAFE_ALLOC_N(ptr->levels, ptr->level_count, GF_LevelAssignment);
	if (!ptr->levels) return GF_OUT_OF_MEM;

	for (i = 0; i < ptr->level_count; i++) {
		GF_LevelAssignment *level = &ptr->levels[i];
		u8 tmp;
		if (!level || ptr->size < 5) return GF_BAD_PARAM;
		ISOM_DECREASE_SIZE(ptr, 5)

		level->track_id = gf_bs_read_u32(bs);
		tmp = gf_bs_read_u8(bs);
		level->padding_flag = tmp >> 7;
		level->type = tmp & 0x7F;
		if (level->type == 0) {
			ISOM_DECREASE_SIZE(ptr, 4)
			level->grouping_type = gf_bs_read_u32(bs);
		}
		else if (level->type == 1) {
			ISOM_DECREASE_SIZE(ptr, 8)
			level->grouping_type = gf_bs_read_u32(bs);
			level->grouping_type_parameter = gf_bs_read_u32(bs);
		}
		else if (level->type == 4) {
			ISOM_DECREASE_SIZE(ptr, 4)
			level->sub_track_id = gf_bs_read_u32(bs);
		}
	}
	return GF_OK;
}

GF_Box *leva_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_LevelAssignmentBox, GF_ISOM_BOX_TYPE_LEVA);
	return (GF_Box *)tmp;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err leva_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->level_count);
	for (i = 0; i<ptr->level_count; i++) {
		gf_bs_write_u32(bs, ptr->levels[i].track_id);
		gf_bs_write_u8(bs, ptr->levels[i].padding_flag << 7 | (ptr->levels[i].type & 0x7F));
		if (ptr->levels[i].type == 0) {
			gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
		}
		else if (ptr->levels[i].type == 1) {
			gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
			gf_bs_write_u32(bs, ptr->levels[i].grouping_type_parameter);
		}
		else if (ptr->levels[i].type == 4) {
			gf_bs_write_u32(bs, ptr->levels[i].sub_track_id);
		}
	}
	return GF_OK;
}

GF_Err leva_box_size(GF_Box *s)
{
	u32 i;
	GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;

	ptr->size += 1;
	for (i = 0; i < ptr->level_count; i++) {
		ptr->size += 5;
		if (ptr->levels[i].type == 0 || ptr->levels[i].type == 4) {
			ptr->size += 4;
		}
		else if (ptr->levels[i].type == 1) {
			ptr->size += 8;
		}
	}
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *pcrb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
	return (GF_Box *)tmp;
}

void pcrb_box_del(GF_Box *s)
{
	GF_PcrInfoBox *ptr = (GF_PcrInfoBox *) s;
	if (ptr == NULL) return;
	if (ptr->pcr_values) gf_free(ptr->pcr_values);
	gf_free(ptr);
}

GF_Err pcrb_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;

	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->subsegment_count = gf_bs_read_u32(bs);

	if ((u64)ptr->subsegment_count > ptr->size / 8 || (u64)ptr->subsegment_count > (u64)SIZE_MAX/sizeof(u64)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of subsegment %d in pcrb\n", ptr->subsegment_count));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count);
	if (!ptr->pcr_values) return GF_OUT_OF_MEM;
	for (i=0; i<ptr->subsegment_count; i++) {
		u64 data1 = gf_bs_read_u32(bs);
		u64 data2 = gf_bs_read_u16(bs);
		ISOM_DECREASE_SIZE(ptr, 6);
		ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6);

	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err pcrb_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->subsegment_count);

	for (i=0; i<ptr->subsegment_count; i++ ) {
		u32 data1 = (u32) (ptr->pcr_values[i] >> 10);
		u16 data2 = (u16) (ptr->pcr_values[i] << 6);

		gf_bs_write_u32(bs, data1);
		gf_bs_write_u16(bs, data2);
	}
	return GF_OK;
}

GF_Err pcrb_box_size(GF_Box *s)
{
	GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;

	ptr->size += 4;
	ptr->size += ptr->subsegment_count * 6;

	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *subs_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
	tmp->Samples = gf_list_new();
	return (GF_Box *)tmp;
}

void subs_box_del(GF_Box *s)
{
	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
	if (ptr == NULL) return;

	while (gf_list_count(ptr->Samples)) {
		GF_SubSampleInfoEntry *pSamp;
		pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
		while (gf_list_count(pSamp->SubSamples)) {
			GF_SubSampleEntry *pSubSamp;
			pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0);
			gf_free(pSubSamp);
			gf_list_rem(pSamp->SubSamples, 0);
		}
		gf_list_del(pSamp->SubSamples);
		gf_free(pSamp);
		gf_list_rem(ptr->Samples, 0);
	}
	gf_list_del(ptr->Samples);
	gf_free(ptr);
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err subs_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, j, entry_count;
	u16 subsample_count;
	GF_SubSampleEntry *pSubSamp;
	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;

	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	entry_count = gf_list_count(ptr->Samples);
	gf_bs_write_u32(bs, entry_count);

	for (i=0; i<entry_count; i++) {
		GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
		subsample_count = gf_list_count(pSamp->SubSamples);
		gf_bs_write_u32(bs, pSamp->sample_delta);
		gf_bs_write_u16(bs, subsample_count);

		for (j=0; j<subsample_count; j++) {
			pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, j);
			if (ptr->version == 1) {
				gf_bs_write_u32(bs, pSubSamp->subsample_size);
			} else {
				gf_bs_write_u16(bs, pSubSamp->subsample_size);
			}
			gf_bs_write_u8(bs, pSubSamp->subsample_priority);
			gf_bs_write_u8(bs, pSubSamp->discardable);
			gf_bs_write_u32(bs, pSubSamp->reserved);
		}
	}
	return e;
}

GF_Err subs_box_size(GF_Box *s)
{
	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
	u32 entry_count, i;
	u16 subsample_count;

	// add 4 byte for entry_count
	ptr->size += 4;
	entry_count = gf_list_count(ptr->Samples);
	for (i=0; i<entry_count; i++) {
		GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
		subsample_count = gf_list_count(pSamp->SubSamples);
		// 4 byte for sample_delta, 2 byte for subsample_count
		// and 6 + (4 or 2) bytes for each subsample
		ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version==1 ? 4 : 2));
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Err subs_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
	u32 entry_count, i, j;
	u16 subsample_count;

	ISOM_DECREASE_SIZE(ptr, 4);
	entry_count = gf_bs_read_u32(bs);

	if ((u64)entry_count*6 > gf_bs_available(bs)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] subs box: available buffer (%lu) too small for entry count read (%u)\n", gf_bs_available(bs), entry_count));
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	for (i=0; i<entry_count; i++) {
		u32 subs_size=0;
		GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_malloc(sizeof(GF_SubSampleInfoEntry));
		if (!pSamp) return GF_OUT_OF_MEM;

		memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
		pSamp->SubSamples = gf_list_new();
		pSamp->sample_delta = gf_bs_read_u32(bs);
		subsample_count = gf_bs_read_u16(bs);
		subs_size=6;

		for (j=0; j<subsample_count; j++) {
			GF_SubSampleEntry *pSubSamp = (GF_SubSampleEntry*) gf_malloc(sizeof(GF_SubSampleEntry));
			if (!pSubSamp) return GF_OUT_OF_MEM;

			memset(pSubSamp, 0, sizeof(GF_SubSampleEntry));
			if (ptr->version==1) {
				pSubSamp->subsample_size = gf_bs_read_u32(bs);
				subs_size+=4;
			} else {
				pSubSamp->subsample_size = gf_bs_read_u16(bs);
				subs_size+=2;
			}
			pSubSamp->subsample_priority = gf_bs_read_u8(bs);
			pSubSamp->discardable = gf_bs_read_u8(bs);
			pSubSamp->reserved = gf_bs_read_u32(bs);
			subs_size+=6;

			gf_list_add(pSamp->SubSamples, pSubSamp);
		}
		gf_list_add(ptr->Samples, pSamp);
		ISOM_DECREASE_SIZE(ptr, subs_size);
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_FRAGMENTS

GF_Box *tfdt_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
	return (GF_Box *)tmp;
}

void tfdt_box_del(GF_Box *s)
{
	gf_free(s);
}

/*this is using chpl format according to some NeroRecode samples*/
GF_Err tfdt_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;

	if (ptr->version==1) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->baseMediaDecodeTime = gf_bs_read_u64(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tfdt_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->version==1) {
		gf_bs_write_u64(bs, ptr->baseMediaDecodeTime);
	} else {
		gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime);
	}
	return GF_OK;
}

GF_Err tfdt_box_size(GF_Box *s)
{
	GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;

	if (!ptr->version && (ptr->baseMediaDecodeTime<=0xFFFFFFFF)) {
		//ptr->version = 0;
		ptr->size += 4;
	} else {
		ptr->version = 1;
		ptr->size += 8;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *rsot_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TFOriginalDurationBox, GF_ISOM_BOX_TYPE_RSOT);
	return (GF_Box *)tmp;
}

void rsot_box_del(GF_Box *s)
{
	gf_free(s);
}

/*this is using chpl format according to some NeroRecode samples*/
GF_Err rsot_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_TFOriginalDurationBox *ptr = (GF_TFOriginalDurationBox *)s;

	if (ptr->flags & 1) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->original_duration = gf_bs_read_u32(bs);
	}
	if (ptr->flags & 2) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->elapsed_duration = (u32) gf_bs_read_u32(bs);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err rsot_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TFOriginalDurationBox *ptr = (GF_TFOriginalDurationBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->flags & 1) {
		gf_bs_write_u32(bs, ptr->original_duration);
	}
	if (ptr->flags & 2) {
		gf_bs_write_u32(bs, (u32) ptr->elapsed_duration);
	}
	return GF_OK;
}

GF_Err rsot_box_size(GF_Box *s)
{
	GF_TFOriginalDurationBox *ptr = (GF_TFOriginalDurationBox *)s;

	if (ptr->original_duration) {
		ptr->flags |= 1;
		ptr->size+=4;
	}
	if (ptr->elapsed_duration) {
		ptr->flags |= 2;
		ptr->size+=4;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/


GF_Box *rvcc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
	return (GF_Box *)tmp;
}

void rvcc_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err rvcc_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
	ISOM_DECREASE_SIZE(ptr, 2);
	ptr->predefined_rvc_config = gf_bs_read_u16(bs);
	if (!ptr->predefined_rvc_config) {
		ISOM_DECREASE_SIZE(ptr, 2);
		ptr->rvc_meta_idx = gf_bs_read_u16(bs);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err rvcc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u16(bs, ptr->predefined_rvc_config);
	if (!ptr->predefined_rvc_config) {
		gf_bs_write_u16(bs, ptr->rvc_meta_idx);
	}
	return GF_OK;
}

GF_Err rvcc_box_size(GF_Box *s)
{
	GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s;
	ptr->size += 2;
	if (! ptr->predefined_rvc_config) ptr->size += 2;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *sbgp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
	return (GF_Box *)tmp;
}
void sbgp_box_del(GF_Box *a)
{
	GF_SampleGroupBox *p = (GF_SampleGroupBox *)a;
	if (p->sample_entries) gf_free(p->sample_entries);
	gf_free(p);
}

GF_Err sbgp_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_SampleGroupBox *ptr = (GF_SampleGroupBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->grouping_type = gf_bs_read_u32(bs);

	if (ptr->version==1) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->grouping_type_parameter = gf_bs_read_u32(bs);
	}
	ptr->entry_count = gf_bs_read_u32(bs);

	if (ptr->size < sizeof(GF_SampleGroupEntry)*ptr->entry_count || (u64)ptr->entry_count > (u64)SIZE_MAX/sizeof(GF_SampleGroupEntry))
		return GF_ISOM_INVALID_FILE;

	ptr->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*ptr->entry_count);
	if (!ptr->sample_entries) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->entry_count; i++) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->sample_entries[i].sample_count = gf_bs_read_u32(bs);
		ptr->sample_entries[i].group_description_index = gf_bs_read_u32(bs);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sbgp_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, p->grouping_type);
	if (p->version==1)
		gf_bs_write_u32(bs, p->grouping_type_parameter);

	gf_bs_write_u32(bs, p->entry_count);
	for (i = 0; i<p->entry_count; i++ ) {
		gf_bs_write_u32(bs, p->sample_entries[i].sample_count);
		gf_bs_write_u32(bs, p->sample_entries[i].group_description_index);
	}
	return GF_OK;
}

GF_Err sbgp_box_size(GF_Box *s)
{
	GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;

	p->size += 8;
	if (p->grouping_type_parameter) p->version=1;

	if (p->version==1) p->size += 4;
	p->size += 8*p->entry_count;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void *sgpd_parse_entry(GF_SampleGroupDescriptionBox *p, GF_BitStream *bs, s32 bytes_in_box, u32 entry_size, u32 *total_bytes)
{
	Bool null_size_ok = GF_FALSE;
	GF_DefaultSampleGroupDescriptionEntry *def_ptr;
	p->is_opaque = GF_FALSE;
	switch (p->grouping_type) {
	case GF_ISOM_SAMPLE_GROUP_ROLL:
	case GF_ISOM_SAMPLE_GROUP_PROL:
	{
		GF_RollRecoveryEntry *ptr;
		GF_SAFEALLOC(ptr, GF_RollRecoveryEntry);
		if (!ptr) return NULL;
		ptr->roll_distance = gf_bs_read_int(bs, 16);
		*total_bytes = 2;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_RAP:
	{
		GF_VisualRandomAccessEntry *ptr;
		GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry);
		if (!ptr) return NULL;
		ptr->num_leading_samples_known = gf_bs_read_int(bs, 1);
		ptr->num_leading_samples = gf_bs_read_int(bs, 7);
		*total_bytes = 1;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_SAP:
	{
		GF_SAPEntry *ptr;
		GF_SAFEALLOC(ptr, GF_SAPEntry);
		if (!ptr) return NULL;
		ptr->dependent_flag = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 3);
		ptr->SAP_type = gf_bs_read_int(bs, 4);
		*total_bytes = 1;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_SYNC:
	{
		GF_SYNCEntry *ptr;
		GF_SAFEALLOC(ptr, GF_SYNCEntry);
		if (!ptr) return NULL;
		gf_bs_read_int(bs, 2);
		ptr->NALU_type = gf_bs_read_int(bs, 6);
		*total_bytes = 1;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_TELE:
	{
		GF_TemporalLevelEntry *ptr;
		GF_SAFEALLOC(ptr, GF_TemporalLevelEntry);
		if (!ptr) return NULL;
		ptr->level_independently_decodable = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 7);
		*total_bytes = 1;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_SEIG:
	{
		GF_CENCSampleEncryptionGroupEntry *ptr;
		if (bytes_in_box<3) return NULL;
		GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry);
		if (!ptr) return NULL;
		Bool use_mkey = gf_bs_read_int(bs, 1);
		Bool ext_pattern = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 6); //reserved
		if (ext_pattern) {
			ptr->crypt_byte_block = gf_bs_read_u32(bs);
			ptr->skip_byte_block = gf_bs_read_u32(bs);
		} else {
			ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
			ptr->skip_byte_block = gf_bs_read_int(bs, 4);
		}
		ptr->IsProtected = gf_bs_read_u8(bs);
		bytes_in_box -= 3;
		if (use_mkey) {
			u64 pos = gf_bs_get_position(bs);
			u32 i, count = gf_bs_read_u16(bs);
			bytes_in_box -= 2;
			if (bytes_in_box<0) {
				gf_free(ptr);
				return NULL;
			}
			for (i=0; i<count; i++) {
				u8 ivsize = gf_bs_read_u8(bs);
				gf_bs_skip_bytes(bs, 16);
				bytes_in_box -= 17;
				if (!ivsize) {
					//const IV
					ivsize = gf_bs_read_u8(bs);
					gf_bs_skip_bytes(bs, ivsize);
					bytes_in_box -= 1 + ivsize;
				}
				if (bytes_in_box<0) {
					gf_free(ptr);
					return NULL;
				}
			}
			ptr->key_info_size = 1 + (u32) (gf_bs_get_position(bs) - pos);
			ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
			if (!ptr->key_info) {
				gf_free(ptr);
				return NULL;
			}
			gf_bs_seek(bs, pos);
			ptr->key_info[0] = 1;
			gf_bs_read_data(bs, ptr->key_info + 1, ptr->key_info_size - 1);
			*total_bytes = 3 + ptr->key_info_size - 1;

			if (!gf_cenc_validate_key_info(ptr->key_info, ptr->key_info_size)) {
				gf_free(ptr->key_info);
				gf_free(ptr);
				return NULL;
			}
		} else {
			bin128 kid;
			u8 const_iv_size = 0;
			u8 iv_size = gf_bs_read_u8(bs);
			gf_bs_read_data(bs, kid, 16);
			bytes_in_box -= 17;
			if (bytes_in_box<0) {
				gf_free(ptr);
				return NULL;
			}

			*total_bytes = 20;
			if ((ptr->IsProtected == 1) && !iv_size) {
				const_iv_size = gf_bs_read_u8(bs);
				if ((const_iv_size != 8) && (const_iv_size != 16)) {
					GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group have invalid constant_IV size\n"));
					gf_free(ptr);
					return NULL;
				}
			}
			ptr->key_info_size = 20;
			if (!iv_size && ptr->IsProtected) {
				ptr->key_info_size += 1 + const_iv_size;
			}
			ptr->key_info = gf_malloc(sizeof(u8) * ptr->key_info_size);
			if (!ptr->key_info) {
				gf_free(ptr);
				return NULL;
			}
			ptr->key_info[0] = 0;
			ptr->key_info[1] = 0;
			ptr->key_info[2] = 0;
			ptr->key_info[3] = iv_size;
			memcpy(ptr->key_info+4, kid, 16);
			if (!iv_size && ptr->IsProtected) {
				ptr->key_info[20] = const_iv_size;
				gf_bs_read_data(bs, (char *)ptr->key_info+21, const_iv_size);
				*total_bytes += 1 + const_iv_size;
			}
		}

		if (!entry_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n"));
		}
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_OINF:
	{
		GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry();
		u32 s = (u32) gf_bs_get_position(bs);
		gf_isom_oinf_read_entry(ptr, bs);
		*total_bytes = (u32) gf_bs_get_position(bs) - s;
		if (!entry_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n"));
		}
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_LINF:
	{
		GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry();
		u32 s = (u32) gf_bs_get_position(bs);
		gf_isom_linf_read_entry(ptr, bs);
		*total_bytes = (u32) gf_bs_get_position(bs) - s;
		if (!entry_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n"));
		}
		return ptr;
	}

	case GF_ISOM_SAMPLE_GROUP_TRIF:
		if (! entry_size) {
			u32 flags = gf_bs_peek_bits(bs, 24, 0);
			if (flags & 0x10000) entry_size=3;
			else {
				if (flags & 0x80000) entry_size=7;
				else entry_size=11;
				//have dependency list
				if (flags & 0x200000) {
					u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size);
					entry_size += 2 + 2*nb_entries;
				}
			}
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n"));
		}
		break;
	case GF_ISOM_SAMPLE_GROUP_NALM:
		if (! entry_size) {
			u64 start = gf_bs_get_position(bs);
			Bool rle, large_size;
			u32 entry_count;
			gf_bs_read_int(bs, 6);
			large_size = gf_bs_read_int(bs, 1);
			rle = gf_bs_read_int(bs, 1);
			entry_count = gf_bs_read_int(bs, large_size ? 16 : 8);
			gf_bs_seek(bs, start);
			entry_size = 1 + (large_size ? 2 : 1);
			entry_size += entry_count * 2;
			if (rle) entry_size += entry_count * (large_size ? 2 : 1);
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n"));
		}
		break;

	case GF_ISOM_SAMPLE_GROUP_AV1S:
	case GF_ISOM_SAMPLE_GROUP_TSAS:
	case GF_ISOM_SAMPLE_GROUP_STSA:
		null_size_ok = GF_TRUE;
		break;
	//TODO, add support for these ones ?
	case GF_ISOM_SAMPLE_GROUP_TSCL:
		entry_size = 20;
		break;
	case GF_ISOM_SAMPLE_GROUP_LBLI:
		entry_size = 2;
		break;
	case GF_ISOM_SAMPLE_GROUP_SPOR:
	{
		u32 i;
		GF_SubpictureOrderEntry *ptr;
		GF_SAFEALLOC(ptr, GF_SubpictureOrderEntry);
		if (!ptr) return NULL;
		ptr->subpic_id_info_flag = gf_bs_read_int(bs, 1);
		ptr->num_subpic_ref_idx = gf_bs_read_int(bs, 15);
		*total_bytes = 2;
		ptr->subp_track_ref_idx = gf_malloc(sizeof(u16) * ptr->num_subpic_ref_idx);
		if (!ptr->subp_track_ref_idx) {
			gf_free(ptr);
			return NULL;
		}
		for (i=0; i<ptr->num_subpic_ref_idx; i++) {
			ptr->subp_track_ref_idx[i] = gf_bs_read_u16(bs);
			*total_bytes += 2;
			if (gf_bs_is_overflow(bs)) {
				gf_free(ptr->subp_track_ref_idx);
				gf_free(ptr);
				return NULL;
			}
		}
		if (ptr->subpic_id_info_flag) {
			ptr->spinfo.subpic_id_len_minus1 = gf_bs_read_int(bs, 4);
			ptr->spinfo.subpic_id_bit_pos = gf_bs_read_int(bs, 12);
			ptr->spinfo.start_code_emul_flag = gf_bs_read_int(bs, 1);
			ptr->spinfo.pps_sps_subpic_id_flag = gf_bs_read_int(bs, 1);
			if (ptr->spinfo.pps_sps_subpic_id_flag) {
				ptr->spinfo.xps_id = gf_bs_read_int(bs, 6);
			} else {
				ptr->spinfo.xps_id = gf_bs_read_int(bs, 4);
				gf_bs_read_int(bs, 2);
			}
			*total_bytes += 3;
		}
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_SULM:
	{
		u32 i;
		GF_SubpictureLayoutMapEntry *ptr;
		GF_SAFEALLOC(ptr, GF_SubpictureLayoutMapEntry);
		if (!ptr) return NULL;
		ptr->groupID_info_4cc = gf_bs_read_u32(bs);
		ptr->nb_entries = 1 + gf_bs_read_u16(bs);
		*total_bytes = 6;
		ptr->groupIDs = gf_malloc(sizeof(u16) * ptr->nb_entries);
		if (!ptr->groupIDs) {
			gf_free(ptr);
			return NULL;
		}
		for (i=0; i<ptr->nb_entries; i++) {
			ptr->groupIDs[i] = gf_bs_read_u16(bs);
			*total_bytes += 2;
			if (gf_bs_is_overflow(bs)) {
				gf_free(ptr->groupIDs);
				gf_free(ptr);
				return NULL;
			}
		}
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_ILCE:
	{
		GF_FieldInterlaceType *ptr;
		GF_SAFEALLOC(ptr, GF_FieldInterlaceType);
		if (!ptr) return NULL;
		ptr->ilce_type = gf_bs_read_u8(bs);
		*total_bytes = 1;
		return ptr;
	}
	case GF_ISOM_SAMPLE_GROUP_ESGH:
	{
		u32 i;
		GF_EssentialSamplegroupEntry *ptr;
		GF_SAFEALLOC(ptr, GF_EssentialSamplegroupEntry);
		if (!ptr) return NULL;
		ptr->nb_types = gf_bs_read_u32(bs);
		if ((u64)ptr->nb_types * 4 + 4 > entry_size) {
			gf_free(ptr);
			return NULL;
		}
		*total_bytes = 4;
		ptr->group_types = gf_malloc(sizeof(u32) * ptr->nb_types);
		if (!ptr->group_types) {
			gf_free(ptr);
			return NULL;
		}
		for (i=0; i<ptr->nb_types; i++) {
			ptr->group_types[i] = gf_bs_read_u32(bs);
			*total_bytes += 4;
			if (gf_bs_is_overflow(bs)) {
				gf_free(ptr->group_types);
				gf_free(ptr);
				return NULL;
			}
		}
		return ptr;
	}
	case 0:
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] sgpd entry null grouping_type is invalid\n") );
		return NULL;
	default:
		break;
	}

	if (!entry_size && !null_size_ok) {
		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( p->grouping_type) ));
		return NULL;
	}
	p->is_opaque = GF_TRUE;
	GF_SAFEALLOC(def_ptr, GF_DefaultSampleGroupDescriptionEntry);
	if (!def_ptr) return NULL;
	if (entry_size) {
		def_ptr->length = entry_size;
		def_ptr->data = (u8 *) gf_malloc(sizeof(u8)*def_ptr->length);
		if (!def_ptr->data) {
			gf_free(def_ptr);
			return NULL;
		}
		gf_bs_read_data(bs, (char *) def_ptr->data, def_ptr->length);
		*total_bytes = entry_size;
	}
	return def_ptr;
}

void sgpd_del_entry(u32 grouping_type, void *entry, Bool is_opaque)
{
	if (is_opaque) {
		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
		if (ptr && ptr->data) gf_free(ptr->data);
		gf_free(entry);
		return;
	}

	switch (grouping_type) {
	case GF_ISOM_SAMPLE_GROUP_SYNC:
	case GF_ISOM_SAMPLE_GROUP_ROLL:
	case GF_ISOM_SAMPLE_GROUP_PROL:
	case GF_ISOM_SAMPLE_GROUP_RAP:
	case GF_ISOM_SAMPLE_GROUP_TELE:
	case GF_ISOM_SAMPLE_GROUP_SAP:
	case GF_ISOM_SAMPLE_GROUP_AV1S:
		gf_free(entry);
		return;
	case GF_ISOM_SAMPLE_GROUP_SEIG:
	{
		GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
		if (seig->key_info) gf_free(seig->key_info);
		gf_free(entry);
	}
		return;
	case GF_ISOM_SAMPLE_GROUP_OINF:
		gf_isom_oinf_del_entry(entry);
		return;
	case GF_ISOM_SAMPLE_GROUP_LINF:
		gf_isom_linf_del_entry(entry);
		return;
	case GF_ISOM_SAMPLE_GROUP_SPOR:
	{
		GF_SubpictureOrderEntry *spor = (GF_SubpictureOrderEntry *)entry;
		if (spor->subp_track_ref_idx) gf_free(spor->subp_track_ref_idx);
		gf_free(spor);
	}
		return;

	case GF_ISOM_SAMPLE_GROUP_SULM:
	{
		GF_SubpictureLayoutMapEntry *sulm = (GF_SubpictureLayoutMapEntry *) entry;
		if (sulm->groupIDs) gf_free(sulm->groupIDs);
		gf_free(sulm);
		return;
	}
	case GF_ISOM_SAMPLE_GROUP_ILCE:
		gf_free(entry);
		return;

	case GF_ISOM_SAMPLE_GROUP_ESGH:
	{
		GF_EssentialSamplegroupEntry *esgh = (GF_EssentialSamplegroupEntry *) entry;
		if (esgh->group_types) gf_free(esgh->group_types);
		gf_free(esgh);
		return;
	}

	default:
	{
		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
		if (ptr->data) gf_free(ptr->data);
		gf_free(ptr);
	}
	}
}

void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs)
{
	switch (grouping_type) {
	case GF_ISOM_SAMPLE_GROUP_ROLL:
	case GF_ISOM_SAMPLE_GROUP_PROL:
		gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16);
		return;
	case GF_ISOM_SAMPLE_GROUP_RAP:
		gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1);
		gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7);
		return;
	case GF_ISOM_SAMPLE_GROUP_SAP:
		gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->dependent_flag, 1);
		gf_bs_write_int(bs, 0, 3);
		gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->SAP_type, 4);
		return;
	case GF_ISOM_SAMPLE_GROUP_SYNC:
		gf_bs_write_int(bs, 0, 2);
		gf_bs_write_int(bs, ((GF_SYNCEntry*)entry)->NALU_type, 6);
		return;
	case GF_ISOM_SAMPLE_GROUP_TELE:
		gf_bs_write_int(bs, ((GF_TemporalLevelEntry*)entry)->level_independently_decodable, 1);
		gf_bs_write_int(bs, 0, 7);
		return;
	case GF_ISOM_SAMPLE_GROUP_SEIG:
	{
		GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
		Bool use_mkey = seig->key_info[0];
		/*
		u32 nb_keys = 1;
		if (use_mkey) {
			nb_keys = seig->key_info[1];
			nb_keys<<=8;
			nb_keys |= seig->key_info[2];
		}
		*/
		gf_bs_write_int(bs, use_mkey ? 1 : 0, 1);
		if ((seig->crypt_byte_block>15) || (seig->skip_byte_block>15)) {
			gf_bs_write_int(bs, 1, 1);
			gf_bs_write_int(bs, 0, 6);
			gf_bs_write_u32(bs, seig->crypt_byte_block);
			gf_bs_write_u32(bs, seig->skip_byte_block);
		} else {
			gf_bs_write_int(bs, 0, 7);
			gf_bs_write_int(bs, seig->crypt_byte_block, 4);
			gf_bs_write_int(bs, seig->skip_byte_block, 4);
		}
		gf_bs_write_u8(bs, seig->IsProtected);
		if (use_mkey) {
			gf_bs_write_data(bs, seig->key_info+1, seig->key_info_size-1);
		} else {
			gf_bs_write_data(bs, seig->key_info+3, seig->key_info_size - 3);
		}
	}
		return;
	case GF_ISOM_SAMPLE_GROUP_OINF:
		gf_isom_oinf_write_entry(entry, bs);
		return;
	case GF_ISOM_SAMPLE_GROUP_LINF:
		gf_isom_linf_write_entry(entry, bs);
		return;

	case GF_ISOM_SAMPLE_GROUP_SPOR:
	{
		u32 i;
		GF_SubpictureOrderEntry *spor = (GF_SubpictureOrderEntry *) entry;
		gf_bs_write_int(bs, spor->subpic_id_info_flag, 1);
		gf_bs_write_int(bs, spor->num_subpic_ref_idx, 15);
		for (i=0; i<spor->num_subpic_ref_idx; i++) {
			gf_bs_write_u16(bs, spor->subp_track_ref_idx[i]);
		}
		if (spor->subpic_id_info_flag) {
			gf_bs_write_int(bs, spor->spinfo.subpic_id_len_minus1, 4);
			gf_bs_write_int(bs, spor->spinfo.subpic_id_bit_pos, 12);
			gf_bs_write_int(bs, spor->spinfo.start_code_emul_flag, 1);
			gf_bs_write_int(bs, spor->spinfo.pps_sps_subpic_id_flag, 1);
			if (spor->spinfo.pps_sps_subpic_id_flag) {
				gf_bs_write_int(bs, spor->spinfo.xps_id, 6);
			} else {
				gf_bs_write_int(bs, spor->spinfo.xps_id, 4);
				gf_bs_write_int(bs, 0, 2);
			}
		}
		return;
	}

	case GF_ISOM_SAMPLE_GROUP_SULM:
	{
		u32 i;
		GF_SubpictureLayoutMapEntry *sulm = (GF_SubpictureLayoutMapEntry *) entry;
		gf_bs_write_u32(bs, sulm->groupID_info_4cc);
		gf_bs_write_u16(bs, sulm->nb_entries - 1);
		for (i=0; i<sulm->nb_entries; i++) {
			gf_bs_write_u16(bs, sulm->groupIDs[i]);
		}
		return;
	}
	case GF_ISOM_SAMPLE_GROUP_ILCE:
	{
		GF_FieldInterlaceType *ilce = (GF_FieldInterlaceType *) entry;
		gf_bs_write_u8(bs, ilce->ilce_type);
		return;
	}

	case GF_ISOM_SAMPLE_GROUP_ESGH:
	{
		u32 i;
		GF_EssentialSamplegroupEntry *esgh = (GF_EssentialSamplegroupEntry *) entry;
		gf_bs_write_u32(bs, esgh->nb_types);
		for (i=0; i<esgh->nb_types; i++) {
			gf_bs_write_u32(bs, esgh->group_types[i]);
		}
		return;
	}

	default:
	{
		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
		if (ptr->length)
			gf_bs_write_data(bs, (char *) ptr->data, ptr->length);
	}
	}
}

#ifndef GPAC_DISABLE_ISOM_WRITE
static u32 sgpd_size_entry(u32 grouping_type, void *entry)
{
	switch (grouping_type) {
	case GF_ISOM_SAMPLE_GROUP_ROLL:
	case GF_ISOM_SAMPLE_GROUP_PROL:
		return 2;
	case GF_ISOM_SAMPLE_GROUP_TELE:
	case GF_ISOM_SAMPLE_GROUP_RAP:
	case GF_ISOM_SAMPLE_GROUP_SAP:
	case GF_ISOM_SAMPLE_GROUP_SYNC:
		return 1;
	case GF_ISOM_SAMPLE_GROUP_TSCL:
		return 20;
	case GF_ISOM_SAMPLE_GROUP_LBLI:
		return 2;
	case GF_ISOM_SAMPLE_GROUP_AV1S:
	case GF_ISOM_SAMPLE_GROUP_TSAS:
	case GF_ISOM_SAMPLE_GROUP_STSA:
		return 0;
	case GF_ISOM_SAMPLE_GROUP_SEIG:
	{
		GF_CENCSampleEncryptionGroupEntry *seig = (GF_CENCSampleEncryptionGroupEntry *)entry;
		u32 base_size = 3;
		if ((seig->crypt_byte_block>15) || (seig->skip_byte_block>15)) {
			base_size += 7;
		}
		Bool use_mkey = seig->key_info[0] ? GF_TRUE : GF_FALSE;
		if (use_mkey) {
			return base_size + seig->key_info_size-1;
		}
		return base_size + seig->key_info_size-3;
	}
	case GF_ISOM_SAMPLE_GROUP_OINF:
		return gf_isom_oinf_size_entry(entry);
	case GF_ISOM_SAMPLE_GROUP_LINF:
		return gf_isom_linf_size_entry(entry);
	case GF_ISOM_SAMPLE_GROUP_SPOR:
	{
		GF_SubpictureOrderEntry *spor = (GF_SubpictureOrderEntry *)entry;
		u32 s = 2 + 2*spor->num_subpic_ref_idx;
		if (spor->subpic_id_info_flag) {
			s += 3;
		}
		return s;
	}
	case GF_ISOM_SAMPLE_GROUP_SULM:
	{
		GF_SubpictureLayoutMapEntry *sulm = (GF_SubpictureLayoutMapEntry *) entry;
		return 6 + 2*sulm->nb_entries;
	}
	case GF_ISOM_SAMPLE_GROUP_ILCE:
		return 1;

	case GF_ISOM_SAMPLE_GROUP_ESGH:
	{
		GF_EssentialSamplegroupEntry *esgh = (GF_EssentialSamplegroupEntry *) entry;
		return 4 + 4*esgh->nb_types;
	}

	default:
		return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length;
	}
}
#endif

GF_Box *sgpd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
	/*version 0 is deprecated, use v1 by default*/
	tmp->version = 1;
	tmp->group_descriptions = gf_list_new();
	return (GF_Box *)tmp;
}

void sgpd_box_del(GF_Box *a)
{
	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a;
	while (gf_list_count(p->group_descriptions)) {
		void *ptr = gf_list_last(p->group_descriptions);
		sgpd_del_entry(p->grouping_type, ptr, p->is_opaque);
		gf_list_rem_last(p->group_descriptions);
	}
	gf_list_del(p->group_descriptions);
	gf_free(p);
}

GF_Err sgpd_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 entry_count;
	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;

	ISOM_DECREASE_SIZE(p, 8);
	p->grouping_type = gf_bs_read_u32(bs);

	if (p->version>=1) {
		ISOM_DECREASE_SIZE(p, 4);
		p->default_length = gf_bs_read_u32(bs);
	}
	if (p->version>=2) {
		ISOM_DECREASE_SIZE(p, 4);
		p->default_description_index = gf_bs_read_u32(bs);
	}
	entry_count = gf_bs_read_u32(bs);

	if (entry_count>p->size)
		return GF_ISOM_INVALID_FILE;

	while (entry_count) {
		void *ptr;
		u32 parsed_bytes=0;
		u32 size = p->default_length;
		if ((p->version>=1) && !size) {
			size = gf_bs_read_u32(bs);
			ISOM_DECREASE_SIZE(p, 4);
		}
		if (size && size>p->size) {
			return GF_ISOM_INVALID_FILE;
		}
		ptr = sgpd_parse_entry(p, bs, (s32) p->size, size, &parsed_bytes);
		//don't return an error, just stop parsing so that we skip over the sgpd box
		if (!ptr) return GF_OK;
		gf_list_add(p->group_descriptions, ptr);

		ISOM_DECREASE_SIZE(p, parsed_bytes);
		entry_count--;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sgpd_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i, nb_descs;
	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
	GF_Err e;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, p->grouping_type);
	if (p->version>=1) gf_bs_write_u32(bs, p->default_length);
	if (p->version>=2) gf_bs_write_u32(bs, p->default_description_index);
	nb_descs = gf_list_count(p->group_descriptions);
	gf_bs_write_u32(bs, nb_descs);

	for (i=0; i<nb_descs; i++) {
		void *ptr = gf_list_get(p->group_descriptions, i);
		if ((p->version >= 1) && !p->default_length) {
			u32 size = sgpd_size_entry(p->grouping_type, ptr);
			gf_bs_write_u32(bs, size);
		}
		sgpd_write_entry(p->grouping_type, ptr, bs);
	}
	return GF_OK;
}

GF_Err sgpd_box_size(GF_Box *s)
{
	u32 i, nb_descs;
	Bool use_def_size = GF_TRUE;
	GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;

	p->size += 8;

	//we force all sample groups to version 1, v0 being deprecated
	if (!p->version)
		p->version = 1;
	p->size += 4;

	if (p->version>=2)
		p->size += 4;
	p->default_length = 0;

	nb_descs = gf_list_count(p->group_descriptions);
	for (i=0; i<nb_descs; i++) {
		void *ptr = gf_list_get(p->group_descriptions, i);
		u32 size = sgpd_size_entry(p->grouping_type, ptr);
		p->size += size;
		if (use_def_size && !p->default_length) {
			p->default_length = size;
		} else if (p->default_length != size) {
			use_def_size = GF_FALSE;
			p->default_length = 0;
		}
	}
	if (p->version>=1) {
		if (!p->default_length) p->size += nb_descs * 4;
	}
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


void saiz_box_del(GF_Box *s)
{
	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
	if (ptr == NULL) return;
	if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
	gf_free(ptr);
}


GF_Err saiz_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;

	if (ptr->flags & 1) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->aux_info_type = gf_bs_read_u32(bs);
		ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
	}
	ISOM_DECREASE_SIZE(ptr, 5);
	ptr->default_sample_info_size = gf_bs_read_u8(bs);
	ptr->sample_count = gf_bs_read_u32(bs);

	if (ptr->default_sample_info_size == 0) {
		if (ptr->size < ptr->sample_count)
			return GF_ISOM_INVALID_FILE;

		ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
		ptr->sample_alloc = ptr->sample_count;
		if (!ptr->sample_info_size)
			return GF_OUT_OF_MEM;

		ISOM_DECREASE_SIZE(ptr, ptr->sample_count);
		gf_bs_read_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
	}
	return GF_OK;
}

GF_Box *saiz_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err saiz_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->flags & 1) {
		gf_bs_write_u32(bs, ptr->aux_info_type);
		gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
	}
	gf_bs_write_u8(bs, ptr->default_sample_info_size);
	gf_bs_write_u32(bs, ptr->sample_count);
	if (!ptr->default_sample_info_size) {
		if (!ptr->sample_info_size)
			gf_bs_write_u8(bs, 0);
		else
			gf_bs_write_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
	}
	return GF_OK;
}

GF_Err saiz_box_size(GF_Box *s)
{
	GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;

	if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
		ptr->flags |= 1;
	}
	if (ptr->flags & 1) ptr->size += 8;
	ptr->size += 5;
	if (ptr->default_sample_info_size==0)  ptr->size += ptr->sample_count;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

void saio_box_del(GF_Box *s)
{
	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
	if (ptr == NULL) return;
	if (ptr->offsets) gf_free(ptr->offsets);
	if (ptr->cached_data) gf_free(ptr->cached_data);
	gf_free(ptr);
}


GF_Err saio_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;

	if (ptr->flags & 1) {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->aux_info_type = gf_bs_read_u32(bs);
		ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
	}
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->entry_count = gf_bs_read_u32(bs);

	if (ptr->entry_count) {
		u32 i;
		if (ptr->size / (ptr->version == 0 ? 4 : 8) < ptr->entry_count || (u64)ptr->entry_count > (u64)SIZE_MAX/sizeof(u64))
			return GF_ISOM_INVALID_FILE;
		ptr->offsets = gf_malloc(sizeof(u64)*ptr->entry_count);
		if (!ptr->offsets)
			return GF_OUT_OF_MEM;
		ptr->entry_alloc = ptr->entry_count;
		if (ptr->version==0) {
			ISOM_DECREASE_SIZE(ptr, 4*ptr->entry_count);
			for (i=0; i<ptr->entry_count; i++)
				ptr->offsets[i] = gf_bs_read_u32(bs);
		} else {
			ISOM_DECREASE_SIZE(ptr, 8*ptr->entry_count);
			for (i=0; i<ptr->entry_count; i++)
				ptr->offsets[i] = gf_bs_read_u64(bs);
		}
	}
	return GF_OK;
}

GF_Box *saio_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err saio_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->flags & 1) {
		gf_bs_write_u32(bs, ptr->aux_info_type);
		gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
	}


	gf_bs_write_u32(bs, ptr->entry_count);
	if (ptr->entry_count) {
		u32 i;
		if (ptr->sai_data) {
			if (ptr->sai_data->sai_offset) {
				if (ptr->version==0) {
					gf_bs_write_u32(bs, (u32) ptr->sai_data->sai_offset);
				} else {
					gf_bs_write_u64(bs, ptr->sai_data->sai_offset);
				}
				return GF_OK;
			}
			ptr->sai_data->saio_box = ptr;
		}

		//store position in bitstream before writing data - offsets can be NULL if a single offset is rewritten later on (cf senc_box_write)
		ptr->offset_first_offset_field = gf_bs_get_position(bs);
		if (ptr->version==0) {
			if (!ptr->offsets) {
				gf_bs_write_u32(bs, 0);
			} else {
				for (i=0; i<ptr->entry_count; i++)
					gf_bs_write_u32(bs, (u32) ptr->offsets[i]);
			}
		} else {
			if (!ptr->offsets) {
				gf_bs_write_u64(bs, 0);
			} else {
				for (i=0; i<ptr->entry_count; i++)
					gf_bs_write_u64(bs, ptr->offsets[i]);
			}
		}
	}
	return GF_OK;
}

GF_Err saio_box_size(GF_Box *s)
{
	GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;

	if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
		ptr->flags |= 1;
	}

	if (ptr->flags & 1) ptr->size += 8;
	ptr->size += 4;
	//a little optim here: in cenc, the saio always points to a single data block, only one entry is needed
	switch (ptr->aux_info_type) {
	case GF_ISOM_CENC_SCHEME:
	case GF_ISOM_CBC_SCHEME:
	case GF_ISOM_CENS_SCHEME:
	case GF_ISOM_CBCS_SCHEME:
		if (ptr->offsets) gf_free(ptr->offsets);
		ptr->offsets = NULL;
		ptr->entry_alloc = 0;
		ptr->entry_count = 1;
		break;
	}

	ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE


void prft_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err prft_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;

	ISOM_DECREASE_SIZE(ptr, 12);
	ptr->refTrackID = gf_bs_read_u32(bs);
	ptr->ntp = gf_bs_read_u64(bs);
	if (ptr->version==0) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->timestamp = gf_bs_read_u32(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 8);
		ptr->timestamp = gf_bs_read_u64(bs);
	}
	return GF_OK;
}

GF_Box *prft_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err prft_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->refTrackID);
	gf_bs_write_u64(bs, ptr->ntp);
	if (ptr->version==0) {
		gf_bs_write_u32(bs, (u32) ptr->timestamp);
	} else {
		gf_bs_write_u64(bs, ptr->timestamp);
	}

	return GF_OK;
}

GF_Err prft_box_size(GF_Box *s)
{
	GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox*)s;

	ptr->size += 4+8+ (ptr->version ? 8 : 4);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *trgr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR);
	tmp->groups = gf_list_new();
	if (!tmp->groups) {
		gf_free(tmp);
		return NULL;
	}
	return (GF_Box *)tmp;
}

void trgr_box_del(GF_Box *s)
{
	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
	if (ptr == NULL) return;
	gf_list_del(ptr->groups);
	gf_free(ptr);
}


GF_Err trgr_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;

	BOX_FIELD_LIST_ASSIGN(groups)
	return GF_OK;
}


GF_Err trgr_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}


#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err trgr_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err trgr_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *) s;
	gf_isom_check_position_list(s, ptr->groups, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *trgt_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT);
	return (GF_Box *)tmp;
}

void trgt_box_del(GF_Box *s)
{
	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err trgt_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->track_group_id = gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err trgt_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *) s;
	if (!s) return GF_BAD_PARAM;
	if (ptr->group_type == GF_ISOM_BOX_TYPE_UUID) return GF_BAD_PARAM;
	s->type = ptr->group_type;
	e = gf_isom_full_box_write(s, bs);
	s->type = GF_ISOM_BOX_TYPE_TRGT;
	if (e) return e;
	gf_bs_write_u32(bs, ptr->track_group_id);
	return GF_OK;
}

GF_Err trgt_box_size(GF_Box *s)
{
	GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;

	ptr->size+= 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *stvi_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_StereoVideoBox, GF_ISOM_BOX_TYPE_STVI);
	return (GF_Box *)tmp;
}

void stvi_box_del(GF_Box *s)
{
	GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
	if (ptr == NULL) return;
	if (ptr->stereo_indication_type) gf_free(ptr->stereo_indication_type);
	gf_free(ptr);
}

GF_Err stvi_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;

	ISOM_DECREASE_SIZE(ptr, 12);
	gf_bs_read_int(bs, 30);
	ptr->single_view_allowed = gf_bs_read_int(bs, 2);
	ptr->stereo_scheme = gf_bs_read_u32(bs);
	ptr->sit_len = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, ptr->sit_len);

	ptr->stereo_indication_type = gf_malloc(sizeof(char)*ptr->sit_len);
	if (!ptr->stereo_indication_type) return GF_OUT_OF_MEM;

	gf_bs_read_data(bs, ptr->stereo_indication_type, ptr->sit_len);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err stvi_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_StereoVideoBox *ptr = (GF_StereoVideoBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, 0, 30);
	gf_bs_write_int(bs, ptr->single_view_allowed, 2);
	gf_bs_write_u32(bs, ptr->stereo_scheme);
	gf_bs_write_u32(bs, ptr->sit_len);
	gf_bs_write_data(bs, ptr->stereo_indication_type, ptr->sit_len);

	return GF_OK;
}

GF_Err stvi_box_size(GF_Box *s)
{
	GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;

	ptr->size+= 12 + ptr->sit_len;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *fiin_box_new()
{
	ISOM_DECL_BOX_ALLOC(FDItemInformationBox, GF_ISOM_BOX_TYPE_FIIN);
	return (GF_Box *)tmp;
}

void fiin_box_del(GF_Box *s)
{
	FDItemInformationBox *ptr = (FDItemInformationBox *)s;
	if (ptr == NULL) return;
	if (ptr->partition_entries) gf_list_del(ptr->partition_entries);
	gf_free(ptr);
}


GF_Err fiin_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	FDItemInformationBox *ptr = (FDItemInformationBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_PAEN:
		BOX_FIELD_LIST_ASSIGN(partition_entries)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_SEGR:
		BOX_FIELD_ASSIGN(session_info, FDSessionGroupBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_GITN:
		BOX_FIELD_ASSIGN(group_id_to_name, GroupIdToNameBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err fiin_box_read(GF_Box *s, GF_BitStream *bs)
{
	FDItemInformationBox *ptr = (FDItemInformationBox *)s;

	ISOM_DECREASE_SIZE(ptr, 2);
	gf_bs_read_u16(bs);
	return gf_isom_box_array_read(s, bs);
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err fiin_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	FDItemInformationBox *ptr = (FDItemInformationBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u16(bs, gf_list_count(ptr->partition_entries) );
	return GF_OK;
}

GF_Err fiin_box_size(GF_Box *s)
{
	u32 pos=0;
	FDItemInformationBox *ptr = (FDItemInformationBox *) s;
	s->size+= 2;
	gf_isom_check_position_list(s, ptr->partition_entries, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *paen_box_new()
{
	ISOM_DECL_BOX_ALLOC(FDPartitionEntryBox, GF_ISOM_BOX_TYPE_PAEN);
	return (GF_Box *)tmp;
}

void paen_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err paen_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_FPAR:
		BOX_FIELD_ASSIGN(blocks_and_symbols, FilePartitionBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_FECR:
		BOX_FIELD_ASSIGN(FEC_symbol_locations, FECReservoirBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_FIRE:
		BOX_FIELD_ASSIGN(File_symbol_locations, FileReservoirBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err paen_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err paen_box_write(GF_Box *s, GF_BitStream *bs)
{
	if (!s) return GF_BAD_PARAM;
	return gf_isom_box_write_header(s, bs);
}

GF_Err paen_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/




GF_Box *fpar_box_new()
{
	ISOM_DECL_BOX_ALLOC(FilePartitionBox, GF_ISOM_BOX_TYPE_FPAR);
	return (GF_Box *)tmp;
}

void fpar_box_del(GF_Box *s)
{
	FilePartitionBox *ptr = (FilePartitionBox *)s;
	if (ptr == NULL) return;
	if (ptr->scheme_specific_info) gf_free(ptr->scheme_specific_info);
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}

GF_Err gf_isom_read_null_terminated_string(GF_Box *s, GF_BitStream *bs, u64 size, char **out_str)
{
	u32 len=10;
	u32 i=0;

	*out_str = gf_malloc(sizeof(char)*len);
	if (! *out_str) return GF_OUT_OF_MEM;

	if (!s->size) {
		*out_str[0] = 0;
		return GF_OK;
	}

	while (1) {
		ISOM_DECREASE_SIZE(s, 1 );
		(*out_str)[i] = gf_bs_read_u8(bs);
		if (!(*out_str)[i]) break;
		i++;
		if (i==len) {
			len += 10;
			*out_str = gf_realloc(*out_str, sizeof(char)*len);
		}
		if (gf_bs_available(bs) == 0) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] missing null character in null terminated string\n"));
			(*out_str)[i] = 0;
			return GF_OK;
		}
		if (i >= size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] string bigger than container, probably missing null character\n"));
			(*out_str)[i] = 0;
			return GF_OK;
		}
	}
	return GF_OK;
}

GF_Err fpar_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	FilePartitionBox *ptr = (FilePartitionBox *)s;

	ISOM_DECREASE_SIZE(ptr, ((ptr->version ? 4 : 2) + 12) );
	ptr->itemID = gf_bs_read_int(bs, ptr->version ? 32 : 16);
	ptr->packet_payload_size = gf_bs_read_u16(bs);
	gf_bs_read_u8(bs);
	ptr->FEC_encoding_ID = gf_bs_read_u8(bs);
	ptr->FEC_instance_ID = gf_bs_read_u16(bs);
	ptr->max_source_block_length = gf_bs_read_u16(bs);
	ptr->encoding_symbol_length = gf_bs_read_u16(bs);
	ptr->max_number_of_encoding_symbols = gf_bs_read_u16(bs);

	e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_specific_info);
	if (e) return e;

	ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
	ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
	if (ptr->nb_entries > ptr->size / 6 || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(FilePartitionEntry))
		return GF_ISOM_INVALID_FILE;

	ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * 6 );
	GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FilePartitionEntry);
	if (!ptr->entries) return GF_OUT_OF_MEM;

	for (i=0;i < ptr->nb_entries; i++) {
		ptr->entries[i].block_count = gf_bs_read_u16(bs);
		ptr->entries[i].block_size = gf_bs_read_u32(bs);
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err fpar_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	FilePartitionBox *ptr = (FilePartitionBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, ptr->itemID, ptr->version ? 32 : 16);
	gf_bs_write_u16(bs, ptr->packet_payload_size);
	gf_bs_write_u8(bs, 0);
	gf_bs_write_u8(bs, ptr->FEC_encoding_ID);
	gf_bs_write_u16(bs, ptr->FEC_instance_ID);
	gf_bs_write_u16(bs, ptr->max_source_block_length);
	gf_bs_write_u16(bs, ptr->encoding_symbol_length);
	gf_bs_write_u16(bs, ptr->max_number_of_encoding_symbols);
	if (ptr->scheme_specific_info) {
		gf_bs_write_data(bs, ptr->scheme_specific_info, (u32)strlen(ptr->scheme_specific_info) );
	}
	//null terminated string
	gf_bs_write_u8(bs, 0);

	gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);

	for (i=0;i < ptr->nb_entries; i++) {
		gf_bs_write_u16(bs, ptr->entries[i].block_count);
		gf_bs_write_u32(bs, ptr->entries[i].block_size);
	}
	return GF_OK;
}

GF_Err fpar_box_size(GF_Box *s)
{
	FilePartitionBox *ptr = (FilePartitionBox *)s;

	ptr->size += 13 + (ptr->version ? 8 : 4);
	if (ptr->scheme_specific_info)
		ptr->size += strlen(ptr->scheme_specific_info);

	ptr->size+= ptr->nb_entries * 6;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *fecr_box_new()
{
	ISOM_DECL_BOX_ALLOC(FECReservoirBox, GF_ISOM_BOX_TYPE_FECR);
	return (GF_Box *)tmp;
}

void fecr_box_del(GF_Box *s)
{
	FECReservoirBox *ptr = (FECReservoirBox *)s;
	if (ptr == NULL) return;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}

GF_Err fecr_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	FECReservoirBox *ptr = (FECReservoirBox *)s;

	ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
	ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);

	if (ptr->nb_entries > ptr->size / (ptr->version ? 8 : 6) || (u64)ptr->nb_entries > (u64)SIZE_MAX/sizeof(FECReservoirEntry) ) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fecr\n", ptr->nb_entries));
		return GF_ISOM_INVALID_FILE;
	}

	ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * (ptr->version ? 8 : 6) );
	GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FECReservoirEntry);
	if (!ptr->entries) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->nb_entries; i++) {
		ptr->entries[i].item_id = gf_bs_read_int(bs, ptr->version ? 32 : 16);
		ptr->entries[i].symbol_count = gf_bs_read_u32(bs);
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err fecr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	FECReservoirBox *ptr = (FECReservoirBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
	for (i=0; i<ptr->nb_entries; i++) {
		gf_bs_write_int(bs, ptr->entries[i].item_id, ptr->version ? 32 : 16);
		gf_bs_write_u32(bs, ptr->entries[i].symbol_count);
	}
	return GF_OK;
}

GF_Err fecr_box_size(GF_Box *s)
{
	FECReservoirBox *ptr = (FECReservoirBox *)s;
	ptr->size += (ptr->version ? 4 : 2) +  ptr->nb_entries * (ptr->version ? 8 : 6);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *segr_box_new()
{
	ISOM_DECL_BOX_ALLOC(FDSessionGroupBox, GF_ISOM_BOX_TYPE_SEGR);
	return (GF_Box *)tmp;
}

void segr_box_del(GF_Box *s)
{
	u32 i;
	FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
	if (ptr == NULL) return;
	for (i=0; i<ptr->num_session_groups; i++) {
		if (ptr->session_groups[i].group_ids) gf_free(ptr->session_groups[i].group_ids);
		if (ptr->session_groups[i].channels) gf_free(ptr->session_groups[i].channels);
	}
	if (ptr->session_groups) gf_free(ptr->session_groups);
	gf_free(ptr);
}

GF_Err segr_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, k;
	FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;

	ISOM_DECREASE_SIZE(ptr, 2);
	ptr->num_session_groups = gf_bs_read_u16(bs);
	if (ptr->size < ptr->num_session_groups) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in segr\n", ptr->num_session_groups));
		ptr->num_session_groups = 0;
		return GF_ISOM_INVALID_FILE;
	}

	GF_SAFE_ALLOC_N(ptr->session_groups, ptr->num_session_groups, SessionGroupEntry);
	if (!ptr->session_groups) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->num_session_groups; i++) {
		ptr->session_groups[i].nb_groups = gf_bs_read_u8(bs);
		ISOM_DECREASE_SIZE(ptr, 1);

		ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_groups*4);

		GF_SAFE_ALLOC_N(ptr->session_groups[i].group_ids, ptr->session_groups[i].nb_groups, u32);
		if (!ptr->session_groups[i].group_ids) return GF_OUT_OF_MEM;

		for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
			ptr->session_groups[i].group_ids[k] = gf_bs_read_u32(bs);
		}

		ptr->session_groups[i].nb_channels = gf_bs_read_u16(bs);
		ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_channels*4);

		GF_SAFE_ALLOC_N(ptr->session_groups[i].channels, ptr->session_groups[i].nb_channels, u32);
		if (!ptr->session_groups[i].channels) return GF_OUT_OF_MEM;

		for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
			ptr->session_groups[i].channels[k] = gf_bs_read_u32(bs);
		}
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err segr_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i, k;
	GF_Err e;
	FDSessionGroupBox *ptr = (FDSessionGroupBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u16(bs, ptr->num_session_groups);
	for (i=0; i<ptr->num_session_groups; i++) {
		gf_bs_write_u8(bs, ptr->session_groups[i].nb_groups);
		for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
			gf_bs_write_u32(bs, ptr->session_groups[i].group_ids[k]);
		}

		gf_bs_write_u16(bs, ptr->session_groups[i].nb_channels);
		for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
			gf_bs_write_u32(bs, ptr->session_groups[i].channels[k]);
		}
	}
	return GF_OK;
}

GF_Err segr_box_size(GF_Box *s)
{
	u32 i;
	FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;

	ptr->size += 2;

	for (i=0; i<ptr->num_session_groups; i++) {
		ptr->size += 1 + 4*ptr->session_groups[i].nb_groups;
		ptr->size += 2 + 4*ptr->session_groups[i].nb_channels;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *gitn_box_new()
{
	ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN);
	return (GF_Box *)tmp;
}

void gitn_box_del(GF_Box *s)
{
	u32 i;
	GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
	if (ptr == NULL) return;
	if (ptr->entries) {
		for (i=0; i<ptr->nb_entries; i++) {
			if (ptr->entries[i].name) gf_free(ptr->entries[i].name);
		}
		gf_free(ptr->entries);
	}
	gf_free(ptr);
}

GF_Err gitn_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;

	ISOM_DECREASE_SIZE(ptr, 2);
	ptr->nb_entries = gf_bs_read_u16(bs);
	if (ptr->size / 4 < ptr->nb_entries)
		return GF_ISOM_INVALID_FILE;

	GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, GroupIdNameEntry);
	if (!ptr->entries) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->nb_entries; i++) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->entries[i].group_id = gf_bs_read_u32(bs);

		e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->entries[i].name);
		if (e) return e;
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err gitn_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GroupIdToNameBox *ptr = (GroupIdToNameBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u16(bs, ptr->nb_entries);
	for (i=0; i<ptr->nb_entries; i++) {
		gf_bs_write_u32(bs, ptr->entries[i].group_id);
		if (ptr->entries[i].name) gf_bs_write_data(bs, ptr->entries[i].name, (u32)strlen(ptr->entries[i].name) );
		gf_bs_write_u8(bs, 0);
	}
	return GF_OK;
}

GF_Err gitn_box_size(GF_Box *s)
{
	u32 i;
	GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
	ptr->size += 2;

	for (i=0; i<ptr->nb_entries; i++) {
		ptr->size += 5;
		if (ptr->entries[i].name) ptr->size += strlen(ptr->entries[i].name);
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#ifndef GPAC_DISABLE_ISOM_HINTING

GF_Box *fdpa_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_FDpacketBox, GF_ISOM_BOX_TYPE_FDPA);
	return (GF_Box *)tmp;
}

void fdpa_box_del(GF_Box *s)
{
	u32 i;
	GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
	if (ptr == NULL) return;

	if (ptr->headers) {
		for (i=0; i<ptr->header_ext_count; i++) {
			if (ptr->headers[i].data) gf_free(ptr->headers[i].data);
		}
		gf_free(ptr->headers);
	}
	gf_free(ptr);
}

GF_Err fdpa_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;

	ISOM_DECREASE_SIZE(ptr, 3);
	ptr->info.sender_current_time_present = gf_bs_read_int(bs, 1);
	ptr->info.expected_residual_time_present = gf_bs_read_int(bs, 1);
	ptr->info.session_close_bit = gf_bs_read_int(bs, 1);
	ptr->info.object_close_bit = gf_bs_read_int(bs, 1);
	gf_bs_read_int(bs, 4);
	ptr->info.transport_object_identifier = gf_bs_read_u16(bs);
	ISOM_DECREASE_SIZE(ptr, 2);
	ptr->header_ext_count = gf_bs_read_u16(bs);
	if (ptr->size / 2 < ptr->header_ext_count) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fdpa\n", ptr->header_ext_count));
		return GF_ISOM_INVALID_FILE;
	}

	GF_SAFE_ALLOC_N(ptr->headers, ptr->header_ext_count, GF_LCTheaderExtension);
	if (!ptr->headers) return GF_OUT_OF_MEM;

	for (i=0; i<ptr->header_ext_count; i++) {
		ptr->headers[i].header_extension_type = gf_bs_read_u8(bs);
		ISOM_DECREASE_SIZE(ptr, 1);

		if (ptr->headers[i].header_extension_type > 127) {
			ISOM_DECREASE_SIZE(ptr, 3);
			gf_bs_read_data(bs, (char *) ptr->headers[i].content, 3);
		} else {
			ISOM_DECREASE_SIZE(ptr, 1);
			ptr->headers[i].data_length = gf_bs_read_u8(bs);
			if (ptr->headers[i].data_length) {
				ptr->headers[i].data_length = 4*ptr->headers[i].data_length - 2;
				if (ptr->size < sizeof(char) * ptr->headers[i].data_length)
					return GF_ISOM_INVALID_FILE;
				ptr->headers[i].data = gf_malloc(sizeof(char) * ptr->headers[i].data_length);
				if (!ptr->headers[i].data) return GF_OUT_OF_MEM;

				ISOM_DECREASE_SIZE(ptr, ptr->headers[i].data_length);
				gf_bs_read_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
			}
		}
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err fdpa_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_FDpacketBox *ptr = (GF_FDpacketBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, ptr->info.sender_current_time_present, 1);
	gf_bs_write_int(bs, ptr->info.expected_residual_time_present, 1);
	gf_bs_write_int(bs, ptr->info.session_close_bit, 1);
	gf_bs_write_int(bs, ptr->info.object_close_bit, 1);
	gf_bs_write_int(bs, 0, 4);
	gf_bs_write_u16(bs, ptr->info.transport_object_identifier);
	gf_bs_write_u16(bs, ptr->header_ext_count);
	for (i=0; i<ptr->header_ext_count; i++) {
		gf_bs_write_u8(bs, ptr->headers[i].header_extension_type);
		if (ptr->headers[i].header_extension_type > 127) {
			gf_bs_write_data(bs, (const char *) ptr->headers[i].content, 3);
		} else {
			gf_bs_write_u8(bs, ptr->headers[i].data_length ? (ptr->headers[i].data_length+2)/4 : 0);
			if (ptr->headers[i].data_length) {
				gf_bs_write_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
			}
		}
	}
	return GF_OK;
}

GF_Err fdpa_box_size(GF_Box *s)
{
	u32 i;
	GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;

	ptr->size += 5;

	for (i=0; i<ptr->header_ext_count; i++) {
		ptr->size += 1;
		if (ptr->headers[i].header_extension_type > 127) {
			ptr->size += 3;
		} else {
			ptr->size += 1 + ptr->headers[i].data_length;
		}
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *extr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ExtraDataBox, GF_ISOM_BOX_TYPE_EXTR);
	return (GF_Box *)tmp;
}

void extr_box_del(GF_Box *s)
{
	GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
	if (ptr == NULL) return;
	if (ptr->feci) gf_isom_box_del((GF_Box*)ptr->feci);
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}

GF_Err extr_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;

	e = gf_isom_box_parse_ex((GF_Box**) &ptr->feci, bs, GF_ISOM_BOX_TYPE_EXTR, GF_FALSE, ptr->size);
	if (e) return e;
	if (!ptr->feci || ptr->feci->size > ptr->size) return GF_ISOM_INVALID_MEDIA;
	ptr->data_length = (u32) (ptr->size - ptr->feci->size);
	ptr->data = gf_malloc(sizeof(char)*ptr->data_length);
	if (!ptr->data) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->data, ptr->data_length);

	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err extr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	if (ptr->feci) {
		e = gf_isom_box_write((GF_Box *)ptr->feci, bs);
		if (e) return e;
	}
	gf_bs_write_data(bs, ptr->data, ptr->data_length);
	return GF_OK;
}

GF_Err extr_box_size(GF_Box *s)
{
	GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
	ptr->size += ptr->data_length;
	if (ptr->feci) {
		GF_Err e = gf_isom_box_size((GF_Box*)ptr->feci);
		if (e) return e;
		ptr->size += ptr->feci->size;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *fdsa_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_HintSample, GF_ISOM_BOX_TYPE_FDSA);
	if (!tmp) return NULL;
	tmp->packetTable = gf_list_new();
	tmp->hint_subtype = GF_ISOM_BOX_TYPE_FDP_STSD;
	return (GF_Box*)tmp;
}

void fdsa_box_del(GF_Box *s)
{
	GF_HintSample *ptr = (GF_HintSample *)s;
	gf_list_del(ptr->packetTable);
	gf_free(ptr);
}

GF_Err fdsa_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_HintSample *ptr = (GF_HintSample *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_FDPA:
		BOX_FIELD_LIST_ASSIGN(packetTable)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_EXTR:
		BOX_FIELD_ASSIGN(extra_data, GF_ExtraDataBox)
		break;
	}
	return GF_OK;
}
GF_Err fdsa_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err fdsa_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_HintSample *ptr = (GF_HintSample *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	e = gf_isom_box_array_write(s, ptr->packetTable, bs);
	if (e) return e;
	if (ptr->extra_data) {
		e = gf_isom_box_write((GF_Box *)ptr->extra_data, bs);
		if (e) return e;
	}
	return GF_OK;
}

GF_Err fdsa_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

#endif /*GPAC_DISABLE_ISOM_HINTING*/


void trik_box_del(GF_Box *s)
{
	GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
	if (ptr == NULL) return;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}

GF_Err trik_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
	ptr->entry_count = (u32) ptr->size;
	if ((u64)ptr->entry_count > (u64)SIZE_MAX/sizeof(GF_TrickPlayBoxEntry)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in trik\n", ptr->size));
		return GF_ISOM_INVALID_FILE;
	}
	ptr->entries = (GF_TrickPlayBoxEntry *) gf_malloc(ptr->entry_count * sizeof(GF_TrickPlayBoxEntry) );
	if (!ptr->entries) return GF_OUT_OF_MEM;

	for (i=0; i< ptr->entry_count; i++) {
		ptr->entries[i].pic_type = gf_bs_read_int(bs, 2);
		ptr->entries[i].dependency_level = gf_bs_read_int(bs, 6);
	}
	return GF_OK;
}

GF_Box *trik_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrickPlayBox, GF_ISOM_BOX_TYPE_TRIK);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err trik_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	for (i=0; i < ptr->entry_count; i++ ) {
		gf_bs_write_int(bs, ptr->entries[i].pic_type, 2);
		gf_bs_write_int(bs, ptr->entries[i].dependency_level, 6);
	}
	return GF_OK;
}

GF_Err trik_box_size(GF_Box *s)
{
	GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
	ptr->size += 8 * ptr->entry_count;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void bloc_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err bloc_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;

	ISOM_DECREASE_SIZE(s, 256)
	gf_bs_read_data(bs, (char *) ptr->baseLocation, 256);
	ptr->baseLocation[256]=0;
	ISOM_DECREASE_SIZE(s, 256)
	gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256);
	ISOM_DECREASE_SIZE(s, 512)
	ptr->basePurlLocation[256]=0;
	gf_bs_skip_bytes(bs, 512);
	return GF_OK;
}

GF_Box *bloc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_BaseLocationBox, GF_ISOM_BOX_TYPE_BLOC);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err bloc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, (const char *) ptr->baseLocation, 256);
	gf_bs_write_data(bs, (const char *) ptr->basePurlLocation, 256);
	for (i=0; i < 64; i++ ) {
		gf_bs_write_u64(bs, 0);
	}
	return GF_OK;
}

GF_Err bloc_box_size(GF_Box *s)
{
	s->size += 1024;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ainf_box_del(GF_Box *s)
{
	GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
	if (ptr->APID) gf_free(ptr->APID);
	gf_free(s);
}

GF_Err ainf_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;

	ISOM_DECREASE_SIZE(s, 4)
	ptr->profile_version = gf_bs_read_u32(bs);
	return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->APID);
}

GF_Box *ainf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AssetInformationBox, GF_ISOM_BOX_TYPE_AINF);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ainf_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->profile_version);
	if (ptr->APID)
		gf_bs_write_data(bs, ptr->APID, (u32) strlen(ptr->APID) );
	gf_bs_write_u8(bs, 0);
	return GF_OK;
}

GF_Err ainf_box_size(GF_Box *s)
{
	GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
	s->size += 4 + (ptr->APID ? strlen(ptr->APID) : 0 ) + 1;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void mhac_box_del(GF_Box *s)
{
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
	if (ptr->mha_config) gf_free(ptr->mha_config);
	gf_free(s);
}

GF_Err mhac_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;

	ISOM_DECREASE_SIZE(s, 5)
	ptr->configuration_version = gf_bs_read_u8(bs);
	ptr->mha_pl_indication = gf_bs_read_u8(bs);
	ptr->reference_channel_layout = gf_bs_read_u8(bs);
	ptr->mha_config_size = gf_bs_read_u16(bs);
	if (ptr->mha_config_size) {
		ISOM_DECREASE_SIZE(s, ptr->mha_config_size)

		ptr->mha_config = gf_malloc(sizeof(char)*ptr->mha_config_size);
		if (!ptr->mha_config) return GF_OUT_OF_MEM;

		gf_bs_read_data(bs, ptr->mha_config, ptr->mha_config_size);
	}
	return GF_OK;
}

GF_Box *mhac_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MHAConfigBox, GF_ISOM_BOX_TYPE_MHAC);
	tmp->configuration_version = 1;
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mhac_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->configuration_version);
	gf_bs_write_u8(bs, ptr->mha_pl_indication);
	gf_bs_write_u8(bs, ptr->reference_channel_layout);
	gf_bs_write_u16(bs, ptr->mha_config ? ptr->mha_config_size : 0);
	if (ptr->mha_config && ptr->mha_config_size)
		gf_bs_write_data(bs, ptr->mha_config, ptr->mha_config_size);

	return GF_OK;
}

GF_Err mhac_box_size(GF_Box *s)
{
	GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s;
	s->size += 5;
	if (ptr->mha_config_size && ptr->mha_config) s->size += ptr->mha_config_size;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void mhap_box_del(GF_Box *s)
{
	GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
	if (ptr->compat_profiles) gf_free(ptr->compat_profiles);
	gf_free(s);
}

GF_Err mhap_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;

	ISOM_DECREASE_SIZE(s, 1)
	ptr->num_profiles = gf_bs_read_u8(bs);
	if (!ptr->num_profiles) return GF_OK;

	ISOM_DECREASE_SIZE(s, ptr->num_profiles)
	ptr->compat_profiles = gf_malloc(sizeof(u8) * ptr->num_profiles);
	if (!ptr->compat_profiles) return GF_OUT_OF_MEM;
	for (i=0; i<ptr->num_profiles; i++) {
		ptr->compat_profiles[i] = gf_bs_read_u8(bs);
	}
	return GF_OK;
}

GF_Box *mhap_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MHACompatibleProfilesBox, GF_ISOM_BOX_TYPE_MHAP);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mhap_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->num_profiles);
	for (i=0; i<ptr->num_profiles; i++) {
		gf_bs_write_u8(bs, ptr->compat_profiles[i]);
	}
	return GF_OK;
}

GF_Err mhap_box_size(GF_Box *s)
{
	GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
	s->size += 1 + ptr->num_profiles;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *jp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_JP2SignatureBox, GF_ISOM_BOX_TYPE_JP);
	return (GF_Box *)tmp;
}

void jp_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err jp_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_JP2SignatureBox *ptr = (GF_JP2SignatureBox *) s;
	ISOM_DECREASE_SIZE(s, 4)
	ptr->signature = gf_bs_read_u32(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err jp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_JP2SignatureBox *ptr = (GF_JP2SignatureBox *) s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->signature);
	return GF_OK;
}

GF_Err jp_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void jp2h_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err jp2h_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_J2KHeaderBox *ptr = (GF_J2KHeaderBox *)s;
	switch(a->type) {
	case GF_ISOM_BOX_TYPE_IHDR:
		BOX_FIELD_ASSIGN(ihdr, GF_J2KImageHeaderBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_COLR:
		BOX_FIELD_ASSIGN(colr, GF_ColourInformationBox)
		return GF_OK;
	}
	return GF_OK;
}
GF_Err jp2h_box_read(GF_Box *s,GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

GF_Box *jp2h_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_J2KHeaderBox, GF_ISOM_BOX_TYPE_JP2H);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err jp2h_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err jp2h_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *jp2p_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_JP2ProfileBox, GF_ISOM_BOX_TYPE_JP2P);
	tmp->compatible_brands = gf_list_new();
	return (GF_Box *)tmp;
}

void jp2p_box_del(GF_Box *s)
{
	GF_JP2ProfileBox *ptr = (GF_JP2ProfileBox *) s;
	u32 i, count = gf_list_count(ptr->compatible_brands);
	for (i=0; i<count; i++) {
		u32 *brand = (u32 *)gf_list_get(ptr->compatible_brands, i);
		gf_free(brand);
	}
	gf_list_del(ptr->compatible_brands);
	gf_free(s);
}

GF_Err jp2p_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_JP2ProfileBox *ptr = (GF_JP2ProfileBox *) s;
	while (ptr->size) {
		ISOM_DECREASE_SIZE_NO_ERR(s, 4)
		u32 *brand = (u32 *)gf_malloc(sizeof(u32));
		if (!brand) return GF_OUT_OF_MEM;
		*brand = gf_bs_read_u32(bs);
		if (gf_list_add(ptr->compatible_brands, brand) != GF_OK)
			return GF_OUT_OF_MEM;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err jp2p_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_JP2ProfileBox *ptr = (GF_JP2ProfileBox *) s;
	u32 i, count = gf_list_count(ptr->compatible_brands);

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	for (i=0; i<count; i++) {
		u32 *brand = (u32 *)gf_list_get(ptr->compatible_brands, i);
		gf_bs_write_u32(bs, *brand);
	}
	return GF_OK;
}

GF_Err jp2p_box_size(GF_Box *s)
{
	GF_JP2ProfileBox *ptr = (GF_JP2ProfileBox *) s;
	u32 count = gf_list_count(ptr->compatible_brands);
	s->size += 4 * count;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *jsub_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_JP2SubSamplingBox, GF_ISOM_BOX_TYPE_JSUB);
	return (GF_Box *)tmp;
}

void jsub_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err jsub_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_JP2SubSamplingBox *ptr = (GF_JP2SubSamplingBox *) s;
	ISOM_DECREASE_SIZE(s, 4)
	ptr->horizontal_sub = gf_bs_read_u8(bs);
	ptr->vertical_sub = gf_bs_read_u8(bs);
	ptr->horizontal_offset = gf_bs_read_u8(bs);
	ptr->vertical_offset = gf_bs_read_u8(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err jsub_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_JP2SubSamplingBox *ptr = (GF_JP2SubSamplingBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->horizontal_sub);
	gf_bs_write_u8(bs, ptr->vertical_sub);
	gf_bs_write_u8(bs, ptr->horizontal_offset);
	gf_bs_write_u8(bs, ptr->vertical_offset);

	return GF_OK;
}

GF_Err jsub_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *orfo_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_JP2OriginalFormatBox, GF_ISOM_BOX_TYPE_JSUB);
	return (GF_Box *)tmp;
}

void orfo_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err orfo_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_JP2OriginalFormatBox *ptr = (GF_JP2OriginalFormatBox *) s;
	ISOM_DECREASE_SIZE(s, 2)
	ptr->original_fieldcount = gf_bs_read_u8(bs);
	ptr->original_fieldorder = gf_bs_read_u8(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err orfo_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_JP2OriginalFormatBox *ptr = (GF_JP2OriginalFormatBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->original_fieldcount);
	gf_bs_write_u8(bs, ptr->original_fieldorder);

	return GF_OK;
}

GF_Err orfo_box_size(GF_Box *s)
{
	s->size += 2;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

void ihdr_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err ihdr_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;

	ISOM_DECREASE_SIZE(s, 14)

	ptr->height = gf_bs_read_u32(bs);
	ptr->width = gf_bs_read_u32(bs);
	ptr->nb_comp = gf_bs_read_u16(bs);
	ptr->bpc = gf_bs_read_u8(bs);
	ptr->Comp = gf_bs_read_u8(bs);
	ptr->UnkC = gf_bs_read_u8(bs);
	ptr->IPR = gf_bs_read_u8(bs);

	return GF_OK;
}

GF_Box *ihdr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_J2KImageHeaderBox, GF_ISOM_BOX_TYPE_IHDR);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ihdr_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->height);
	gf_bs_write_u32(bs, ptr->width);
	gf_bs_write_u16(bs, ptr->nb_comp);
	gf_bs_write_u8(bs, ptr->bpc);
	gf_bs_write_u8(bs, ptr->Comp);
	gf_bs_write_u8(bs, ptr->UnkC);
	gf_bs_write_u8(bs, ptr->IPR);
	return GF_OK;
}

GF_Err ihdr_box_size(GF_Box *s)
{
	s->size += 14;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


/* Dolby Vision */

GF_Box *dvcC_box_new()
{
	GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox));
	if (tmp == NULL) return NULL;
	memset(tmp, 0, sizeof(GF_DOVIConfigurationBox));
	tmp->type = GF_ISOM_BOX_TYPE_DVCC;
	return (GF_Box *)tmp;
}

void dvcC_box_del(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
	gf_free(ptr);
}

GF_Err dvcC_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;

	//GF_DOVIDecoderConfigurationRecord
	ISOM_DECREASE_SIZE(ptr, 24)
	ptr->DOVIConfig.dv_version_major = gf_bs_read_u8(bs);
	ptr->DOVIConfig.dv_version_minor = gf_bs_read_u8(bs);
	ptr->DOVIConfig.dv_profile = gf_bs_read_int(bs, 7);
	ptr->DOVIConfig.dv_level = gf_bs_read_int(bs, 6);
	ptr->DOVIConfig.rpu_present_flag = gf_bs_read_int(bs, 1);
	ptr->DOVIConfig.el_present_flag = gf_bs_read_int(bs, 1);
	ptr->DOVIConfig.bl_present_flag = gf_bs_read_int(bs, 1);
	ptr->DOVIConfig.dv_bl_signal_compatibility_id = gf_bs_read_int(bs, 4);
	ptr->DOVIConfig.dv_md_compression = gf_bs_read_int(bs, 2);
	for (i = 0; i < 10; i++) {
		ptr->DOVIConfig.dv_feature_flags[i] = gf_bs_read_int(bs, 1);
	}
	if (gf_bs_read_int(bs, 16) != 0)
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bits are not zero\n"));

	for (i = 0; i < 4; i++) {
		if (gf_bs_read_u32(bs) != 0) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bits are not zero\n"));
		}
	}
	switch (ptr->DOVIConfig.dv_bl_signal_compatibility_id) {
	case 0:
	case 1:
	case 2:
	case 4:
	case 6:
		break;
	default:
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC compatibility ID %d is not valid (only 0, 1, 2, 4 or 6 defined), patching to 0\n", ptr->DOVIConfig.dv_bl_signal_compatibility_id));
		ptr->DOVIConfig.dv_bl_signal_compatibility_id = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dvcC_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	//GF_DOVIDecoderConfigurationRecord
	gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_major);
	gf_bs_write_u8(bs,  ptr->DOVIConfig.dv_version_minor);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_profile, 7);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_level, 6);
	gf_bs_write_int(bs, ptr->DOVIConfig.rpu_present_flag, 1);
	gf_bs_write_int(bs, ptr->DOVIConfig.el_present_flag, 1);
	gf_bs_write_int(bs, ptr->DOVIConfig.bl_present_flag, 1);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_bl_signal_compatibility_id, 4);
	gf_bs_write_int(bs, ptr->DOVIConfig.dv_md_compression, 2);
	for (u32 i = 0; i < 10; i++) {
		gf_bs_write_int(bs, ptr->DOVIConfig.dv_feature_flags[i], 1);
	}
	gf_bs_write_int(bs, 0, 16);
	gf_bs_write_u32(bs, 0);
	gf_bs_write_u32(bs, 0);
	gf_bs_write_u32(bs, 0);
	gf_bs_write_u32(bs, 0);

	return GF_OK;
}

GF_Err dvcC_box_size(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;

	ptr->size += 24;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *dvvC_box_new()
{
	GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox));
	if (tmp == NULL) return NULL;
	memset(tmp, 0, sizeof(GF_DOVIConfigurationBox));
	tmp->type = GF_ISOM_BOX_TYPE_DVVC;
	return (GF_Box *)tmp;
}

void dvvC_box_del(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
	gf_free(ptr);
}

GF_Err dvvC_box_read(GF_Box *s, GF_BitStream *bs)
{
	return dvcC_box_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dvvC_box_write(GF_Box *s, GF_BitStream *bs)
{
	return dvcC_box_write(s, bs);
}

GF_Err dvvC_box_size(GF_Box *s)
{
	return dvcC_box_size(s);
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *dOps_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OpusSpecificBox, GF_ISOM_BOX_TYPE_DOPS);
	return (GF_Box *)tmp;
}

void dOps_box_del(GF_Box *s)
{
	GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
	if (ptr) gf_free(ptr);
}

//we don't use odf_opus_cfg read due to endianness
GF_Err dOps_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
	ptr->opcfg.version = gf_bs_read_u8(bs);
	if (ptr->opcfg.version) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[IsoMedia] Opus config version not 0 !\n", ptr->size));
		return GF_NOT_SUPPORTED;
	}
	//force version to 1 as used in ogg/opus
	ptr->opcfg.version = 1;
	ptr->opcfg.OutputChannelCount = gf_bs_read_u8(bs);
	ptr->opcfg.PreSkip = gf_bs_read_u16(bs);
	ptr->opcfg.InputSampleRate = gf_bs_read_u32(bs);
	ptr->opcfg.OutputGain = gf_bs_read_u16(bs);
	ptr->opcfg.ChannelMappingFamily = gf_bs_read_u8(bs);
	ISOM_DECREASE_SIZE(ptr, 11)
	if (ptr->size) {
		ISOM_DECREASE_SIZE(ptr, 2+ptr->opcfg.OutputChannelCount);
		ptr->opcfg.StreamCount = gf_bs_read_u8(bs);
		ptr->opcfg.CoupledCount = gf_bs_read_u8(bs);
		gf_bs_read_data(bs, (char *) ptr->opcfg.ChannelMapping, ptr->opcfg.OutputChannelCount);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

//we don't use odf_opus_cfg write due to endianness
GF_Err dOps_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	//we always write 0 - the version may also be set to 1 when fed from ffenc or opus+ogg
	gf_bs_write_u8(bs, /*ptr->opcfg.version*/ 0);
	gf_bs_write_u8(bs, ptr->opcfg.OutputChannelCount);
	gf_bs_write_u16(bs, ptr->opcfg.PreSkip);
	gf_bs_write_u32(bs, ptr->opcfg.InputSampleRate);
	gf_bs_write_u16(bs, ptr->opcfg.OutputGain);
	gf_bs_write_u8(bs, ptr->opcfg.ChannelMappingFamily);
	if (ptr->opcfg.ChannelMappingFamily) {
		gf_bs_write_u8(bs, ptr->opcfg.StreamCount);
		gf_bs_write_u8(bs, ptr->opcfg.CoupledCount);
		gf_bs_write_data(bs, (char *) ptr->opcfg.ChannelMapping, ptr->opcfg.OutputChannelCount);
	}
	return GF_OK;
}

GF_Err dOps_box_size(GF_Box *s)
{
	GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
	ptr->size += 11;
	if (ptr->opcfg.ChannelMappingFamily)
		ptr->size += 2 + ptr->opcfg.OutputChannelCount;

	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *iacb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_IAConfigurationBox, GF_ISOM_BOX_TYPE_IACB);
	return (GF_Box *)tmp;
}

void iacb_box_del(GF_Box *s)
{
	GF_IAConfigurationBox *ptr = (GF_IAConfigurationBox *)s;
	if (ptr->cfg) gf_odf_iamf_cfg_del(ptr->cfg);
	gf_free(ptr);
}

GF_Err iacb_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_IAConfigurationBox *ptr = (GF_IAConfigurationBox *)s;
	if (ptr->cfg) gf_odf_iamf_cfg_del(ptr->cfg);
	ptr->cfg = gf_odf_iamf_cfg_read_bs_size(bs, (u32)ptr->size);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err iacb_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_IAConfigurationBox *ptr = (GF_IAConfigurationBox *)s;
	if (!s) return GF_BAD_PARAM;
	if (!ptr->cfg) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	return gf_odf_iamf_cfg_write_bs(ptr->cfg, bs);
}

GF_Err iacb_box_size(GF_Box *s)
{
		GF_IAConfigurationBox *ptr = (GF_IAConfigurationBox *)s;
		if (!ptr->cfg) {
		ptr->size = 0;
		return GF_BAD_PARAM;
		}
		ptr->size += gf_odf_iamf_cfg_size(ptr->cfg);
		return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

void dfla_box_del(GF_Box *s)
{
	GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
	if (ptr->data) gf_free(ptr->data);
	gf_free(ptr);
}

GF_Err dfla_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
	ptr->dataSize = (u32) ptr->size;
	ptr->size=0;
	ptr->data = gf_malloc(ptr->dataSize);
	gf_bs_read_data(bs, ptr->data, ptr->dataSize);
	return GF_OK;
}

GF_Box *dfla_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_FLACConfigBox, GF_ISOM_BOX_TYPE_DFLA);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dfla_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, ptr->data, ptr->dataSize);
	return GF_OK;
}

GF_Err dfla_box_size(GF_Box *s)
{
	GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s;
	ptr->size += ptr->dataSize;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *ddts_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DTSSpecificBox, GF_ISOM_BOX_TYPE_DDTS);
	return (GF_Box *)tmp;
}

void ddts_box_del(GF_Box *s)
{
	GF_DTSSpecificBox *ptr = (GF_DTSSpecificBox *)s;
	if (ptr) gf_free(ptr);
}

GF_Err ddts_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_DTSSpecificBox *ptr = (GF_DTSSpecificBox *)s;
	ISOM_DECREASE_SIZE(ptr, 20);
	ptr->cfg.SamplingFrequency = gf_bs_read_u32(bs);
	ptr->cfg.MaxBitrate = gf_bs_read_u32(bs);
	ptr->cfg.AvgBitrate = gf_bs_read_u32(bs);
	ptr->cfg.SampleDepth = gf_bs_read_u8(bs);
	ptr->cfg.FrameDuration = gf_bs_read_int(bs, 2);
	ptr->cfg.StreamConstruction = gf_bs_read_int(bs, 5);
	ptr->cfg.CoreLFEPresent = gf_bs_read_int(bs, 1);
	ptr->cfg.CoreLayout = gf_bs_read_int(bs, 6);
	ptr->cfg.CoreSize = gf_bs_read_int(bs, 14);
	ptr->cfg.StereoDownmix = gf_bs_read_int(bs, 1);
	ptr->cfg.RepresentationType = gf_bs_read_int(bs, 3);
	ptr->cfg.ChannelLayout = gf_bs_read_u16(bs);
	ptr->cfg.MultiAssetFlag = gf_bs_read_int(bs, 1);
	ptr->cfg.LBRDurationMod = gf_bs_read_int(bs, 1);
	gf_bs_read_int(bs, 6); // ReservedBox flag and reserved bits
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err ddts_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_DTSSpecificBox *ptr = (GF_DTSSpecificBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->cfg.SamplingFrequency);
	gf_bs_write_u32(bs, ptr->cfg.MaxBitrate);
	gf_bs_write_u32(bs, ptr->cfg.AvgBitrate);
	gf_bs_write_u8(bs, ptr->cfg.SampleDepth);
	gf_bs_write_int(bs, ptr->cfg.FrameDuration, 2);
	gf_bs_write_int(bs, ptr->cfg.StreamConstruction, 5);
	gf_bs_write_int(bs, ptr->cfg.CoreLFEPresent, 1);
	gf_bs_write_int(bs, ptr->cfg.CoreLayout, 6);
	gf_bs_write_int(bs, ptr->cfg.CoreSize, 14);
	gf_bs_write_int(bs, ptr->cfg.StereoDownmix, 1);
	gf_bs_write_int(bs, ptr->cfg.RepresentationType, 3);
	gf_bs_write_u16(bs, ptr->cfg.ChannelLayout);
	gf_bs_write_int(bs, ptr->cfg.MultiAssetFlag, 1);
	gf_bs_write_int(bs, ptr->cfg.LBRDurationMod, 1);
	gf_bs_write_int(bs, 0, 6);  // ReservedBoxPresent and reserved bits
	return GF_OK;
}

GF_Err ddts_box_size(GF_Box *s)
{
	GF_DTSSpecificBox *ptr = (GF_DTSSpecificBox *)s;
	ptr->size += 20;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *udts_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_UDTSSpecificBox, GF_ISOM_BOX_TYPE_UDTS);
	return (GF_Box *)tmp;
}

void udts_box_del(GF_Box *s)
{
	GF_UDTSSpecificBox *ptr = (GF_UDTSSpecificBox *)s;
	if (ptr) {
		if (ptr->cfg.PresentationIDTagData) gf_free(ptr->cfg.PresentationIDTagData);
		if (ptr->cfg.ExpansionBoxData) gf_free(ptr->cfg.ExpansionBoxData);
		gf_free(ptr);
	}
}

GF_Err udts_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_UDTSSpecificBox *ptr = (GF_UDTSSpecificBox *)s;
	u32 i, bits;

	ISOM_DECREASE_SIZE(ptr, 6);
	ptr->cfg.DecoderProfileCode = gf_bs_read_int(bs, 6);
	ptr->cfg.FrameDurationCode = gf_bs_read_int(bs, 2);
	ptr->cfg.MaxPayloadCode = gf_bs_read_int(bs, 3);
	ptr->cfg.NumPresentationsCode = gf_bs_read_int(bs, 5);
	ptr->cfg.ChannelMask = gf_bs_read_u32(bs);

	//non-aligned syntax, count bits
	bits = 10;
	ptr->cfg.BaseSamplingFrequencyCode = gf_bs_read_int(bs, 1);
	ptr->cfg.SampleRateMod = gf_bs_read_int(bs, 2);
	ptr->cfg.RepresentationType = gf_bs_read_int(bs, 3);
	ptr->cfg.StreamIndex = gf_bs_read_int(bs, 3);
	ptr->cfg.ExpansionBoxPresent = gf_bs_read_int(bs, 1);
	ptr->cfg.PresentationIDTagDataSize = 0;

	for (i=0; i<=ptr->cfg.NumPresentationsCode; i++) {
		ptr->cfg.IDTagPresent[i] = gf_bs_read_int(bs, 1);
		bits++;
		ptr->cfg.PresentationIDTagDataSize += 16 * (ptr->cfg.IDTagPresent[i] != 0);
	}
	bits+= gf_bs_align(bs);
	bits/=8;
	ISOM_DECREASE_SIZE(ptr, bits);

	if (ptr->cfg.PresentationIDTagDataSize > 0) {
		ISOM_DECREASE_SIZE(ptr, ptr->cfg.PresentationIDTagDataSize);

		ptr->cfg.PresentationIDTagData = gf_realloc(ptr->cfg.PresentationIDTagData, ptr->cfg.PresentationIDTagDataSize);
		if (!ptr->cfg.PresentationIDTagData) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->cfg.PresentationIDTagData, ptr->cfg.PresentationIDTagDataSize);
	}
	//leftover
	if (ptr->size && ptr->cfg.ExpansionBoxPresent) {
		ptr->cfg.ExpansionBoxDataSize = (u32) ptr->size;
		ISOM_DECREASE_SIZE(ptr, ptr->cfg.ExpansionBoxDataSize);
		ptr->cfg.ExpansionBoxData = gf_realloc(ptr->cfg.ExpansionBoxData, ptr->cfg.ExpansionBoxDataSize);
		if (!ptr->cfg.ExpansionBoxData) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->cfg.ExpansionBoxData, ptr->cfg.ExpansionBoxDataSize);
	} else {
		ptr->cfg.ExpansionBoxPresent = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err udts_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_UDTSSpecificBox *ptr = (GF_UDTSSpecificBox *)s;
	u8 i;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, ptr->cfg.DecoderProfileCode, 6);
	gf_bs_write_int(bs, ptr->cfg.FrameDurationCode, 2);
	gf_bs_write_int(bs, ptr->cfg.MaxPayloadCode, 3);
	gf_bs_write_int(bs, ptr->cfg.NumPresentationsCode, 5);
	gf_bs_write_u32(bs, ptr->cfg.ChannelMask);
	gf_bs_write_int(bs, ptr->cfg.BaseSamplingFrequencyCode, 1);
	gf_bs_write_int(bs, ptr->cfg.SampleRateMod, 2);
	gf_bs_write_int(bs, ptr->cfg.RepresentationType, 3);
	gf_bs_write_int(bs, ptr->cfg.StreamIndex, 3);
	gf_bs_write_int(bs, ptr->cfg.ExpansionBoxPresent, 1);
	for (i=0; i<=ptr->cfg.NumPresentationsCode; i++)
		gf_bs_write_int(bs, ptr->cfg.IDTagPresent[i], 1);
	gf_bs_align(bs);
	if (ptr->cfg.PresentationIDTagData && ptr->cfg.PresentationIDTagDataSize)
		gf_bs_write_data(bs, ptr->cfg.PresentationIDTagData, ptr->cfg.PresentationIDTagDataSize);
	if (ptr->cfg.ExpansionBoxData && ptr->cfg.ExpansionBoxDataSize)
		gf_bs_write_data(bs, ptr->cfg.ExpansionBoxData, ptr->cfg.ExpansionBoxDataSize);
	return GF_OK;
}

GF_Err udts_box_size(GF_Box *s)
{
	GF_UDTSSpecificBox *ptr = (GF_UDTSSpecificBox *)s;
	u32 bits = 58 + ptr->cfg.NumPresentationsCode + 1;  // 58 bits for fixed fields
	ptr->size += (bits + 7) / 8;  // align to next byte
	ptr->size += ptr->cfg.PresentationIDTagDataSize + ptr->cfg.ExpansionBoxDataSize;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void mvcg_box_del(GF_Box *s)
{
	GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
	if (ptr->entries) gf_free(ptr->entries);
	gf_free(ptr);
}

GF_Err mvcg_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
	ISOM_DECREASE_SIZE(s, 7)
	ptr->multiview_group_id = gf_bs_read_u32(bs);
	ptr->num_entries = gf_bs_read_u16(bs);
	gf_bs_read_u8(bs);
	ptr->entries = gf_malloc(ptr->num_entries * sizeof(MVCIEntry));
	if (!ptr->entries) return GF_OUT_OF_MEM;
	memset(ptr->entries, 0, ptr->num_entries * sizeof(MVCIEntry));
	for (i=0; i<ptr->num_entries; i++) {
		ISOM_DECREASE_SIZE(s, 1)
		ptr->entries[i].entry_type = gf_bs_read_u8(bs);
		switch (ptr->entries[i].entry_type) {
		case 0:
			ISOM_DECREASE_SIZE(s, 4)
			ptr->entries[i].trackID = gf_bs_read_u32(bs);
			break;
		case 1:
			ISOM_DECREASE_SIZE(s, 6)
			ptr->entries[i].trackID = gf_bs_read_u32(bs);
			ptr->entries[i].tierID = gf_bs_read_u16(bs);
			break;
		case 2:
			ISOM_DECREASE_SIZE(s, 2)
			gf_bs_read_int(bs, 6);
			ptr->entries[i].output_view_id = gf_bs_read_int(bs, 10);
			break;
		case 3:
			ISOM_DECREASE_SIZE(s, 4)
			gf_bs_read_int(bs, 6)	;
			ptr->entries[i].start_view_id = gf_bs_read_int(bs, 10);
			ptr->entries[i].view_count = gf_bs_read_u16(bs);
			break;
		}
	}
	return gf_isom_box_array_read(s, bs);
}

GF_Box *mvcg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MultiviewGroupBox, GF_ISOM_BOX_TYPE_MVCG);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err mvcg_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;


	gf_bs_write_u32(bs, ptr->multiview_group_id);
	gf_bs_write_u16(bs, ptr->num_entries);
	gf_bs_write_u8(bs, 0);

	for (i=0; i<ptr->num_entries; i++) {
		gf_bs_write_u8(bs, ptr->entries[i].entry_type);
		switch (ptr->entries[i].entry_type) {
		case 0:
			gf_bs_write_u32(bs, ptr->entries[i].trackID);
			break;
		case 1:
			gf_bs_write_u32(bs, ptr->entries[i].trackID);
			gf_bs_write_u16(bs, ptr->entries[i].tierID);
			break;
		case 2:
			gf_bs_write_int(bs, 0, 6);
			gf_bs_write_int(bs, ptr->entries[i].output_view_id, 10);
			break;
		case 3:
			gf_bs_write_int(bs, 0, 6)	;
			gf_bs_write_int(bs, ptr->entries[i].start_view_id, 10);
			gf_bs_write_u16(bs, ptr->entries[i].view_count);
			break;
		}
	}
	return GF_OK;
}

GF_Err mvcg_box_size(GF_Box *s)
{
	u32 i;
	GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s;

	ptr->size += 7;
	for (i=0; i<ptr->num_entries; i++) {
		switch (ptr->entries[i].entry_type) {
		case 0:
			ptr->size += 1 + 4;
			break;
		case 1:
			ptr->size += 1 + 6;
			break;
		case 2:
			ptr->size += 1 + 2;
			break;
		case 3:
			ptr->size += 1 + 4;
			break;
		}
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void vwid_box_del(GF_Box *s)
{
	u32 i;
	GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
	if (ptr->views) {
		for (i=0; i<ptr->num_views; i++) {
			if (ptr->views[i].view_refs)
				gf_free(ptr->views[i].view_refs);
		}
		gf_free(ptr->views);
	}
	gf_free(ptr);
}

GF_Err vwid_box_read(GF_Box *s,GF_BitStream *bs)
{
	u32 i;
	GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
	ISOM_DECREASE_SIZE(s, 3)
	gf_bs_read_int(bs, 2);
	ptr->min_temporal_id = gf_bs_read_int(bs, 3);
	ptr->max_temporal_id = gf_bs_read_int(bs, 3);
	ptr->num_views = gf_bs_read_u16(bs);
	if (ptr->num_views > ptr->size / 6)
		return GF_ISOM_INVALID_FILE;

	ptr->views = gf_malloc(sizeof(ViewIDEntry)*ptr->num_views);
	memset(ptr->views, 0, sizeof(ViewIDEntry)*ptr->num_views);
	for (i=0; i<ptr->num_views; i++) {
		u32 j;
		ISOM_DECREASE_SIZE(s, 6)

		gf_bs_read_int(bs, 6);
		ptr->views[i].view_id = gf_bs_read_int(bs, 10);
		gf_bs_read_int(bs, 6);
		ptr->views[i].view_order_index = gf_bs_read_int(bs, 10);
		ptr->views[i].texture_in_stream = gf_bs_read_int(bs, 1);
		ptr->views[i].texture_in_track = gf_bs_read_int(bs, 1);
		ptr->views[i].depth_in_stream = gf_bs_read_int(bs, 1);
		ptr->views[i].depth_in_track = gf_bs_read_int(bs, 1);
		ptr->views[i].base_view_type = gf_bs_read_int(bs, 2);
		ptr->views[i].num_ref_views = gf_bs_read_int(bs, 10);

		if (ptr->views[i].num_ref_views > ptr->size / 2)
			return GF_ISOM_INVALID_FILE;

		ptr->views[i].view_refs = gf_malloc(sizeof(ViewIDRefViewEntry)*ptr->views[i].num_ref_views);
		for (j=0; j<ptr->views[i].num_ref_views; j++) {
			ISOM_DECREASE_SIZE(s, 2)
			gf_bs_read_int(bs, 4);
			ptr->views[i].view_refs[j].dep_comp_idc = gf_bs_read_int(bs, 2);
			ptr->views[i].view_refs[j].ref_view_id = gf_bs_read_int(bs, 10);
		}
	}
	return GF_OK;
}

GF_Box *vwid_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ViewIdentifierBox, GF_ISOM_BOX_TYPE_VWID);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err vwid_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i, j;
	GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_int(bs, 0, 2);
	gf_bs_write_int(bs, ptr->min_temporal_id, 3);
	gf_bs_write_int(bs, ptr->max_temporal_id, 3);
	gf_bs_write_u16(bs, ptr->num_views);

	for (i=0; i<ptr->num_views; i++) {
		gf_bs_write_int(bs, 0, 6);
		gf_bs_write_int(bs, ptr->views[i].view_id, 10);
		gf_bs_write_int(bs, 0, 6);
		gf_bs_write_int(bs, ptr->views[i].view_order_index, 10);

		gf_bs_write_int(bs, ptr->views[i].texture_in_stream, 1);
		gf_bs_write_int(bs, ptr->views[i].texture_in_track, 1);
		gf_bs_write_int(bs, ptr->views[i].depth_in_stream, 1);
		gf_bs_write_int(bs, ptr->views[i].depth_in_track, 1);
		gf_bs_write_int(bs, ptr->views[i].base_view_type, 2);
		gf_bs_write_int(bs, ptr->views[i].num_ref_views, 10);

		for (j=0; j<ptr->views[i].num_ref_views; j++) {
			gf_bs_write_int(bs, 0, 4);
			gf_bs_write_int(bs, ptr->views[i].view_refs[j].dep_comp_idc, 2);
			gf_bs_write_int(bs, ptr->views[i].view_refs[j].ref_view_id, 10);
		}
	}
	return GF_OK;
}

GF_Err vwid_box_size(GF_Box *s)
{
	u32 i;
	GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s;
	ptr->size += 3;
	for (i=0; i<ptr->num_views; i++) {
		ptr->size += 6 + 2 * ptr->views[i].num_ref_views;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void pcmC_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err pcmC_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;

	ISOM_DECREASE_SIZE(s, 2)
	ptr->format_flags = gf_bs_read_u8(bs);
	ptr->PCM_sample_size = gf_bs_read_u8(bs);
	return GF_OK;
}

GF_Box *pcmC_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PCMConfigBox, GF_ISOM_BOX_TYPE_PCMC);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err pcmC_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->format_flags);
	gf_bs_write_u8(bs, ptr->PCM_sample_size);
	return GF_OK;
}

GF_Err pcmC_box_size(GF_Box *s)
{
	s->size += 2;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



void chnl_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;

	ISOM_DECREASE_SIZE(s, 1)
	if (ptr->version==0) {
		ptr->layout.stream_structure = gf_bs_read_u8(bs);
	} else {
		ptr->layout.stream_structure = gf_bs_read_int(bs, 4);
		ptr->layout.format_ordering = gf_bs_read_int(bs, 4);
		ISOM_DECREASE_SIZE(s, 1)
		ptr->layout.base_channel_count = gf_bs_read_u8(bs);
	}
	if (ptr->layout.stream_structure & 1) {
		ISOM_DECREASE_SIZE(s, 1)
		ptr->layout.definedLayout = gf_bs_read_u8(bs);
		if (ptr->layout.definedLayout==0) {
			u32 remain = (u32) ptr->size;
			if (ptr->layout.stream_structure & 2) remain--;
			ptr->layout.channels_count = 0;
			u32 nb_channels = 0;
			if (ptr->version) {
				ISOM_DECREASE_SIZE(s, 1)
				nb_channels = gf_bs_read_u8(bs);
			}
			while (remain) {
				if (ptr->layout.channels_count==64) return GF_ISOM_INVALID_FILE;

				ISOM_DECREASE_SIZE(s, 1)
				ptr->layout.layouts[ptr->layout.channels_count].position = gf_bs_read_u8(bs);
				remain--;
				if (ptr->layout.layouts[ptr->layout.channels_count].position == 126) {
					ISOM_DECREASE_SIZE(s, 3)
					ptr->layout.layouts[ptr->layout.channels_count].azimuth = gf_bs_read_int(bs, 16);
					ptr->layout.layouts[ptr->layout.channels_count].elevation = gf_bs_read_int(bs, 8);
					remain-=3;
				}
				ptr->layout.channels_count++;
				if (ptr->version) {
					nb_channels--;
					if (!nb_channels) break;
				}
			}
		} else {
			if (ptr->version==0) {
				ISOM_DECREASE_SIZE(s, 8)
				ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
				ptr->layout.omitted_channels_present = 1;
				ptr->layout.channel_order_definition = 0;
			} else {
				ISOM_DECREASE_SIZE(s, 1)
				gf_bs_read_int(bs, 4);
				ptr->layout.channel_order_definition = gf_bs_read_int(bs, 3);
				ptr->layout.omitted_channels_present = gf_bs_read_int(bs, 1);
				if (ptr->layout.omitted_channels_present) {
					ISOM_DECREASE_SIZE(s, 8)
					ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
				}
			}
		}
	}
	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
		ISOM_DECREASE_SIZE(s, 1)
		ptr->layout.object_count = gf_bs_read_u8(bs);
	}
	return GF_OK;
}

GF_Box *chnl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutBox, GF_ISOM_BOX_TYPE_CHNL);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->version==0) {
		gf_bs_write_u8(bs, ptr->layout.stream_structure);
	} else {
		gf_bs_write_int(bs, ptr->layout.stream_structure, 4);
		gf_bs_write_int(bs, ptr->layout.format_ordering, 4);
		gf_bs_write_u8(bs, ptr->layout.base_channel_count);
	}
	if (ptr->layout.stream_structure & 1) {
		gf_bs_write_u8(bs, ptr->layout.definedLayout);
		if (ptr->layout.definedLayout==0) {
			u32 i;
			if (ptr->version==1) {
				gf_bs_write_u8(bs, ptr->layout.channels_count);
			}
			for (i=0; i<ptr->layout.channels_count; i++) {
				gf_bs_write_u8(bs, ptr->layout.layouts[i].position);
				if (ptr->layout.layouts[i].position==126) {
					gf_bs_write_int(bs, ptr->layout.layouts[i].azimuth, 16);
					gf_bs_write_int(bs, ptr->layout.layouts[i].elevation, 8);
				}
			}
		} else {
			if (ptr->version==1) {
				gf_bs_write_int(bs, 0, 4);
				gf_bs_write_int(bs, ptr->layout.channel_order_definition, 3);
				gf_bs_write_int(bs, ptr->layout.omitted_channels_present, 1);
				if (ptr->layout.omitted_channels_present)
					gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
			} else {
				gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
			}
		}
	}
	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
		gf_bs_write_u8(bs, ptr->layout.object_count);
	}
	return GF_OK;
}

GF_Err chnl_box_size(GF_Box *s)
{
	GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
	s->size += 1;
	if (ptr->version==1) s->size++;
	if (ptr->layout.stream_structure & 1) {
		s->size += 1;
		if (ptr->layout.definedLayout==0) {
			u32 i;
			if (ptr->version==1) s->size++;
			for (i=0; i<ptr->layout.channels_count; i++) {
				s->size+=1;
				if (ptr->layout.layouts[i].position==126)
					s->size+=3;
			}
		} else {
			if (ptr->version==1) {
				s->size += 1;
				if (ptr->layout.omitted_channels_present)
					s->size += 8;
			} else {
				s->size += 8;
			}
		}
	}
	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
		s->size += 1;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *emsg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMSG);
	return (GF_Box *)tmp;
}

void emsg_box_del(GF_Box *s)
{
	GF_EventMessageBox *ptr = (GF_EventMessageBox *) s;
	if (ptr == NULL) return;
	if (ptr->scheme_id_uri) gf_free(ptr->scheme_id_uri);
	if (ptr->value) gf_free(ptr->value);
	if (ptr->message_data) gf_free(ptr->message_data);
	gf_free(ptr);
}

GF_Err emsg_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_Err e;
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;

	if (ptr->version==0) {
		e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
		if (e) return e;
		e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
		if (e) return e;

		ISOM_DECREASE_SIZE(ptr, 16);
		ptr->timescale = gf_bs_read_u32(bs);
		ptr->presentation_time_delta = gf_bs_read_u32(bs);
		ptr->event_duration = gf_bs_read_u32(bs);
		ptr->event_id = gf_bs_read_u32(bs);
	} else if (ptr->version==1) {
		ISOM_DECREASE_SIZE(ptr, 20);
		ptr->timescale = gf_bs_read_u32(bs);
		ptr->presentation_time_delta = gf_bs_read_u64(bs);
		ptr->event_duration = gf_bs_read_u32(bs);
		ptr->event_id = gf_bs_read_u32(bs);

		e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
		if (e) return e;
		e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
		if (e) return e;
	} else {
		return GF_OK;
	}
	if (ptr->size) {
		if (ptr->size>0xFFFFFFFUL) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] emsg message data size too big ("LLU") to be loaded\n", ptr->size));
			return GF_OUT_OF_MEM;
		}
		ptr->message_data_size = (u32) ptr->size;
		ptr->message_data = gf_malloc(ptr->message_data_size);
		if (!ptr->message_data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->message_data, ptr->message_data_size);
		ptr->size = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err emsg_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 len;
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	if (ptr->version==1) {
		gf_bs_write_u32(bs, ptr->timescale);
		gf_bs_write_u64(bs, ptr->presentation_time_delta);
		gf_bs_write_u32(bs, ptr->event_duration);
		gf_bs_write_u32(bs, ptr->event_id);
	}

	len = ptr->scheme_id_uri ? (u32) strlen(ptr->scheme_id_uri) : 0;
	if (len) gf_bs_write_data(bs, ptr->scheme_id_uri, len);
	gf_bs_write_u8(bs, 0);

	len = ptr->value ? (u32) strlen(ptr->value) : 0;
	if (len) gf_bs_write_data(bs, ptr->value, len);
	gf_bs_write_u8(bs, 0);

	if (ptr->version==0) {
		gf_bs_write_u32(bs, ptr->timescale);
		gf_bs_write_u32(bs, (u32) ptr->presentation_time_delta);
		gf_bs_write_u32(bs, ptr->event_duration);
		gf_bs_write_u32(bs, ptr->event_id);
	}
	if (ptr->message_data)
		gf_bs_write_data(bs, ptr->message_data, ptr->message_data_size);
	return GF_OK;
}

GF_Err emsg_box_size(GF_Box *s)
{
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;

	if (ptr->version) {
		ptr->size += 20;
	} else {
		ptr->size += 16;
	}
	ptr->size+=2; //1 NULL-terminated strings
	if (ptr->scheme_id_uri) ptr->size += strlen(ptr->scheme_id_uri);
	if (ptr->value) ptr->size += strlen(ptr->value);
	if (ptr->message_data)
		ptr->size += ptr->message_data_size;

	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE


GF_Box *silb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SchemeIdListBox, GF_ISOM_BOX_TYPE_SILB);
	return (GF_Box *)tmp;
}

void silb_box_del(GF_Box *s)
{
	GF_SchemeIdListBox *ptr = (GF_SchemeIdListBox *) s;
	if (ptr == NULL) return;
	while (gf_list_count(ptr->schemes)) {
		GF_SchemeIdListBoxEntry *ent = (GF_SchemeIdListBoxEntry *)gf_list_get(ptr->schemes, 0);
		gf_free(ent->scheme_id_uri);
		gf_free(ent->value);
		gf_free(ent);
		gf_list_rem(ptr->schemes, 0);
	}
	gf_list_del(ptr->schemes);
	gf_free(ptr);
}

GF_Err silb_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SchemeIdListBox *ptr = (GF_SchemeIdListBox*) s;

	ptr->number_of_schemes = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4+ptr->number_of_schemes*sizeof(GF_SchemeIdListBoxEntry)+1);
	if (ptr->number_of_schemes) {
		ptr->schemes = gf_list_new();
		if (!ptr->schemes) return GF_OUT_OF_MEM;

		for (u32 i=0; i<ptr->number_of_schemes; i++) {
			GF_SchemeIdListBoxEntry *ent = gf_malloc(sizeof(GF_SchemeIdListBoxEntry));
			if (!ent) return GF_OUT_OF_MEM;
			memset(ent, 0, sizeof(GF_SchemeIdListBoxEntry));

			e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ent->scheme_id_uri);
			if (e) {
				gf_free(ent);
				return e;
			}
			e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ent->value);
			if (e) {
				if (ent->scheme_id_uri) gf_free(ent->scheme_id_uri);
				gf_free(ent);
				return e;
			}

			ent->reserved = gf_bs_read_int(bs, 7);
			ent->atleast_once_flag = gf_bs_read_int(bs, 1);

			gf_list_add(ptr->schemes, ent);
		}
	}

	ptr->reserved = gf_bs_read_int(bs, 7);
	ptr->other_schemes_flag = gf_bs_read_int(bs, 1);

	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err silb_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SchemeIdListBox *ptr = (GF_SchemeIdListBox*) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u32(bs, ptr->number_of_schemes);
	for (u32 i=0; i<ptr->number_of_schemes; i++) {
		GF_SchemeIdListBoxEntry *ent = gf_list_get(ptr->schemes, i);

		u32 len = ent->scheme_id_uri ? (u32) strlen(ent->scheme_id_uri) : 0;
		if (len) gf_bs_write_data(bs, ent->scheme_id_uri, len);
		gf_bs_write_u8(bs, 0);

		len = ent->value ? (u32) strlen(ent->value) : 0;
		if (len) gf_bs_write_data(bs, ent->value, len);
		gf_bs_write_u8(bs, 0);

		gf_bs_write_int(bs, ent->reserved, 7);
		gf_bs_write_int(bs, ent->atleast_once_flag, 1);
	}

	gf_bs_write_int(bs, ptr->reserved, 7);
	gf_bs_write_int(bs, ptr->other_schemes_flag, 1);

	return GF_OK;
}

GF_Err silb_box_size(GF_Box *s)
{
	GF_SchemeIdListBox *ptr = (GF_SchemeIdListBox*) s;

	ptr->size += 4;     //number_of_schemes
	for (u32 i=0; i<ptr->number_of_schemes; i++) {
		GF_SchemeIdListBoxEntry *ent = gf_list_get(ptr->schemes, i);
		if (!ent) return GF_BAD_PARAM;
		ptr->size += 2; //2 NULL-terminated strings
		if (ent->scheme_id_uri) ptr->size += strlen(ent->scheme_id_uri);
		if (ent->value) ptr->size += strlen(ent->value);
		ptr->size += 1; //reserved + atleast_once_flag
	}
	ptr->size += 1;     //reserved + other_schemes_flag

	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE


GF_Box *emib_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMIB);
	return (GF_Box *)tmp;
}

void emib_box_del(GF_Box *s)
{
	GF_EventMessageBox *ptr = (GF_EventMessageBox *) s;
	if (ptr == NULL) return;
	if (ptr->scheme_id_uri) gf_free(ptr->scheme_id_uri);
	if (ptr->value) gf_free(ptr->value);
	if (ptr->message_data) gf_free(ptr->message_data);
	gf_free(ptr);
}

GF_Err emib_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_Err e;
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;

	ISOM_DECREASE_SIZE(ptr, 20);
	gf_bs_read_u32(bs); /*reserved*/
	ptr->presentation_time_delta = gf_bs_read_u64(bs);
	ptr->event_duration = gf_bs_read_u32(bs);
	ptr->event_id = gf_bs_read_u32(bs);

	e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri);
	if (e) return e;
	e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value);
	if (e) return e;

	if (ptr->size) {
		if (ptr->size>0xFFFFFFFUL) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] emib message data size too big ("LLU") to be loaded\n", ptr->size));
			return GF_OUT_OF_MEM;
		}
		ptr->message_data_size = (u32) ptr->size;
		ptr->message_data = gf_malloc(ptr->message_data_size);
		if (!ptr->message_data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->message_data, ptr->message_data_size);
		ptr->size = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err emib_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 len;
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, 0); /*reserved*/
	gf_bs_write_u64(bs, ptr->presentation_time_delta);
	gf_bs_write_u32(bs, ptr->event_duration);
	gf_bs_write_u32(bs, ptr->event_id);

	len = ptr->scheme_id_uri ? (u32) strlen(ptr->scheme_id_uri) : 0;
	if (len) gf_bs_write_data(bs, ptr->scheme_id_uri, len);
	gf_bs_write_u8(bs, 0);

	len = ptr->value ? (u32) strlen(ptr->value) : 0;
	if (len) gf_bs_write_data(bs, ptr->value, len);
	gf_bs_write_u8(bs, 0);

	if (ptr->message_data)
		gf_bs_write_data(bs, ptr->message_data, ptr->message_data_size);

	return GF_OK;
}

GF_Err emib_box_size(GF_Box *s)
{
	GF_EventMessageBox *ptr = (GF_EventMessageBox*) s;
	ptr->size += 20;
	ptr->size += 2; //1 NULL-terminated strings
	if (ptr->scheme_id_uri) ptr->size += strlen(ptr->scheme_id_uri);
	if (ptr->value) ptr->size += strlen(ptr->value);
	if (ptr->message_data)
		ptr->size += ptr->message_data_size;

	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE


GF_Box *emeb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_EMEB);
	return (GF_Box *)tmp;
}

void emeb_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err emeb_box_read(GF_Box *s,GF_BitStream *bs)
{
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err emeb_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err emeb_box_size(GF_Box *s)
{
	(void)s;
	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE


GF_Box *evte_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_EVTE);
	return (GF_Box *)tmp;
}

void evte_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err evte_box_read(GF_Box *s,GF_BitStream *bs)
{
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err evte_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err evte_box_size(GF_Box *s)
{
	(void)s;
	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE



GF_Box *csgp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CompactSampleGroupBox, GF_ISOM_BOX_TYPE_CSGP);
	return (GF_Box *)tmp;
}
void csgp_box_del(GF_Box *a)
{
	GF_CompactSampleGroupBox *p = (GF_CompactSampleGroupBox *)a;
	if (p->patterns) {
		u32 i;
		for (i=0; i<p->pattern_count; i++) {
			if (p->patterns[i].sample_group_description_indices)
				gf_free(p->patterns[i].sample_group_description_indices);
		}
		gf_free(p->patterns);
	}
	gf_free(p);
}

u32 get_size_by_code(u32 code)
{
	if (code==0) return 4;
	if (code==1) return 8;
	if (code==2) return 16;
	return 32;
}
GF_Err csgp_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i, bits, gidx_mask;
	Bool index_msb_indicates_fragment_local_description, grouping_type_parameter_present;
	u32 pattern_size, scount_size, index_size;
	GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);

	index_msb_indicates_fragment_local_description = (ptr->flags & (1<<7)) ? GF_TRUE : GF_FALSE;
	grouping_type_parameter_present = (ptr->flags & (1<<6)) ? GF_TRUE : GF_FALSE;

	pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
	scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
	index_size = get_size_by_code( (ptr->flags & 0x3) );

	if (((pattern_size==4) && (scount_size!=4)) || ((pattern_size!=4) && (scount_size==4))) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample group pattern_size and sample_count_size mare not both 4 bits\n"));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->grouping_type = gf_bs_read_u32(bs);
	if (grouping_type_parameter_present) {
		ISOM_DECREASE_SIZE(ptr, 4);
		ptr->grouping_type_parameter = gf_bs_read_u32(bs);
	}
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->pattern_count = gf_bs_read_u32(bs);


	if ( (ptr->size / ( (pattern_size + scount_size) / 8 ) < ptr->pattern_count) || (u64)ptr->pattern_count > (u64)SIZE_MAX/sizeof(GF_CompactSampleGroupPattern) ) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample group pattern_count value (%lu) invalid\n", ptr->pattern_count));
		return GF_ISOM_INVALID_FILE;
	}

	ptr->patterns = gf_malloc(sizeof(GF_CompactSampleGroupPattern) * ptr->pattern_count);
	if (!ptr->patterns) return GF_OUT_OF_MEM;
	memset(ptr->patterns, 0, sizeof(GF_CompactSampleGroupPattern) * ptr->pattern_count);

	u64 patterns_sizes=0;
	bits = 0;
	for (i=0; i<ptr->pattern_count; i++) {
		ptr->patterns[i].length = gf_bs_read_int(bs, pattern_size);
		ptr->patterns[i].sample_count = gf_bs_read_int(bs, scount_size);
		bits += pattern_size + scount_size;
		if (! (bits % 8)) {
			bits/=8;
			ISOM_DECREASE_SIZE(ptr, bits);
			bits=0;
		}
		patterns_sizes+=ptr->patterns[i].length;
		if (patterns_sizes * index_size > ptr->size*8) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample group pattern cumulated sizes "LLU" larger than box size "LLU"\n", patterns_sizes, ptr->size));
			ptr->patterns[i].sample_group_description_indices = NULL;
			return GF_ISOM_INVALID_FILE;
		}

		if ( (u64)ptr->patterns[i].length > (u64)SIZE_MAX/sizeof(u32) ) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample group pattern #%d value (%lu) invalid\n", i, ptr->patterns[i].length));
			ptr->patterns[i].sample_group_description_indices = NULL;
			return GF_ISOM_INVALID_FILE;
		}
		ptr->patterns[i].sample_group_description_indices = gf_malloc(sizeof(u32) * ptr->patterns[i].length);
		if (!ptr->patterns[i].sample_group_description_indices) return GF_OUT_OF_MEM;
	}
	bits = 0;
	gidx_mask = ((u32)1) << (index_size-1);
	for (i=0; i<ptr->pattern_count; i++) {
		u32 j;
		for (j=0; j<ptr->patterns[i].length; j++) {
			u32 idx = gf_bs_read_int(bs, index_size);
			if (index_msb_indicates_fragment_local_description) {
				//MSB set, this is a index of a group described in the fragment
				if (idx & gidx_mask) {
					idx += 0x10000;
					idx &= ~gidx_mask;
				}
			}
			ptr->patterns[i].sample_group_description_indices[j] = idx;
			bits += index_size;

			if (! (bits % 8)) {
				bits/=8;
				ISOM_DECREASE_SIZE(ptr, bits);
				bits=0;
			}
		}
	}
	if (bits)
		gf_bs_align(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err csgp_box_write(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	GF_Err e;
	GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
	u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
	u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
	u32 index_size = get_size_by_code( (ptr->flags & 0x3) );

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_int(bs, ptr->flags, 24);
	gf_bs_write_u32(bs, ptr->grouping_type);

	if (ptr->flags & (1<<6))
		gf_bs_write_u32(bs, ptr->grouping_type_parameter);

	gf_bs_write_u32(bs, ptr->pattern_count);

	for (i = 0; i<ptr->pattern_count; i++ ) {
		gf_bs_write_int(bs, ptr->patterns[i].length, pattern_size);
		gf_bs_write_int(bs, ptr->patterns[i].sample_count, scount_size);
	}

	for (i = 0; i<ptr->pattern_count; i++ ) {
		u32 j;
		for (j=0; j<ptr->patterns[i].length; j++) {
			u32 idx = ptr->patterns[i].sample_group_description_indices[j];
			if (idx > 0x10000) {
				idx -= 0x10000;
				gf_bs_write_int(bs, 1, 1);
				gf_bs_write_int(bs, idx, index_size-1);
			} else {
				gf_bs_write_int(bs, idx, index_size);
			}
		}
	}
	gf_bs_align(bs);
	return GF_OK;
}

GF_Err csgp_box_size(GF_Box *s)
{
	u32 i, bits;
	GF_CompactSampleGroupBox *ptr = (GF_CompactSampleGroupBox*)s;
	u32 pattern_size = get_size_by_code( ((ptr->flags>>4) & 0x3) );
	u32 scount_size = get_size_by_code( ((ptr->flags>>2) & 0x3) );
	u32 index_size = get_size_by_code( (ptr->flags & 0x3) );

	ptr->size += 12; //v, flags , grouping_type, pattern_length
	if (ptr->flags & (1<<6))
		ptr->size+=4;

	ptr->size += ptr->pattern_count * (pattern_size + scount_size) / 8;
	bits=0;
	for (i=0; i<ptr->pattern_count; i++)
		bits += ptr->patterns[i].length * index_size;
	ptr->size += bits/8;
	if (bits % 8) ptr->size++;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *dmlp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrueHDConfigBox, GF_ISOM_BOX_TYPE_DMLP);
	return (GF_Box *)tmp;
}

void dmlp_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err dmlp_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;
	ISOM_DECREASE_SIZE(ptr, 10)
	ptr->format_info = gf_bs_read_u32(bs);
	ptr->peak_data_rate = gf_bs_read_int(bs, 15);
	gf_bs_read_int(bs, 1);
	gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err dmlp_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrueHDConfigBox *ptr = (GF_TrueHDConfigBox *)s;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->format_info);
	gf_bs_write_int(bs, ptr->peak_data_rate, 15);
	gf_bs_write_int(bs, 0, 1);
	gf_bs_write_u32(bs, 0);
	return GF_OK;
}

GF_Err dmlp_box_size(GF_Box *s)
{
	s->size += 10;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *xtra_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_XtraBox, GF_ISOM_BOX_TYPE_XTRA);
	tmp->tags = gf_list_new();
	return (GF_Box *)tmp;
}

void xtra_box_del(GF_Box *s)
{
	GF_XtraBox *ptr = (GF_XtraBox *)s;
	while (gf_list_count(ptr->tags)) {
		GF_XtraTag *tag = gf_list_pop_back(ptr->tags);
		if (tag->name) gf_free(tag->name);
		if (tag->prop_value) gf_free(tag->prop_value);
		gf_free(tag);
	}
	gf_list_del(ptr->tags);
	gf_free(s);
}

GF_Err xtra_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_XtraBox *ptr = (GF_XtraBox *)s;
	while (ptr->size) {
		GF_XtraTag *tag;
		u32 prop_type = 0;

		char *data=NULL, *data2=NULL;
		ISOM_DECREASE_SIZE_NO_ERR(ptr, 8)
		s32 tag_size = gf_bs_read_u32(bs);
		u32 name_size = gf_bs_read_u32(bs);
		if (tag_size < 8) return GF_ISOM_INVALID_FILE;

		tag_size -= 8;
		if ((tag_size>ptr->size) || (name_size>ptr->size)) {
			return GF_ISOM_INVALID_FILE;
		}
		ISOM_DECREASE_SIZE_NO_ERR(ptr, 10)

		ISOM_DECREASE_SIZE_NO_ERR(ptr, name_size)
		data = gf_malloc(sizeof(char) * (name_size+1));
		gf_bs_read_data(bs, data, name_size);
		data[name_size] = 0;
		tag_size-=name_size;

		u32 flags = gf_bs_read_u32(bs);
		u32 prop_size = gf_bs_read_u32(bs);
		tag_size-=8;

		if (prop_size>6 ) {
			tag_size-=2;
			prop_type = gf_bs_read_u16(bs);
			prop_size -= 6;
			if (ptr->size < prop_size && data) {
				gf_free(data);
			}
			ISOM_DECREASE_SIZE_NO_ERR(ptr, prop_size)
			//add 3 extra bytes for UTF16 case string dump (3 because we need 0-aligned short value)
			data2 = gf_malloc(sizeof(char) * (prop_size+3));
			gf_bs_read_data(bs, data2, prop_size);
			data2[prop_size] = 0;
			data2[prop_size+1] = 0;
			data2[prop_size+2] = 0;
			tag_size-=prop_size;
		} else {
			prop_size = 0;
		}
		GF_SAFEALLOC(tag, GF_XtraTag)
		tag->flags = flags;
		tag->name = data;
		tag->prop_size = prop_size;
		tag->prop_value = data2;
		tag->prop_type = prop_type;
		gf_list_add(ptr->tags, tag);

		if (tag_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isom] left-over bytes in tag %s in Xtra !\n", data));
			gf_bs_skip_bytes(bs, tag_size);
			ISOM_DECREASE_SIZE_NO_ERR(ptr, tag_size)
		}
	}
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err xtra_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_XtraBox *ptr = (GF_XtraBox *)s;
	u32 i, count = gf_list_count(ptr->tags);

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;

	for (i=0; i<count; i++) {
		GF_XtraTag *tag = gf_list_get(ptr->tags, i);
		u32 tag_size = 16;
		u32 name_len = tag->name ? (u32) strlen(tag->name) : 0;
		tag_size += name_len;
		if (tag->prop_value) {
			tag_size += 2 + tag->prop_size;
		}
		gf_bs_write_u32(bs, tag_size);
		gf_bs_write_u32(bs, name_len);
		gf_bs_write_data(bs, tag->name, name_len);
		gf_bs_write_u32(bs, tag->flags);
		gf_bs_write_u32(bs, 6 + tag->prop_size);
		gf_bs_write_u16(bs, tag->prop_type);
		gf_bs_write_data(bs, tag->prop_value, tag->prop_size);
	}
	return GF_OK;
}

GF_Err xtra_box_size(GF_Box *s)
{
	GF_XtraBox *ptr = (GF_XtraBox *)s;
	u32 i, count = gf_list_count(ptr->tags);
	for (i=0; i<count; i++) {
		GF_XtraTag *tag = gf_list_get(ptr->tags, i);
		ptr->size += 18 + (u32) strlen(tag->name) + tag->prop_size;
	}
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *st3d_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Stereo3DBox, GF_ISOM_BOX_TYPE_ST3D);
	return (GF_Box *)tmp;
}

void st3d_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err st3d_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;
	ISOM_DECREASE_SIZE(ptr, 1)
	ptr->stereo_type = gf_bs_read_u8(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err st3d_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_Stereo3DBox *ptr = (GF_Stereo3DBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->stereo_type);
	return GF_OK;
}

GF_Err st3d_box_size(GF_Box *s)
{
	s->size += 1;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/



GF_Box *svhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SphericalVideoInfoBox, GF_ISOM_BOX_TYPE_SVHD);
	return (GF_Box *)tmp;
}

void svhd_box_del(GF_Box *s)
{
	GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
	if (ptr->string) gf_free(ptr->string);
	gf_free(s);
}


GF_Err svhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
	if ((u32)ptr->size >= (u32)0xFFFFFFFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in svhd box\n", ptr->size));
		return GF_ISOM_INVALID_FILE;
	}
	ptr->string = gf_malloc(sizeof(char) * ((u32) ptr->size+1));
	if (!ptr->string) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->string, (u32) ptr->size);
	ptr->string[ptr->size] = 0;
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err svhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->string)
		gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string));
	gf_bs_write_u8(bs, 0);
	return GF_OK;
}

GF_Err svhd_box_size(GF_Box *s)
{
	GF_SphericalVideoInfoBox *ptr = (GF_SphericalVideoInfoBox *)s;
	if (ptr->string)
		s->size += (u32) strlen(ptr->string);
	s->size += 1;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *prhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProjectionHeaderBox, GF_ISOM_BOX_TYPE_PRHD);
	return (GF_Box *)tmp;
}

void prhd_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err prhd_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;
	ISOM_DECREASE_SIZE(ptr, 12)
	ptr->yaw = (s32) gf_bs_read_u32(bs);
	ptr->pitch = (s32) gf_bs_read_u32(bs);
	ptr->roll = (s32) gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err prhd_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ProjectionHeaderBox *ptr = (GF_ProjectionHeaderBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->yaw);
	gf_bs_write_u32(bs, ptr->pitch);
	gf_bs_write_u32(bs, ptr->roll);
	return GF_OK;
}

GF_Err prhd_box_size(GF_Box *s)
{
	s->size += 12;
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

GF_Box *proj_type_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProjectionTypeBox, GF_ISOM_BOX_TYPE_EQUI); //will be overwritten
	return (GF_Box *)tmp;
}

void proj_type_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err proj_type_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;

	if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
		ISOM_DECREASE_SIZE(ptr, 8)
		ptr->layout = gf_bs_read_u32(bs);
		ptr->padding = gf_bs_read_u32(bs);
	}
	else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
		ISOM_DECREASE_SIZE(ptr, 16)
		ptr->bounds_top = gf_bs_read_u32(bs);
		ptr->bounds_bottom = gf_bs_read_u32(bs);
		ptr->bounds_left = gf_bs_read_u32(bs);
		ptr->bounds_right = gf_bs_read_u32(bs);
	} else {
		ISOM_DECREASE_SIZE(ptr, 8)
		ptr->crc = gf_bs_read_u32(bs);
		ptr->encoding_4cc = gf_bs_read_u32(bs);
	}
	return gf_isom_box_array_read(s, bs);
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err proj_type_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->type==GF_ISOM_BOX_TYPE_CBMP) {
		gf_bs_write_u32(bs, ptr->layout);
		gf_bs_write_u32(bs, ptr->padding);
	}
	else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI) {
		gf_bs_write_u32(bs, ptr->bounds_top);
		gf_bs_write_u32(bs, ptr->bounds_bottom);
		gf_bs_write_u32(bs, ptr->bounds_left);
		gf_bs_write_u32(bs, ptr->bounds_right);
	} else {
		gf_bs_write_u32(bs, ptr->crc);
		gf_bs_write_u32(bs, ptr->encoding_4cc);
	}
	return GF_OK;
}

GF_Err proj_type_box_size(GF_Box *s)
{
	GF_ProjectionTypeBox *ptr = (GF_ProjectionTypeBox *)s;
	if (ptr->type==GF_ISOM_BOX_TYPE_CBMP)
		s->size += 8;
	else if (ptr->type==GF_ISOM_BOX_TYPE_EQUI)
		s->size += 16;
	else
		s->size += 8;

	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


GF_Box *empty_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_Box, GF_QT_BOX_TYPE_FRCD);
	return (GF_Box *) tmp;
}

void empty_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err empty_box_read(GF_Box *s, GF_BitStream *bs)
{
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err empty_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err empty_box_size(GF_Box *s)
{
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/


void extl_box_del(GF_Box *s)
{
	GF_ExternalTrackLocationBox *ptr = (GF_ExternalTrackLocationBox *)s;
	if (ptr->location) gf_free(ptr->location);
	gf_free(ptr);
	return;
}


GF_Err extl_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ExternalTrackLocationBox *ptr = (GF_ExternalTrackLocationBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->referenced_track_ID = gf_bs_read_u32(bs);
	ptr->referenced_handler_type = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->media_timescale = gf_bs_read_u32(bs);

	if (ptr->size) {
		u32 name_size = (u32) ptr->size;
		if (name_size < 1 || name_size >= GF_UINT_MAX-1) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid size %llu in hdlr\n", ptr->size));
			return GF_ISOM_INVALID_FILE;
		}
		ptr->location = (char*)gf_malloc(name_size+1);
		if (!ptr->location) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->location, name_size);
		ptr->location[name_size] = 0;
	}
	return GF_OK;
}

GF_Box *extl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ExternalTrackLocationBox, GF_ISOM_BOX_TYPE_EXTL);
	return (GF_Box *)tmp;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err extl_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ExternalTrackLocationBox *ptr = (GF_ExternalTrackLocationBox *)s;

	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, (u32) ptr->referenced_track_ID);
	gf_bs_write_u32(bs, (u32) ptr->referenced_handler_type);
	gf_bs_write_u32(bs, ptr->media_timescale);

	gf_bs_write_utf8(bs, ptr->location);
	return GF_OK;
}

GF_Err extl_box_size(GF_Box *s)
{
	GF_ExternalTrackLocationBox *ptr = (GF_ExternalTrackLocationBox *)s;

	ptr->size += 12;
	ptr->size += 1 + (ptr->location ? (u32) strlen(ptr->location) : 0);

	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

//#define DUMP_STATS

#ifdef DUMP_STATS
static u32 global_boxes=0;
static u32 global_samples=0;
static u32 global_cost=0;
static u32 global_cost_full=0;
static s32 global_cost_diff=0;
static u32 global_patterns_diff=0;
static s32 global_cost_nodiff=0;
static u32 global_patterns_nodiff=0;
static s32 global_cost_refs_sbgp=0;
#endif


GF_Box *sref_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleReferences, GF_ISOM_BOX_TYPE_CDRF);
	tmp->entries = gf_list_new();
	return (GF_Box *) tmp;
}

void sref_box_del(GF_Box *s)
{
	GF_SampleReferences *ptr = (GF_SampleReferences*)s;
	while (gf_list_count(ptr->entries)) {
		GF_SampleRefEntry *ent = gf_list_pop_back(ptr->entries);
		if (ent->sample_refs) gf_free(ent->sample_refs);
		gf_free(ent);
	}
	gf_list_del(ptr->entries);
	gf_free(s);

#ifdef DUMP_STATS
	if (global_boxes)
		fprintf(stdout, "\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", global_boxes, global_samples, global_cost, global_cost_full, global_cost_diff, global_cost_nodiff, global_cost_refs_sbgp, global_patterns_diff, global_patterns_nodiff);
#endif
}


typedef struct
{
	Bool is_abs;
	u32 orig_sampleID;
	s32 diff_sampleID;
	u32 nb_refs;
	s32 *sample_refs;
	s32 *orig_sample_refs;

	u32 flags;
} GF_SampleRefDiffEntry;

static s32 read_signed_int(GF_BitStream *bs, u32 nb_bits, s32 max_val)
{
	s32 val = gf_bs_read_int(bs, nb_bits);
	if (val<max_val) return val;
	if (max_val>=GF_INT_MAX/2) return max_val;
	return val - (2*max_val);
}

GF_Err cdrf_box_read(GF_SampleReferences *s, GF_BitStream *bs)
{
	GF_Err e = GF_OK;
	ISOM_DECREASE_SIZE(s, 1)
	s->flags = gf_bs_read_u8(bs);
	Bool use_nodiff = (s->flags & 16) ? GF_TRUE : GF_FALSE;

	u32 i, j;
	u32 bits = 8, entry_bits=8;
	if (s->flags & 1) bits = 16;
	else if (s->flags & 2) bits = 32;

	s32 max_val = 1;
	i=0;
	while (i<bits-1) {
		i++;
		max_val = i<31 ? max_val<<1 : GF_INT_MAX;
	}
	s32 max_val2 = max_val>>1;

	if (s->flags & 4) entry_bits = 16;
	else if (s->flags & 8) entry_bits = 32;
	s->cdrf_entries = gf_bs_read_int(bs, entry_bits);

	GF_List *def_refs = gf_list_new();
	GF_List *samples = gf_list_new();
	for (i=0; i<s->cdrf_entries; i++) {
		ISOM_DECREASE_SIZE_GOTO_EXIT(s, bits/8)
		Bool is_ref = gf_bs_read_int(bs, 1);
		if (!is_ref) {
			GF_SampleRefDiffEntry *ent;
			u32 nb_refs = gf_bs_read_int(bs, bits-1);
			if ( nb_refs >= GF_UINT_MAX || bits < 8 || (1+nb_refs) > GF_UINT_MAX / (bits/8) ) {
				e = GF_NON_COMPLIANT_BITSTREAM;
				goto exit;
			}
			ISOM_DECREASE_SIZE_GOTO_EXIT(s, (1+nb_refs)*(bits/8))
			GF_SAFEALLOC(ent, GF_SampleRefDiffEntry);
			if (!ent) {
				e = GF_OUT_OF_MEM;
				goto exit;
			}
			gf_list_add(def_refs, ent);
			gf_list_add(samples, ent);
			ent->sample_refs = gf_malloc(sizeof(s32)*nb_refs);
			if (!ent->sample_refs) {
				e = GF_OUT_OF_MEM;
				goto exit;
			}
			ent->nb_refs = nb_refs;
			if (use_nodiff) {
				ent->diff_sampleID = (s32) read_signed_int(bs, bits, max_val);
			} else {
				ent->is_abs = gf_bs_read_int(bs, 1);
				ent->diff_sampleID = (s32) read_signed_int(bs, bits-1, max_val2);
			}
			for (j=0; j<nb_refs; j++) {
				ent->sample_refs[j] = (s32) (s8) read_signed_int(bs, bits, max_val);
			}

		} else {
			ISOM_DECREASE_SIZE_GOTO_EXIT(s, 3*bits/8)
			u32 offset = gf_bs_read_int(bs, bits-1);
			u32 pattern_len = gf_bs_read_int(bs, bits);
			u32 nb_samples = gf_bs_read_int(bs, bits);
			if (nb_samples > GF_INT_MAX) {
				e = GF_ISOM_INVALID_FILE;
				goto exit;
			}
			u32 pattern_idx=0;
			for (j=0; j<nb_samples; j++) {
				u32 s_offset = offset + pattern_idx;
				GF_SampleRefDiffEntry *ent = gf_list_get(samples, s_offset);
				if (!ent) {
					e = GF_ISOM_INVALID_FILE;
					goto exit;
				}
				if (use_nodiff) {
					GF_SampleRefDiffEntry *rent;
					ISOM_DECREASE_SIZE_GOTO_EXIT(s, bits/8)
					GF_SAFEALLOC(rent, GF_SampleRefDiffEntry);
					if (!rent) {
						e = GF_OUT_OF_MEM;
						goto exit;
					}
					rent->diff_sampleID = (s32) read_signed_int(bs, bits, max_val);
					rent->nb_refs = ent->nb_refs;
					rent->sample_refs = ent->sample_refs;
					rent->flags = 1;
					gf_list_add(samples, rent);
				} else {
					gf_list_add(samples, ent);
				}
				pattern_idx++;
				if (pattern_idx==pattern_len) pattern_idx=0;
			}
		}
	}

	u32 prev_sample_id = 0;
	while (gf_list_count(samples)) {
		GF_SampleRefDiffEntry *ent = gf_list_pop_front(samples);
		GF_SampleRefEntry *final_ent;
		GF_SAFEALLOC(final_ent, GF_SampleRefEntry);
		if (final_ent) {
			final_ent->sample_refs = gf_malloc(sizeof(u32)*ent->nb_refs);
			gf_list_add(s->entries, final_ent);
		}
		if (!final_ent || !final_ent->sample_refs) {
			e = GF_OUT_OF_MEM;
			goto exit;
		}
		if (use_nodiff)
			final_ent->sampleID = ent->diff_sampleID;
		else
			if (ent->is_abs) final_ent->sampleID = ent->diff_sampleID;
			else final_ent->sampleID = prev_sample_id + ent->diff_sampleID;

		prev_sample_id = final_ent->sampleID;
		final_ent->nb_refs = ent->nb_refs;
		for (j=0; j<ent->nb_refs;j++) {
			s32 ref;
			if (use_nodiff)
				ref = ent->sample_refs[j];
			else
				ref = final_ent->sampleID - ent->sample_refs[j];

			assert(ref>=0);
			final_ent->sample_refs[j] = ref;
		}
		if (ent->flags) {
			gf_free(ent);
		}
	}

exit:
	if (use_nodiff) {
		while (gf_list_count(samples)) {
			GF_SampleRefDiffEntry *ent = gf_list_pop_front(samples);
			if (gf_list_find(def_refs, ent) < 0) {
				gf_free(ent);
			}
		}
	}
	gf_list_del(samples);

	while (gf_list_count(def_refs)) {
		GF_SampleRefDiffEntry *ent = gf_list_pop_back(def_refs);
		if (ent->sample_refs) gf_free(ent->sample_refs);
		gf_free(ent);
	}
	gf_list_del(def_refs);

	return e;
}
GF_Err sref_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleReferences *ptr = (GF_SampleReferences*)s;
	if (ptr->type==GF_ISOM_BOX_TYPE_CDRF) {
		return cdrf_box_read(ptr, bs);
	}
	ISOM_DECREASE_SIZE(s, 4)

	u32 bits = 8;
	if (ptr->flags & (1<<1)) bits = 32;
	else if (ptr->flags & (1)) bits = 16;
	u32 max_val = (u32)(((u64)1<<bits) - 1);
	u32 i, nb_entries = gf_bs_read_u32(bs);
	if (nb_entries * bits / 8 > s->size) return GF_ISOM_INVALID_FILE;
	for (i=0; i<nb_entries; i++) {
		GF_SampleRefEntry *ent;
		GF_SAFEALLOC(ent, GF_SampleRefEntry);
		if (!ent) return GF_OUT_OF_MEM;
		gf_list_add(ptr->entries, ent);
		ISOM_DECREASE_SIZE(s, bits/8)
		ent->sampleID = gf_bs_read_int(bs, bits);
		if (ent->sampleID == max_val)
			continue;
		ISOM_DECREASE_SIZE(s, bits/8)
		ent->nb_refs = gf_bs_read_int(bs, bits);
		if (ent->nb_refs > s->size * 8 / bits) return GF_ISOM_INVALID_FILE;
		if (ent->nb_refs) {
			u32 j;
			ent->sample_refs = gf_malloc(sizeof(u32) * ent->nb_refs);
			for (j=0; j<ent->nb_refs; j++) {
				ent->sample_refs[j] = gf_bs_read_int(bs, bits);
				ISOM_DECREASE_SIZE(s, bits/8)
			}
		}
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

#ifdef DUMP_STATS
static Bool cdrf_sample_is_leaf(GF_SampleReferences *ptr, u32 sample_id)
{
	u32 i, j, nb_entries = gf_list_count(ptr->entries);
	for (i=0; i<nb_entries; i++) {
		GF_SampleRefEntry *ent = gf_list_get(ptr->entries, i);
		for (j=0; j<ent->nb_refs; j++) {
			if (ent->sample_refs[j]==sample_id) return GF_TRUE;
		}
	}
	return GF_FALSE;
}
#endif

static GF_List *cdrf_get_refs(GF_SampleReferences *ptr, s32 *out_max_id, s32 *out_max_id_nodiff)
{
	Bool all_intra=GF_TRUE;
	s32 max_id_diff=-1;
	s32 max_id_nodiff=-1;
	u32 i, j, nb_entries = gf_list_count(ptr->entries);
	u32 prev_sample_id = 0;
	Bool prev_is_irap=GF_FALSE;
	GF_List *refs = gf_list_new();
	for (i=0; i<nb_entries; i++) {
		GF_SampleRefEntry *ent = gf_list_get(ptr->entries, i);
		GF_SampleRefDiffEntry *rent;
		GF_SAFEALLOC(rent, GF_SampleRefDiffEntry);
		rent->diff_sampleID = rent->orig_sampleID = ent->sampleID;
		if (ent->sampleID==GF_INT_MAX) {
			rent->is_abs = GF_TRUE;
			prev_is_irap = GF_FALSE;
		} else if (!ent->nb_refs) {
			//if prev is irap code as diff
			if (prev_is_irap) {
				rent->is_abs = GF_FALSE;
				rent->diff_sampleID -= prev_sample_id;
			} else {
				rent->is_abs = GF_TRUE;
			}
			prev_is_irap = GF_TRUE;
		} else {
			prev_is_irap = GF_FALSE;
			all_intra = GF_FALSE;
			rent->nb_refs = ent->nb_refs;
			rent->orig_sample_refs = ent->sample_refs;
			rent->sample_refs = gf_malloc(sizeof(s32) * ent->nb_refs);
			for (j=0; j<rent->nb_refs; j++) {
				rent->sample_refs[j] = ent->sampleID;
				rent->sample_refs[j] -= ent->sample_refs[j];

				if (out_max_id) {
					if (max_id_diff < ABS(rent->sample_refs[j]))
						max_id_diff = ABS(rent->sample_refs[j]);

					if (max_id_nodiff < rent->orig_sample_refs[j])
						max_id_nodiff = rent->orig_sample_refs[j];
				}
			}
			if (!i)
				rent->is_abs = GF_TRUE;
			else
				rent->diff_sampleID -= prev_sample_id;
		}
#ifdef DUMP_STATS
		if (cdrf_sample_is_leaf(ptr, ent->sampleID))
			rent->flags = 1;
#endif
		prev_sample_id = ent->sampleID;
		gf_list_add(refs, rent);

		if (out_max_id) {
			if (max_id_diff < rent->diff_sampleID)
				max_id_diff = rent->diff_sampleID;
			if (max_id_nodiff < rent->orig_sampleID)
				max_id_nodiff = rent->orig_sampleID;
		}
	}
	if (all_intra) {
		for (i=0; i<nb_entries; i++) {
			GF_SampleRefDiffEntry *ent = gf_list_get(refs, i);
			ent->flags = 1;
		}
	}

	if (out_max_id) *out_max_id = max_id_diff;
	if (out_max_id_nodiff) *out_max_id_nodiff = max_id_nodiff;
	return refs;
}
static void cdrf_clean_refs(GF_List *refs)
{
	while (gf_list_count(refs)) {
		GF_SampleRefDiffEntry *rent = gf_list_pop_back(refs);
		if (rent->sample_refs) gf_free(rent->sample_refs);
		gf_free(rent);
	}
	gf_list_del(refs);
}

static Bool cdrf_same_entry(GF_SampleRefDiffEntry *ref_ent, GF_SampleRefDiffEntry *ref, u32 mode)
{
	//diff cdrf
	if (mode==0) {
		if (ref->is_abs != ref_ent->is_abs) return GF_FALSE;
		if (ref->diff_sampleID != ref_ent->diff_sampleID) return GF_FALSE;
	}
#ifdef DUMP_STATS
	//refs
	if (mode==2) {
		//both leaf samples, check ID
		if (!ref->flags || !ref_ent->flags) {
			if (ref->orig_sampleID != ref_ent->orig_sampleID) return GF_FALSE;
		}
	}
#endif
	if (ref->nb_refs != ref_ent->nb_refs) return GF_FALSE;
	u32 k, l, match = 0;
	s32 *ref_ent_ids = mode ? ref_ent->orig_sample_refs : ref_ent->sample_refs;
	s32 *ref_ids = mode ? ref->orig_sample_refs : ref->sample_refs;

	for (k=0; k<ref_ent->nb_refs; k++) {
		for (l=0; l<ref->nb_refs; l++) {
			if (ref_ids[l] == ref_ent_ids[k]) {
				match ++;
				break;
			}
		}
	}
	if (match==ref_ent->nb_refs) return GF_TRUE;
	return GF_FALSE;
}


static s32 cdrf_locate_first_ref(GF_SampleRefDiffEntry *ref_ent, u32 max_idx, GF_List *refs, s32 pattern_offset, u32 nb_in_pattern, u32 mode)
{
	u32 j;
	if (pattern_offset>=0) {
		GF_SampleRefDiffEntry *ref = gf_list_get(refs, pattern_offset);
		//detect loop
		if (cdrf_same_entry(ref_ent, ref, mode))
			return pattern_offset;
		//detect following
		pattern_offset += nb_in_pattern;
		ref = gf_list_get(refs, pattern_offset);
		if (cdrf_same_entry(ref_ent, ref, mode))
			return pattern_offset;
	}
	//browse from start
	for (j=0; j<max_idx; j++) {
		GF_SampleRefDiffEntry *ref = gf_list_get(refs, j);
		if (cdrf_same_entry(ref_ent, ref, mode))
			return j;
	}
	return -1;
}

static void cdrf_box_flush_pattern(GF_BitStream *bs, u32 pattern_len, s32 prev_offset, u32 nb_samples, u32 *sample_ids, u32 bits)
{
	gf_assert(pattern_len);
	gf_assert(nb_samples);
	gf_bs_write_int(bs, 1, 1);
	gf_bs_write_int(bs, prev_offset, bits-1);
	gf_bs_write_int(bs, pattern_len, bits);
	gf_bs_write_int(bs, nb_samples, bits);

	if (sample_ids) {
		u32 j;
		for (j=0; j<nb_samples; j++)
			gf_bs_write_int(bs, sample_ids[j], bits);
	}
}

GF_Err cdrf_box_write(GF_SampleReferences *ptr, GF_BitStream *bs)
{
	GF_List *refs = cdrf_get_refs(ptr, NULL, NULL);
	u32 i, j;
	u32 bits = 8, entry_bits=8;
	if (ptr->flags & 1) bits = 16;
	else if (ptr->flags & 2) bits = 32;

	if (ptr->flags & 4) entry_bits = 16;
	else if (ptr->flags & 8) entry_bits = 32;

	gf_isom_box_write_header((GF_Box*)ptr, bs);
	gf_bs_write_u8(bs, ptr->flags);
	gf_bs_write_int(bs, ptr->cdrf_entries, entry_bits);

	u32 mode = (ptr->flags & 16) ? 1 : 0;

	s32 prev_offset = -1;
	u32 prev_len = 0;
	u32 pattern_len = 0;
	u32 nb_samples = 0;
	u32 nb_entries = gf_list_count(ptr->entries);
	s32 *sample_ids = NULL;
	if (mode) {
		sample_ids = gf_malloc(sizeof(s32)*nb_entries);
		if (!sample_ids) return GF_OUT_OF_MEM;
	}

	for (i=0; i<nb_entries; i++) {
		GF_SampleRefDiffEntry *rent = gf_list_get(refs, i);
		s32 found = cdrf_locate_first_ref(rent, i, refs, prev_offset, prev_len, mode);

		if (found<0) {
			if (prev_len) {
				cdrf_box_flush_pattern(bs, pattern_len ? pattern_len : prev_len, prev_offset, nb_samples, sample_ids, bits);
			}
			//write direct sample
			gf_bs_write_int(bs, 0, 1);
			gf_bs_write_int(bs, rent->nb_refs, bits-1);
			if (mode) {
				gf_bs_write_int(bs, rent->orig_sampleID, bits);
				for (j=0; j<rent->nb_refs; j++)
					gf_bs_write_int(bs, rent->orig_sample_refs[j], bits);
			} else {
				gf_bs_write_int(bs, rent->is_abs, 1);
				gf_bs_write_int(bs, rent->diff_sampleID, bits-1);
				for (j=0; j<rent->nb_refs; j++)
					gf_bs_write_int(bs, rent->sample_refs[j], bits);
			}

			//reset pattern to empty
			prev_offset = -1;
			prev_len = 0;
			pattern_len = 0;
			nb_samples=0;
		} else {
			if (pattern_len && (pattern_len == prev_len)) {
				prev_len = 0;
			}
			if ((prev_offset>=0) && (found == prev_offset+prev_len)) {
				prev_len++;
				if (sample_ids)
					sample_ids[nb_samples] = rent->orig_sampleID;
				nb_samples++;
				continue;
			}
			if (!pattern_len && (found == prev_offset)) {
				pattern_len = prev_len;
				prev_len = 1;
				if (sample_ids)
					sample_ids[nb_samples] = rent->orig_sampleID;
				nb_samples++;
				continue;
			}
			if (prev_len || pattern_len) {
				cdrf_box_flush_pattern(bs, pattern_len ? pattern_len : prev_len, prev_offset, nb_samples, sample_ids, bits);
			}

			//reset pattern to one sample found
			prev_offset = found;
			pattern_len = 0;
			prev_len = 1;
			nb_samples = 1;
			if (sample_ids)
				sample_ids[0] = rent->orig_sampleID;
		}
	}
	if (prev_len) {
		cdrf_box_flush_pattern(bs, pattern_len ? pattern_len : prev_len, prev_offset, nb_samples, sample_ids, bits);
	}
	if (sample_ids)
		gf_free(sample_ids);
	cdrf_clean_refs(refs);
	return GF_OK;
}

GF_Err sref_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleReferences *ptr = (GF_SampleReferences*)s;
	if (ptr->type==GF_ISOM_BOX_TYPE_CDRF) {
		return cdrf_box_write(ptr, bs);
	}
	GF_Err e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	u32 bits = 8;
	if (ptr->flags & (1<<1)) bits = 32;
	else if (ptr->flags & (1)) bits = 16;

	u32 i, nb_entries = gf_list_count(ptr->entries);
	gf_bs_write_u32(bs, nb_entries);
	for (i=0; i<nb_entries; i++) {
		GF_SampleRefEntry *ent = gf_list_get(ptr->entries, i);
		if (ent->sampleID == GF_INT_MAX) {
			gf_bs_write_int(bs, 0xFFFFFFFF, bits);
			continue;
		}
		gf_bs_write_int(bs, ent->sampleID, bits);
		gf_bs_write_int(bs, ent->nb_refs, bits);
		if (ent->nb_refs) {
			u32 j;
			for (j=0; j<ent->nb_refs; j++) {
				gf_bs_write_int(bs, ent->sample_refs[j], bits);
			}
		}
	}
	return GF_OK;
}

//#define DUMP_REFS


static u32 cdrf_get_cost(GF_List *refs, u32 mode, s32 max_id, u32 *cost_full, u32 *total_entries, u8 *flags)
{
	s32 prev_offset = -1;
	u32 prev_len = 0;
	u32 nb_samples = 0;
	u32 pattern_len = 0;

#ifdef DUMP_STATS
	u32 cost_refs=0;
	u32 cost_sbgp=0;
#endif
	u32 i, nb_entries = gf_list_count(refs);
	u32 nb_direct_cost=0, nb_direct_entries=0, nb_pattern_entries=0, nb_samples_reused=0;
	*cost_full=0;

	for (i=0; i<nb_entries; i++) {
		GF_SampleRefDiffEntry *rent = gf_list_get(refs, i);
		s32 found = cdrf_locate_first_ref(rent, i, refs, prev_offset, prev_len, mode);

		*cost_full += 2 + rent->nb_refs;
#ifdef DUMP_REFS
		Bool pattern_start=GF_FALSE;
		Bool pattern_end=GF_FALSE;
#endif
		if (found<0) {
#ifdef DUMP_STATS
			if (mode==2) {
				//need refs sample entry + length
				cost_refs += 4 + 5+4*rent->nb_refs;
				//need sgpd entry
				cost_sbgp += 8;
				continue;
			}
#endif
			if (prev_len > max_id) {
				max_id = prev_len;
			}
			if (prev_len) {
				gf_fatal_assert(nb_samples);
				nb_pattern_entries += 1;
#ifdef DUMP_REFS
				pattern_end=GF_TRUE;
#endif
			}
			if (prev_offset > max_id)
				max_id = prev_offset;

			prev_offset = -1;
			prev_len = 0;
			pattern_len = 0;
			nb_samples = 0;
			nb_direct_entries += 1;
			nb_direct_cost += 2 + rent->nb_refs;
		} else {
#ifdef DUMP_STATS
			if (mode==2) {
				//reuse existing refs sample group, no refs extra cost
				GF_SampleRefDiffEntry *prev_ent = gf_list_get(refs, i-1);
				//same as previous, RLE from previous sbgp entry can be used
				if (prev_ent && cdrf_same_entry(rent, prev_ent, 2)) {

				} else {
					//need sgpd entry
					cost_sbgp += 8;
				}
				continue;
			}
#endif
			nb_samples_reused += 1;
			if (pattern_len && (pattern_len == prev_len)) {
				prev_len = 0;
			}

			if ((prev_offset>=0) && (found == prev_offset+prev_len)) {
				prev_len++;
				nb_samples ++;
			}
			else if (!pattern_len && (found == prev_offset)) {
				pattern_len = prev_len;
				prev_len = 1;
				nb_samples ++;
			} else {
				if (prev_len > max_id) {
					max_id = prev_len;
				}
				if (prev_len || pattern_len) {
					nb_pattern_entries += 1;
					gf_assert(nb_samples);
#ifdef DUMP_REFS
					pattern_end=GF_TRUE;
#endif
				}
				if (prev_offset > max_id)
					max_id = prev_offset;

				pattern_len = 0;
				prev_offset = found;
				prev_len = 1;
				nb_samples = 1;
#ifdef DUMP_REFS
				pattern_start=GF_TRUE;
#endif
			}
		}

#ifdef DUMP_REFS
		fprintf(stderr, "Sample #%d %d %d refs[", i+1, rent->orig_sampleID, rent->diff_sampleID);
		for (u32 j=0; j<rent->nb_refs; j++) fprintf(stderr, " %d", mode ? rent->orig_sample_refs[j] : rent->sample_refs[j]);
		fprintf(stderr, "] Pattern End %d Start %d", pattern_end, pattern_start);
		if (found>=0)
			fprintf(stderr, " reuse entry #%u", found+1);
		fprintf(stderr, "\n");
#endif

	}
	if (prev_len || pattern_len) {
		nb_pattern_entries += 1;
	}

#ifdef DUMP_STATS
	if (mode==2) {
		*flags = 0;
		cost_refs += 24; //Full box + grouping type + length + nb_entries
		cost_sbgp += 20; //FullBox + grouping_type + nb_entries
		return cost_refs+cost_sbgp;
	}
#endif

	*flags = 0;
	u32 byte_s=1;
	if (max_id > 32767) {
		byte_s=4;
		*flags |= 2;
	}
	else if (max_id > 255) {
		byte_s=2;
		*flags |= 1;
	}
	*total_entries = nb_pattern_entries + nb_direct_entries;

	u32 byte_e=1;
	if (nb_pattern_entries + nb_direct_entries > 32767) {
		byte_e=4;
		*flags |= 8;
	}
	else if (nb_pattern_entries + nb_direct_entries > 255) {
		byte_e=2;
		*flags |= 4;
	}

	//move to bytes
	*cost_full *= byte_s;
	//size+type+flags
	*cost_full += 9;

	if (nb_entries > 32767) *cost_full += 4;
	else if (nb_entries > 255) *cost_full += 2;
	else  *cost_full += 1;

	u32 final_size = 8 + 1 + byte_e;
	final_size += nb_direct_cost * byte_s + nb_pattern_entries * 3 * byte_s;
	if (mode==1) {
		final_size += nb_samples_reused * byte_s;
		*flags |= 16;
	}

#ifdef DUMP_STATS
	if (mode==1) global_patterns_nodiff += nb_pattern_entries;
	else global_patterns_diff += nb_pattern_entries;
#endif

	return final_size;
}
GF_Err cdrf_box_size(GF_SampleReferences *ptr)
{
	if (ptr->cdrf_cache_size) {
		ptr->size = ptr->cdrf_cache_size;
		return GF_OK;
	}
	s32 max_id = 0;
	s32 max_id_nodiff = 0;
	GF_List *refs = cdrf_get_refs(ptr, &max_id, &max_id_nodiff);

	u32 cost_full, nb_entries;
	u8 flags;
#ifdef DUMP_STATS
	//get cost for refs+sbgp
	u32 final_size_refs_sbgp = cdrf_get_cost(refs, 2, max_id_nodiff, &cost_full, &nb_entries, &flags);
#endif
	//get cost in diff mode
	u32 final_size = cdrf_get_cost(refs, 0, max_id, &cost_full, &nb_entries, &flags);

	//get cost in nodiff mode
	u32 nb_entries_nodiff;
	u8 flags_nodiff;
	u32 final_size_nodiff = cdrf_get_cost(refs, 1, max_id_nodiff, &cost_full, &nb_entries_nodiff, &flags_nodiff);

	if (final_size_nodiff < final_size) {
		ptr->size = final_size_nodiff;
		ptr->flags = flags_nodiff;
		ptr->cdrf_entries = nb_entries_nodiff;
	} else {
		ptr->size = final_size;
		ptr->flags = flags;
		ptr->cdrf_entries = nb_entries;
	}
	ptr->cdrf_cache_size = ptr->size;
	cdrf_clean_refs(refs);

#ifdef DUMP_STATS
	global_boxes+=1;
	global_samples+=gf_list_count(ptr->entries);
	global_cost += ptr->size;
	global_cost_full += cost_full;
	global_cost_diff += final_size;
	global_cost_nodiff += final_size_nodiff;
	global_cost_refs_sbgp += final_size_refs_sbgp;
#endif
	return GF_OK;
}

GF_Err sref_box_size(GF_Box *s)
{
	GF_SampleReferences *ptr = (GF_SampleReferences*)s;
	if ((ptr->type!=GF_GPAC_BOX_TYPE_SREF) && gf_opts_get_bool("core", "no-cdrf")) {
		ptr->type = GF_GPAC_BOX_TYPE_SREF;
	}
	if (ptr->type == GF_ISOM_BOX_TYPE_CDRF) {
		return cdrf_box_size(ptr);
	}

	u32 i, j, tot_entries = 0, nb_entries = gf_list_count(ptr->entries), nb_refs=0;
	ptr->size += 4;
	u32 max_size = 1;
	for (i=0; i<nb_entries; i++) {
		GF_SampleRefEntry *ent = gf_list_get(ptr->entries, i);
		if (ent->sampleID==GF_INT_MAX) {
			continue;
		}
		nb_refs++;
		tot_entries += ent->nb_refs;
		if (ent->sampleID >= 0xFFFF) max_size = 4;
		else if (ent->sampleID >= 0xFF) max_size = MAX(2, max_size);
		else max_size = MAX(1, max_size);
		for (j=0; j<ent->nb_refs; j++) {
			if (ent->sample_refs[j] > 0xFFFF) max_size = 4;
			else if (ent->sample_refs[j] > 0xFF) max_size = MAX(2, max_size);
			else max_size = MAX(1, max_size);
		}
	}
	ptr->size += max_size*nb_entries + max_size*nb_refs + max_size*tot_entries;
	if (max_size==4) ptr->flags = 1<<1;
	else if (max_size==2) ptr->flags = 1;
	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE


GF_Box *srat_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SamplingRateBox, GF_ISOM_BOX_TYPE_SRAT);
	return (GF_Box *)tmp;
}

void srat_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err srat_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SamplingRateBox *ptr = (GF_SamplingRateBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4)
	ptr->sampling_rate = gf_bs_read_u32(bs);
	return GF_OK;
}


#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err srat_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SamplingRateBox *ptr = (GF_SamplingRateBox *)s;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->sampling_rate);
	return GF_OK;
}

GF_Err srat_box_size(GF_Box *s)
{
	s->size += 4;
	return GF_OK;
}
#endif // GPAC_DISABLE_ISOM_WRITE

#endif /*GPAC_DISABLE_ISOM*/
