static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, s32 bytes_in_box, u32 entry_size, u32 *total_bytes)
{
	Bool null_size_ok = GF_FALSE;
	GF_DefaultSampleGroupDescriptionEntry *def_ptr;

	switch (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);
		gf_bs_read_int(bs, 7); //reserved
		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_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 (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;
		}
		return ptr;
	}
	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( grouping_type) ));
		return NULL;
	}
	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;

fixed #2092


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

fixed #2092


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

fixed #2092


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

fixed #2092


GF_Box *clap_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP);
	return (GF_Box *)tmp;

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;

fixed #2092


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;

fixed #2092


GF_Box *saio_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
	return (GF_Box *)tmp;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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

fixed #2092


GF_Box *gitn_box_new()
{
	ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN);
	return (GF_Box *)tmp;

fixed #2092


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;

fixed #2092


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
	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;
}

fixed #2092


#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;

fixed #2092


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;

fixed #2092


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

fixed #2092


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

	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;
}

fixed #2092


GF_Box *srpp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP);
	return (GF_Box *)tmp;
}

fixed #2092


void dac3_box_del(GF_Box *s)
{
	GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
	gf_free(ptr);

fixed #2092


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

fixed #2092


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

fixed #2092


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);
}

fixed #2092


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

fixed #2092


void tpay_box_del(GF_Box *s)
{
	gf_free((GF_TPAYBox *)s);
}

fixed #2092


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

fixed #2092


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;
}

fixed #2092


void paen_box_del(GF_Box *s)
{
	gf_free(s);

fixed #2092


void chnl_box_del(GF_Box *s)
{
	gf_free(s);

fixed #2092


GF_Box *svhd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SphericalVideoInfoBox, GF_ISOM_BOX_TYPE_SVHD);
	return (GF_Box *)tmp;

fixed #2092


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;

fixed #2092


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);

fixed #2092


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;
}

fixed #2092


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
	gf_isom_check_position_list(s, 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;
}

fixed #2092


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

fixed #2092


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

fixed #2092


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

fixed #2092


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
	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;
}

fixed #2092


GF_Err void_box_write(GF_Box *s, GF_BitStream *bs)
{
	gf_bs_write_u32(bs, 0);
	return GF_OK;

fixed #2092


#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, 0, 28);
	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;

fixed #2092


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);

fixed #2092


GF_Box *totl_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
	return (GF_Box *)tmp;
}

fixed #2092


GF_Box *npck_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
	return (GF_Box *)tmp;
}

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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;

fixed #2092


GF_Err dmlp_box_size(GF_Box *s)
{
	s->size += 10;
	return GF_OK;

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


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;

fixed #2092


GF_Err dvcC_box_size(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s;

	ptr->size += 24;
	return GF_OK;

fixed #2092


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

fixed #2092


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

fixed #2092


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

fixed #2092


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);
}

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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);
}

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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

fixed #2092


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

fixed #2092


GF_Err dOps_box_size(GF_Box *s)
{
	GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s;
	ptr->size += 11;
	if (ptr->ChannelMappingFamily)
		ptr->size += 2 + ptr->OutputChannelCount;

	return GF_OK;

fixed #2092


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);
}

fixed #2092


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);

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;

fixed #2092


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);
}

fixed #2092


GF_Err chpl_box_read(GF_Box *s,GF_BitStream *bs)
{
	GF_ChapterEntry *ce;
	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(ptr, 9)
		ce->start_time = gf_bs_read_u64(bs);
		len = gf_bs_read_u8(bs);
		if (ptr->size<len) return GF_ISOM_INVALID_FILE;
		if (len) {
			ce->name = (char *)gf_malloc(sizeof(char)*(len+1));
			if (!ce->name) return GF_OUT_OF_MEM;
			ISOM_DECREASE_SIZE(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--;
	}
	return GF_OK;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;

fixed #2092


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;

fixed #2092


GF_Box *dmed_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
	return (GF_Box *)tmp;
}

fixed #2092


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;

fixed #2092


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

fixed #2092


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_list_add(ptr->groups, a);

fixed #2092


#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;

fixed #2092


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;

fixed #2092


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;

fixed #2092


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

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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);
}

fixed #2092


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

fixed #2092


#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dvvC_box_write(GF_Box *s, GF_BitStream *bs)
{
	return dvcC_box_write(s, bs);

fixed #2092


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

fixed #2092


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;

fixed #2092


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;
	}
	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;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;
	gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
	gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
	gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
	gf_bs_write_int(bs, ptr->compositionStartTime, 32);
	gf_bs_write_int(bs, ptr->compositionEndTime, 32);
	return GF_OK;
}

fixed #2092


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->type), ptr->type ));
		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);

	//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);
		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;
}

fixed #2092


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_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;

fixed #2092


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;

fixed #2092


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

fixed #2092


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);

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


GF_Err pasp_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


/*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;

fixed #2092


void sgpd_del_entry(u32 grouping_type, void *entry)
{
	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:
		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;
	}

	default:
	{
		GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
		if (ptr->data) gf_free(ptr->data);
		gf_free(ptr);
	}
	}

fixed #2092


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;
}

fixed #2092


GF_Box *mehd_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
	return (GF_Box *)tmp;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


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;

fixed #2092


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

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


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

fixed #2092


GF_Err stts_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 i;
	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);
#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;

		if (!ptr->entries[i].sampleDelta) {
			if ((i+1<ptr->nb_entries) ) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stts entry with sample_delta=0 - forbidden ! Fixing to 1\n" ));
				ptr->entries[i].sampleDelta = 1;
			} else if (ptr->entries[i].sampleCount>1) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one stts entry at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n" ));
				ptr->entries[i].sampleDelta = 1;
			}
		}
		//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 reimport raw media)\n", i, (s32) ptr->entries[i].sampleDelta ));
			ptr->entries[i].sampleDelta = 1;
		}
#endif

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

	//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;
}

fixed #2092


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;

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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);
	gf_free(ptr);
}

fixed #2092


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_ex(s, bs, GF_ISOM_BOX_TYPE_STSD);
}

fixed #2092


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

fixed #2092


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);

fixed #2092


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;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


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);

fixed #2092


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;
}

fixed #2092


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;

fixed #2092


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;

fixed #2092


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);

fixed #2092


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;

fixed #2092


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

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

fixed #2092


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

fixed #2092


void npck_box_del(GF_Box *s)
{
	gf_free((GF_NPCKBox *)s);
}

fixed #2092


GF_Box *tmin_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
	return (GF_Box *)tmp;
}

fixed #2092


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;

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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);
		}
		ptr = sgpd_parse_entry(p->grouping_type, 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;

fixed #2092


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;

fixed #2092


GF_Box *emsg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMSG);
	return (GF_Box *)tmp;

fixed #2092


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

fixed #2092


GF_Box *dmlp_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrueHDConfigBox, GF_ISOM_BOX_TYPE_DMLP);
	return (GF_Box *)tmp;

fixed #2092


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

fixed #2092


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);

fixed #2092


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;
	e = gf_isom_check_sample_desc(ptr);
	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->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;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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

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

fixed #2092


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);

fixed #2092


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;

fixed #2092


GF_Box *proj_type_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProjectionTypeBox, GF_ISOM_BOX_TYPE_EQUI); //will be overwritten
	return (GF_Box *)tmp;

fixed #2092


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

fixed #2092


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

fixed #2092


void trex_box_del(GF_Box *s)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);

fixed #2092


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;

fixed #2092


GF_Err st3d_box_size(GF_Box *s)
{
	s->size += 1;
	return GF_OK;

fixed #2092


#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;

fixed #2092


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

fixed #2092


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;
}

fixed #2092


void pasp_box_del(GF_Box *s)
{
	GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
	if (ptr == NULL) return;
	gf_free(ptr);

fixed #2092


GF_Box *prft_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
	return (GF_Box *)tmp;

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


u32 gf_isom_ctrn_field_size_bits(u32 field_idx)
{
	if (field_idx==3) return 32;
	return field_idx*8;

fixed #2092


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

fixed #2092


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

fixed #2092


GF_Box *maxr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
	return (GF_Box *)tmp;
}

fixed #2092


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;

fixed #2092


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;
}

fixed #2092


GF_Err mhap_box_size(GF_Box *s)
{
	GF_MHACompatibleProfilesBox *ptr = (GF_MHACompatibleProfilesBox *) s;
	s->size += 1 + ptr->num_profiles;
	return GF_OK;

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


GF_Err pcmC_box_size(GF_Box *s)
{
	s->size += 2;
	return GF_OK;

fixed #2092


GF_Err trex_box_size(GF_Box *s)
{
	GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
	ptr->size += 20;
	return GF_OK;

fixed #2092


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);
	ISOM_DECREASE_SIZE(s, 256)
	gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256);
	ISOM_DECREASE_SIZE(s, 512)
	gf_bs_skip_bytes(bs, 512);
	return GF_OK;

fixed #2092


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

fixed #2092


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;

fixed #2092


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;

fixed #2092


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;

fixed #2092


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;

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


void tpyl_box_del(GF_Box *s)
{
	gf_free((GF_NTYLBox *)s);
}

fixed #2092


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;
}

fixed #2092


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

fixed #2092


GF_Err stvi_box_size(GF_Box *s)
{
	GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;

	ptr->size+= 12 + ptr->sit_len;
	return GF_OK;

fixed #2092


GF_Err trik_box_size(GF_Box *s)
{
	GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
	ptr->size += 8 * ptr->entry_count;
	return GF_OK;

fixed #2092


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);
}

fixed #2092


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;
	}
	return GF_OK;

fixed #2092


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

fixed #2092


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);
}

fixed #2092


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));
	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);

fixed #2092


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

fixed #2092


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;

fixed #2092


GF_Box *pmax_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
	return (GF_Box *)tmp;
}

fixed #2092


GF_Box *pdin_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
	return (GF_Box *)tmp;

fixed #2092


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;
}

fixed #2092


GF_Err void_box_size(GF_Box *s)
{
	s->size = 4;
	return GF_OK;

fixed #2092


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);
}

fixed #2092


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;
}

fixed #2092


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);

fixed #2092


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)
	//our padding bit
	gf_bs_read_int(bs, 1);
	//the spec is unclear here, just says "the value 0 is interpreted as undetermined"
	ptr->packedLanguage[0] = gf_bs_read_int(bs, 5);
	ptr->packedLanguage[1] = gf_bs_read_int(bs, 5);
	ptr->packedLanguage[2] = gf_bs_read_int(bs, 5);
	//but before or after compaction ?? We assume before
	if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) {
		ptr->packedLanguage[0] += 0x60;
		ptr->packedLanguage[1] += 0x60;
		ptr->packedLanguage[2] += 0x60;
	} else {
		ptr->packedLanguage[0] = 'u';
		ptr->packedLanguage[1] = 'n';
		ptr->packedLanguage[2] = 'd';
	}
	ptr->reserved = gf_bs_read_u16(bs);
	return GF_OK;
}

fixed #2092


GF_Err vmhd_box_size(GF_Box *s)
{
	GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
	ptr->size += 8;
	return GF_OK;

fixed #2092


GF_Err sdtp_box_size(GF_Box *s)
{
	GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
	ptr->size += ptr->sampleCount;
	return GF_OK;

fixed #2092


void nump_box_del(GF_Box *s)
{
	gf_free((GF_NUMPBox *)s);
}

fixed #2092


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

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


GF_Box *nump_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
	return (GF_Box *)tmp;
}

fixed #2092


GF_Err name_box_size(GF_Box *s)
{
	GF_NameBox *ptr = (GF_NameBox *)s;
	if (ptr->string) ptr->size += strlen(ptr->string) + 1;
	return GF_OK;
}

fixed #2092


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);

	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;

fixed #2092


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

fixed #2092


}
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 gorup 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 gorup 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;

	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;
		}
		if ( (u64)ptr->patterns[i].length > (u64)SIZE_MAX/sizeof(u32) ) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] compact sample gorup 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;

fixed #2092


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

fixed #2092


void dvvC_box_del(GF_Box *s)
{
	GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s;
	gf_free(ptr);

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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;
}

fixed #2092


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

fixed #2092


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;

fixed #2092


GF_Box *mvcg_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_MultiviewGroupBox, GF_ISOM_BOX_TYPE_MVCG);
	return (GF_Box *)tmp;

fixed #2092


GF_Err reftype_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
	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;

fixed #2092


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);

fixed #2092