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

#include <gpac/internal/odf_dev.h>
#include <gpac/utf.h>

#define DATE_CODING_LEN 5

#ifndef GPAC_MINIMAL_ODF

static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool isUTF8, u32 *read)
{
	u32 len;
	*read = 1;
	len = gf_bs_read_int(bs, 8) + 1;
	if (gf_bs_available(bs) < len) return GF_BAD_PARAM;
	if (!isUTF8) len *= 2;
	(*string) = (char *) gf_malloc(sizeof(char)*(len+1));
	if (! (*string) ) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, (*string), len);
	(*string)[len] = 0;
	*read += len;
	return GF_OK;
}

static GFINLINE u32 OD_SizeUTF8String(char *string, Bool isUTF8)
{
	if (isUTF8) return 1 + (u32) strlen(string);
	return 1 + 2 * gf_utf8_wcslen((const unsigned short *)string);
}

static GFINLINE void OD_WriteUTF8String(GF_BitStream *bs, char *string, Bool isUTF8)
{
	u32 len;
	if (isUTF8) {
		len = (u32) strlen(string);
		gf_bs_write_int(bs, len, 8);
		gf_bs_write_data(bs, string, len);
	} else {
		len = gf_utf8_wcslen((const unsigned short *)string);
		gf_bs_write_int(bs, len, 8);
		gf_bs_write_data(bs, string, len*2);
	}
}

#endif // GPAC_MINIMAL_ODF

/*use to parse strings read the length as well - Warning : the alloc is done here !!*/
GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes)
{
	u32 length;
	*readBytes = 0;

	/*if the string is not NULL, return an error...*/
	if (*string != NULL) return GF_BAD_PARAM;

	/*the len is always on 8 bits*/
	length = gf_bs_read_int(bs, 8);
	*readBytes = 1;
	/*JLF AMD to MPEG-4 systems :) - This is not conformant at all, just hoping MPEG will accept it soon
	since 255bytes URL is a real pain in the neck*/
	if (!length) {
		length = gf_bs_read_int(bs, 32);
		*readBytes += 4;
		if (length>0xFFFF) return GF_ODF_INVALID_DESCRIPTOR;
	}
	/*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
	(*string) = (char *) gf_malloc(length + 1);
	if (! *string) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, (*string), length);
	*readBytes += length;
	(*string)[length] = 0;
	return GF_OK;
}

/*writes string*/
GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
{
	u32 len;
	/*we accept NULL strings now*/
	if (!string) {
		gf_bs_write_int(bs, 0, 8);
		return GF_OK;
	}
	len = (u32) strlen(string);
	if (len > 255) {
		gf_bs_write_int(bs, 0, 8);
		gf_bs_write_int(bs, len, 32);
	} else {
		gf_bs_write_int(bs, len, 8);
	}
	gf_bs_write_data(bs, string, len);
	return GF_OK;
}

u32 gf_odf_size_url_string(char *string)
{
	u32 len = (u32) strlen(string);
	if (len>255) return len+5;
	return len+1;
}

GF_Descriptor *gf_odf_new_esd()
{
	GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_ESD));
	newDesc->IPIDataSet = gf_list_new();
	newDesc->IPMPDescriptorPointers = gf_list_new();
	newDesc->extensionDescriptors = gf_list_new();
	newDesc->tag = GF_ODF_ESD_TAG;
	return (GF_Descriptor *) newDesc;
}


GF_Err gf_odf_del_esd(GF_ESD *esd)
{
	GF_Err e;
	if (!esd) return GF_BAD_PARAM;
	if (esd->URLString)	gf_free(esd->URLString);

	if (esd->decoderConfig)	{
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig);
		if (e) return e;
	}
	if (esd->slConfig) {
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->slConfig);
		if (e) return e;
	}
	if (esd->ipiPtr) {
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->ipiPtr);
		if (e) return e;
	}
	if (esd->qos) {
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->qos);
		if (e) return e;
	}
	if (esd->RegDescriptor)	{
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->RegDescriptor);
		if (e) return e;
	}
	if (esd->langDesc)	{
		e = gf_odf_delete_descriptor((GF_Descriptor *) esd->langDesc);
		if (e) return e;
	}

	e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
	if (e) return e;
	gf_free(esd);
	return GF_OK;
}


GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
{
	if (!esd || !desc) return GF_BAD_PARAM;

	switch (desc->tag) {
	case GF_ODF_DCD_TAG:
		if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
		esd->decoderConfig = (GF_DecoderConfig *) desc;
		break;

	case GF_ODF_SLC_TAG:
		if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
		esd->slConfig = (GF_SLConfig *) desc;
		break;

	case GF_ODF_MUXINFO_TAG:
		gf_list_add(esd->extensionDescriptors, desc);
		break;

	case GF_ODF_LANG_TAG:
		if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
		esd->langDesc = (GF_Language *) desc;
		break;

#ifndef GPAC_MINIMAL_ODF
	//the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG...
	case GF_ODF_ISOM_IPI_PTR_TAG:
	case GF_ODF_IPI_PTR_TAG:
		if (esd->ipiPtr) return GF_ODF_INVALID_DESCRIPTOR;
		esd->ipiPtr = (GF_IPIPtr *) desc;
		break;

	case GF_ODF_QOS_TAG:
		if (esd->qos) return GF_ODF_INVALID_DESCRIPTOR;
		esd->qos  =(GF_QoS_Descriptor *) desc;
		break;

	case GF_ODF_CI_TAG:
	case GF_ODF_SCI_TAG:
		return gf_list_add(esd->IPIDataSet, desc);

	//we use the same struct for v1 and v2 IPMP DPs
	case GF_ODF_IPMP_PTR_TAG:
		return gf_list_add(esd->IPMPDescriptorPointers, desc);

	case GF_ODF_REG_TAG:
		if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR;
		esd->RegDescriptor =(GF_Registration *) desc;
		break;
#endif

	default:
		if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
		        (desc->tag <= GF_ODF_EXT_END_TAG) ) {
			return gf_list_add(esd->extensionDescriptors, desc);
		}
		return GF_BAD_PARAM;
	}

	return GF_OK;
}

GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
{
	GF_Err e = GF_OK;
	u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;

	if (! esd) return GF_BAD_PARAM;

	nbBytes = 0;

	esd->ESID = gf_bs_read_int(bs, 16);
	streamdependflag = gf_bs_read_int(bs, 1);
	urlflag = gf_bs_read_int(bs, 1);
	ocrflag = gf_bs_read_int(bs, 1);
	esd->streamPriority = gf_bs_read_int(bs, 5);
	nbBytes += 3;

	if (streamdependflag) {
		esd->dependsOnESID = gf_bs_read_int(bs, 16);
		nbBytes += 2;
	}

	if (urlflag) {
		e = gf_odf_read_url_string(bs, & esd->URLString, &read);
		if (e) return e;
		nbBytes += read;
	}
	if (ocrflag) {
		esd->OCRESID = gf_bs_read_int(bs, 16);
		nbBytes += 2;
	}

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
		/*fix for iPod files*/
		if (e==GF_ODF_INVALID_DESCRIPTOR) {
			nbBytes += tmp_size;
			if (nbBytes>DescSize) return e;
			gf_bs_read_int(bs, DescSize-nbBytes);
			return GF_OK;
		}
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = AddDescriptorToESD(esd, tmp);
		if (e) {
			gf_odf_desc_del(tmp);
			return e;
		}
		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);

		//apple fix
		if (!tmp_size) nbBytes = DescSize;

	}
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return e;

}

GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
{
	GF_Err e;
	u32 tmpSize;
	if (! esd) return GF_BAD_PARAM;

	*outSize = 0;
	*outSize += 3;

	if (esd->dependsOnESID) *outSize += 2;
	if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
	if (esd->OCRESID) *outSize += 2;

	if (esd->decoderConfig) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->decoderConfig, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (esd->slConfig) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->slConfig, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (esd->ipiPtr) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->ipiPtr, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (esd->langDesc) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->langDesc, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}

	e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
	if (e) return e;
	e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
	if (e) return e;
	if (esd->qos) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->qos, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (esd->RegDescriptor) {
		e = gf_odf_size_descriptor((GF_Descriptor *) esd->RegDescriptor, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
}

GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
{
	GF_Err e;
	u32 size;
	if (! esd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, esd->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, esd->ESID, 16);
	gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
	gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
	gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
	gf_bs_write_int(bs, esd->streamPriority, 5);

	if (esd->dependsOnESID) {
		gf_bs_write_int(bs, esd->dependsOnESID, 16);
	}
	if (esd->URLString) {
		e = gf_odf_write_url_string(bs, esd->URLString);
		if (e) return e;
	}


	if (esd->OCRESID) {
		gf_bs_write_int(bs, esd->OCRESID, 16);
	}
	if (esd->decoderConfig) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->decoderConfig);
		if (e) return e;
	}
	if (esd->slConfig) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->slConfig);
		if (e) return e;
	}
	if (esd->ipiPtr) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->ipiPtr);
		if (e) return e;
	}
	if (esd->langDesc) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->langDesc);
		if (e) return e;
	}

	e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
	if (e) return e;
	e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
	if (e) return e;
	if (esd->qos) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->qos);
		if (e) return e;
	}
	if (esd->RegDescriptor) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->RegDescriptor);
		if (e) return e;
	}
	return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
}

GF_Descriptor *gf_odf_new_iod()
{
	GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));

	newDesc->ESDescriptors = gf_list_new();
	newDesc->OCIDescriptors = gf_list_new();
	newDesc->IPMP_Descriptors = gf_list_new();

	newDesc->extensionDescriptors = gf_list_new();
	newDesc->tag = GF_ODF_IOD_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
{
	GF_Err e;
	if (!iod) return GF_BAD_PARAM;
	if (iod->URLString)	gf_free(iod->URLString);
	e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
	if (e) return e;
	if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
	gf_free(iod);
	return GF_OK;
}

GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
{
	if (!iod || !desc) return GF_BAD_PARAM;

	switch (desc->tag) {
	case GF_ODF_ESD_TAG:
		return gf_list_add(iod->ESDescriptors, desc);

	//we use the same struct for v1 and v2 IPMP DPs
	case GF_ODF_IPMP_PTR_TAG:
	/*IPMPX*/
	case GF_ODF_IPMP_TAG:
		return gf_list_add(iod->IPMP_Descriptors, desc);

	/*IPMPX*/
	case GF_ODF_IPMP_TL_TAG:
		if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
		iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
		return GF_OK;

	default:
		break;
	}
	if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
	if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
	return GF_BAD_PARAM;
}

GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
{
	GF_Err e;
	u32 urlflag, read;
	u32 tmp_size, nbBytes = 0;
	if (! iod) return GF_BAD_PARAM;

	iod->objectDescriptorID = gf_bs_read_int(bs, 10);
	urlflag = gf_bs_read_int(bs, 1);
	iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 4);
	nbBytes += 2;

	if (urlflag) {
		e = gf_odf_read_url_string(bs, & iod->URLString, &read);
		if (e) return e;
		nbBytes += read;
	} else {
		iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
		nbBytes += 5;
	}

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = AddDescriptorToIOD(iod, tmp);
		if (e) {
			gf_odf_delete_descriptor(tmp);
			return e;
		}
		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
	}
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
{
	GF_Err e;
	if (! iod) return GF_BAD_PARAM;

	*outSize = 0;
	*outSize += 2;
	if (iod->URLString) {
		*outSize += gf_odf_size_url_string(iod->URLString);
	} else {
		*outSize += 5;
		e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
		if (e) return e;

	}
	e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
	if (e) return e;
	if (iod->IPMPToolList) {
		u32 tmpSize;
		e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	return GF_OK;
}

GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
{
	GF_Err e;
	u32 size;
	if (! iod) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, iod->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, iod->objectDescriptorID, 10);
	gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
	gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
	gf_bs_write_int(bs, 15, 4);		//reserved: 0b1111 == 15

	if (iod->URLString) {
		gf_odf_write_url_string(bs, iod->URLString);
	} else {
		gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
		e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
		if (e) return e;
		if (iod->IPMPToolList) {
			e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
			if (e) return e;
		}
	}
	return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
}



GF_Descriptor *gf_odf_new_od()
{
	GF_ObjectDescriptor *newDesc;
	GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
	if (!newDesc) return NULL;

	newDesc->URLString = NULL;
	newDesc->ESDescriptors = gf_list_new();
	newDesc->OCIDescriptors = gf_list_new();
	newDesc->IPMP_Descriptors = gf_list_new();
	newDesc->extensionDescriptors = gf_list_new();
	newDesc->objectDescriptorID = 0;
	newDesc->tag = GF_ODF_OD_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
{
	GF_Err e;
	if (!od) return GF_BAD_PARAM;
	if (od->URLString)	gf_free(od->URLString);
	e = gf_odf_delete_descriptor_list(od->ESDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
	if (e) return e;
	gf_free(od);
	return GF_OK;
}

GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
{
	if (!od || !desc) return GF_BAD_PARAM;

	//check if we can handle ContentClassif tags
	if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
	        (desc->tag <= GF_ODF_OCI_END_TAG) ) {
		return gf_list_add(od->OCIDescriptors, desc);
	}

	//or extensions
	if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
	        (desc->tag <= GF_ODF_EXT_END_TAG) ) {
		return gf_list_add(od->extensionDescriptors, desc);
	}

	//to cope with envivio
	switch (desc->tag) {
	case GF_ODF_ESD_TAG:
	case GF_ODF_ESD_REF_TAG:
		return gf_list_add(od->ESDescriptors, desc);

	//we use the same struct for v1 and v2 IPMP DPs
	case GF_ODF_IPMP_PTR_TAG:
	case GF_ODF_IPMP_TAG:
		return gf_list_add(od->IPMP_Descriptors, desc);

	default:
		return GF_BAD_PARAM;
	}
}

GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
{
	GF_Err e;
	u32 urlflag;
	u32 tmpSize, nbBytes = 0;
	if (! od) return GF_BAD_PARAM;

	od->objectDescriptorID = gf_bs_read_int(bs, 10);
	urlflag = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 5);
	nbBytes += 2;

	if (urlflag) {
		u32 read;
		e = gf_odf_read_url_string(bs, & od->URLString, &read);
		if (e) return e;
		nbBytes += read;
	}

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = AddDescriptorToOD(od, tmp);
		if (e) {
			gf_odf_desc_del(tmp);
			return e;
		}
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
{
	GF_Err e;
	if (! od) return GF_BAD_PARAM;

	*outSize = 2;
	if (od->URLString) {
		*outSize += gf_odf_size_url_string(od->URLString);
	} else {
		e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
		if (e) return e;
	}
	return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
}

GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
{
	GF_Err e;
	u32 size;
	if (! od) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, od->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, od->objectDescriptorID, 10);
	gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
	gf_bs_write_int(bs, 31, 5);		//reserved: 0b1111.1 == 31

	if (od->URLString) {
		gf_odf_write_url_string(bs, od->URLString);
	} else {
		e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
		if (e) return e;
	}
	return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
}

GF_Descriptor *gf_odf_new_isom_iod()
{
	GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));

	newDesc->ES_ID_IncDescriptors = gf_list_new();
	newDesc->ES_ID_RefDescriptors = gf_list_new();
	newDesc->OCIDescriptors = gf_list_new();
	newDesc->IPMP_Descriptors = gf_list_new();
	newDesc->extensionDescriptors = gf_list_new();
	newDesc->tag = GF_ODF_ISOM_IOD_TAG;

	//by default create an IOD with no inline and no capabilities
	newDesc->audio_profileAndLevel = 0xFF;
	newDesc->graphics_profileAndLevel = 0xFF;
	newDesc->scene_profileAndLevel = 0xFF;
	newDesc->OD_profileAndLevel = 0xFF;
	newDesc->visual_profileAndLevel = 0xFF;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
{
	GF_Err e;
	if (!iod) return GF_BAD_PARAM;
	if (iod->URLString)	gf_free(iod->URLString);
	e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
	if (e) return e;
	if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
	gf_free(iod);
	return GF_OK;
}

GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
{
	if (!iod || !desc) return GF_BAD_PARAM;

	switch (desc->tag) {
	case GF_ODF_ESD_TAG:
		return GF_ODF_FORBIDDEN_DESCRIPTOR;

	case GF_ODF_ESD_INC_TAG:
		//there shouldn't be ref if inc
		if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
		return gf_list_add(iod->ES_ID_IncDescriptors, desc);

	case GF_ODF_ESD_REF_TAG:
		//there shouldn't be inc if ref
		if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
		return gf_list_add(iod->ES_ID_RefDescriptors, desc);

	//we use the same struct for v1 and v2 IPMP DPs
	case GF_ODF_IPMP_PTR_TAG:
	case GF_ODF_IPMP_TAG:
		return gf_list_add(iod->IPMP_Descriptors, desc);

	/*IPMPX*/
	case GF_ODF_IPMP_TL_TAG:
		if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
		iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
		return GF_OK;

	default:
		break;
	}
	//check if we can handle ContentClassif tags
	if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
	//or extensions
	if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
	return GF_BAD_PARAM;
}

GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
{
	u32 nbBytes = 0, tmpSize;
	u32 urlflag;
	GF_Err e;
	if (! iod) return GF_BAD_PARAM;

	iod->objectDescriptorID = gf_bs_read_int(bs, 10);
	urlflag = gf_bs_read_int(bs, 1);
	iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 4);
	nbBytes += 2;

	if (urlflag) {
		u32 read;
		e = gf_odf_read_url_string(bs, & iod->URLString, &read);
		if (e) return e;
		nbBytes += read;
	} else {
		iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
		iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
		nbBytes += 5;
	}

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) {
			if (tmp) gf_odf_desc_del((GF_Descriptor *) tmp);
			return e;
		}
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = AddDescriptorToIsomIOD(iod, tmp);
		if (e) {
			gf_odf_desc_del(tmp);
			return e;
		}
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
{
	GF_Err e;
	if (! iod) return GF_BAD_PARAM;

	*outSize = 2;
	if (iod->URLString) {
		*outSize += gf_odf_size_url_string(iod->URLString);
	} else {
		*outSize += 5;
		e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
		if (e) return e;
	}
	if (iod->IPMPToolList) {
		u32 tmpSize;
		e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
}

GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
{
	GF_Err e;
	u32 size;
	if (! iod) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, iod->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, iod->objectDescriptorID, 10);
	gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
	gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
	gf_bs_write_int(bs, 15, 4);		//reserved: 0b1111 == 15

	if (iod->URLString) {
		gf_odf_write_url_string(bs, iod->URLString);
	} else {
		gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
		gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
		e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
		if (e) return e;
		if (iod->IPMPToolList) {
			e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
			if (e) return e;
		}
	}
	e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
	if (e) return e;
	return GF_OK;
}


GF_Descriptor *gf_odf_new_isom_od()
{
	GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor));
	if (!newDesc) return NULL;

	newDesc->URLString = NULL;
	newDesc->ES_ID_IncDescriptors = gf_list_new();
	newDesc->ES_ID_RefDescriptors = gf_list_new();
	newDesc->OCIDescriptors = gf_list_new();
	newDesc->IPMP_Descriptors = gf_list_new();
	newDesc->extensionDescriptors = gf_list_new();
	newDesc->objectDescriptorID = 0;
	newDesc->tag = GF_ODF_ISOM_OD_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
{
	GF_Err e;
	if (!od) return GF_BAD_PARAM;
	if (od->URLString)	gf_free(od->URLString);
	e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
	if (e) return e;
	e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
	if (e) return e;
	gf_free(od);
	return GF_OK;
}

GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
{
	if (!od || !desc) return GF_BAD_PARAM;

	//check if we can handle ContentClassif tags
	if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
	        (desc->tag <= GF_ODF_OCI_END_TAG) ) {
		return gf_list_add(od->OCIDescriptors, desc);
	}

	//or extension ...
	if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
	        (desc->tag <= GF_ODF_EXT_END_TAG) ) {
		return gf_list_add(od->extensionDescriptors, desc);
	}

	switch (desc->tag) {
	case GF_ODF_ESD_TAG:
		return GF_ODF_FORBIDDEN_DESCRIPTOR;

	case GF_ODF_ESD_INC_TAG:
		//there shouldn't be ref if inc
		if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
		return gf_list_add(od->ES_ID_IncDescriptors, desc);

	case GF_ODF_ESD_REF_TAG:
		//there shouldn't be inc if ref
		if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
		return gf_list_add(od->ES_ID_RefDescriptors, desc);

	//we use the same struct for v1 and v2 IPMP DPs
	case GF_ODF_IPMP_PTR_TAG:
	case GF_ODF_IPMP_TAG:
		return gf_list_add(od->IPMP_Descriptors, desc);

	default:
		return GF_BAD_PARAM;
	}
}

GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
{
	GF_Err e;
	u32 urlflag;
	u32 tmpSize, nbBytes = 0;
	if (! od) return GF_BAD_PARAM;

	od->objectDescriptorID = gf_bs_read_int(bs, 10);
	urlflag = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 5);
	nbBytes += 2;

	if (urlflag) {
		u32 read;
		e = gf_odf_read_url_string(bs, & od->URLString, &read);
		if (e) return e;
		nbBytes += read;
	}

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = AddDescriptorToIsomOD(od, tmp);
		if (e) {
			gf_odf_delete_descriptor(tmp);
			return e;
		}
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
{
	GF_Err e;
	if (! od) return GF_BAD_PARAM;

	*outSize = 2;
	if (od->URLString) {
		*outSize += gf_odf_size_url_string(od->URLString);
	} else {
		e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
		if (e) return e;
		e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
		if (e) return e;
	}
	return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
}

GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
{
	GF_Err e;
	u32 size;
	if (! od) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, od->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, od->objectDescriptorID, 10);
	gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
	gf_bs_write_int(bs, 31, 5);		//reserved: 0b1111.1 == 31

	if (od->URLString) {
		gf_odf_write_url_string(bs, od->URLString);
	} else {
		e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
		if (e) return e;
		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
		if (e) return e;
	}
	e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
	if (e) return e;
	return GF_OK;
}



GF_Descriptor *gf_odf_new_dcd()
{
	GF_DecoderConfig *newDesc;
	GF_SAFEALLOC(newDesc, GF_DecoderConfig);
	if (!newDesc) return NULL;

	newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
	newDesc->tag = GF_ODF_DCD_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
{
	GF_Err e;
	if (!dcd) return GF_BAD_PARAM;
	if (dcd->decoderSpecificInfo) {
		e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo);
		if (e) return e;
	}
	if (dcd->rvc_config) {
		e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->rvc_config);
		if (e) return e;
	}
	e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
	if (e) return e;
	gf_free(dcd);
	return GF_OK;
}

GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize)
{
	GF_Err e;
	u32 /*reserved, */tmp_size, nbBytes = 0;
	if (! dcd) return GF_BAD_PARAM;

	dcd->objectTypeIndication = gf_bs_read_int(bs, 8);
	dcd->streamType = gf_bs_read_int(bs, 6);
	dcd->upstream = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 1);
	dcd->bufferSizeDB = gf_bs_read_int(bs, 24);
	dcd->maxBitrate = gf_bs_read_int(bs, 32);
	dcd->avgBitrate = gf_bs_read_int(bs, 32);
	nbBytes += 13;

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		switch (tmp->tag) {
		case GF_ODF_DSI_TAG:
			if (dcd->decoderSpecificInfo) {
				gf_odf_delete_descriptor(tmp);
				return GF_ODF_INVALID_DESCRIPTOR;
			}
			dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp;
			break;

		case GF_ODF_EXT_PL_TAG:
			e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
			if (e < GF_OK) {
				gf_odf_delete_descriptor(tmp);
				return e;
			}
			break;

		/*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI,
		loading will abort with a partially valid ESD which is all the matters*/
		case GF_ODF_SLC_TAG:
			gf_odf_delete_descriptor(tmp);
			return GF_OK;

		//what the hell is this descriptor ?? Don't know, so delete it !
		default:
			gf_odf_delete_descriptor(tmp);
			break;
		}
		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
	}
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

#include <gpac/constants.h>

GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
{
	GF_Err e;
	u32 tmpSize;
	u32 oti;
	if (! dcd) return GF_BAD_PARAM;

	oti = dcd->objectTypeIndication;
	if (oti > 0xFF) {
		oti = gf_codecid_oti(oti);
	}
	if (oti > 0xFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
		return GF_BAD_PARAM;
	}

	*outSize = 0;
	*outSize += 13;
	if (dcd->decoderSpecificInfo) {
		//warning: we don't know anything about the structure of a generic DecSpecInfo
		//we check the tag and size of the descriptor, but we most ofthe time can't parse it
		//the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....)
		e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize);
		if (e) return e;
		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
	if (e) return e;
	return GF_OK;
}

GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
{
	GF_Err e;
	u32 size, oti;
	if (! dcd) return GF_BAD_PARAM;

	oti = dcd->objectTypeIndication;
	if (oti > 0xFF) {
		oti = gf_codecid_oti(oti);
	}
	if (oti > 0xFF) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
		return GF_BAD_PARAM;
	}

	e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, oti, 8);
	gf_bs_write_int(bs, dcd->streamType, 6);
	gf_bs_write_int(bs, dcd->upstream, 1);
	gf_bs_write_int(bs, 1, 1);	//reserved field...
	gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
	gf_bs_write_int(bs, dcd->maxBitrate, 32);
	gf_bs_write_int(bs, dcd->avgBitrate, 32);

	if (dcd->decoderSpecificInfo) {
		e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo);
		if (e) return e;
	}
	e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
	return e;
}


GF_Descriptor *gf_odf_new_default()
{
	GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor));
	if (!newDesc) return NULL;

	newDesc->dataLength = 0;
	newDesc->data = NULL;
	//set it to the Max allowed
	newDesc->tag = GF_ODF_USER_END_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
{
	if (!dd) return GF_BAD_PARAM;

	if (dd->data) gf_free(dd->data);
	gf_free(dd);
	return GF_OK;
}

GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! dd) return GF_BAD_PARAM;

	dd->dataLength = DescSize;
	dd->data = NULL;
	if (DescSize) {
		dd->data = (char*)gf_malloc(dd->dataLength);
		if (! dd->data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, dd->data, dd->dataLength);
		nbBytes += dd->dataLength;
		/* internal tags are read as default but deleted as their own types
		   so dd->data would leak here */
		if ((dd->tag>=GF_ODF_MUXINFO_TAG) && (dd->tag<=GF_ODF_LASER_CFG_TAG)) {
			gf_free(dd->data);
			dd->data = NULL;
		}
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
{
	if (! dd) return GF_BAD_PARAM;
	*outSize  = dd->dataLength;
	return GF_OK;
}

GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
{
	GF_Err e;
	u32 size;
	if (! dd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, dd->tag, size);
	if (e) return e;

	if (dd->data) {
		gf_bs_write_data(bs, dd->data, dd->dataLength);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_esd_inc()
{
	GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc));
	if (!newDesc) return NULL;
	newDesc->tag = GF_ODF_ESD_INC_TAG;
	newDesc->trackID = 0;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
{
	if (!esd_inc) return GF_BAD_PARAM;
	gf_free(esd_inc);
	return GF_OK;
}
GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! esd_inc) return GF_BAD_PARAM;

	esd_inc->trackID = gf_bs_read_int(bs, 32);
	nbBytes += 4;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}
GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
{
	if (! esd_inc) return GF_BAD_PARAM;
	*outSize = 4;
	return GF_OK;
}
GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
{
	GF_Err e;
	u32 size;
	if (! esd_inc) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, esd_inc->trackID, 32);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_esd_ref()
{
	GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref));
	if (!newDesc) return NULL;
	newDesc->tag = GF_ODF_ESD_REF_TAG;
	newDesc->trackRef = 0;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
{
	if (!esd_ref) return GF_BAD_PARAM;
	gf_free(esd_ref);
	return GF_OK;
}
GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! esd_ref) return GF_BAD_PARAM;

	esd_ref->trackRef = gf_bs_read_int(bs, 16);
	nbBytes += 2;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
{
	if (! esd_ref) return GF_BAD_PARAM;
	*outSize = 2;
	return GF_OK;
}
GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
{
	GF_Err e;
	u32 size;
	if (! esd_ref) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, esd_ref->trackRef, 16);
	return GF_OK;
}



GF_Descriptor *gf_odf_new_segment()
{
	GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment));
	if (!newDesc) return NULL;

	memset(newDesc, 0, sizeof(GF_Segment));
	newDesc->tag = GF_ODF_SEGMENT_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_segment(GF_Segment *sd)
{
	if (!sd) return GF_BAD_PARAM;

	if (sd->SegmentName) gf_free(sd->SegmentName);
	gf_free(sd);
	return GF_OK;
}

GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
{
	u32 size, nbBytes = 0;
	if (!sd) return GF_BAD_PARAM;

	sd->startTime = gf_bs_read_double(bs);
	sd->Duration = gf_bs_read_double(bs);
	nbBytes += 16;
	size = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	if (size) {
		sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1));
		if (!sd->SegmentName) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, sd->SegmentName, size);
		sd->SegmentName[size] = 0;
		nbBytes += size;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
{
	if (!sd) return GF_BAD_PARAM;
	*outSize = 17;
	if (sd->SegmentName) *outSize += (u32) strlen(sd->SegmentName);
	return GF_OK;
}

GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
{
	GF_Err e;
	u32 size;
	if (!sd) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, sd->tag, size);
	if (e) return e;
	gf_bs_write_double(bs, sd->startTime);
	gf_bs_write_double(bs, sd->Duration);
	if (sd->SegmentName) {
		gf_bs_write_int(bs, (u32) strlen(sd->SegmentName), 8);
		gf_bs_write_data(bs, sd->SegmentName, (u32) strlen(sd->SegmentName));
	} else {
		gf_bs_write_int(bs, 0, 8);
	}
	return GF_OK;
}



GF_Descriptor *gf_odf_new_lang()
{
	GF_Language *newDesc;
	GF_SAFEALLOC(newDesc, GF_Language);
	if (!newDesc) return NULL;
	newDesc->tag = GF_ODF_LANG_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_lang(GF_Language *ld)
{
	if (!ld) return GF_BAD_PARAM;
	if (ld->full_lang_code) gf_free(ld->full_lang_code);
	gf_free(ld);
	return GF_OK;
}

GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!ld) return GF_BAD_PARAM;

	ld->langCode = gf_bs_read_int(bs, 24);
	nbBytes += 3;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
{
	if (!ld) return GF_BAD_PARAM;
	*outSize = 3;
	return GF_OK;
}

GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
{
	GF_Err e;
	u32 size;
	if (!ld) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ld->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, ld->langCode, 24);
	return GF_OK;
}



GF_Descriptor *gf_odf_new_auxvid()
{
	GF_AuxVideoDescriptor *newDesc;
	GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
	if (!newDesc) return NULL;
	newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
{
	if (!ld) return GF_BAD_PARAM;
	gf_free(ld);
	return GF_OK;
}

GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!ld) return GF_BAD_PARAM;

	ld->aux_video_type = gf_bs_read_int(bs, 8);
	ld->position_offset_h = gf_bs_read_int(bs, 8);
	ld->position_offset_v = gf_bs_read_int(bs, 8);
	nbBytes += 3;
	switch (ld->aux_video_type) {
	case 0x10:
		ld->kfar = gf_bs_read_int(bs, 8);
		ld->knear = gf_bs_read_int(bs, 8);
		nbBytes += 2;
		break;
	case 0x11:
		ld->parallax_zero = gf_bs_read_int(bs, 16);
		ld->parallax_scale = gf_bs_read_int(bs, 16);
		ld->dref = gf_bs_read_int(bs, 16);
		ld->wref = gf_bs_read_int(bs, 16);
		nbBytes += 8;
		break;
	}
	while (nbBytes < DescSize) {
		gf_bs_read_int(bs, 8);
		nbBytes ++;
	}
	return GF_OK;
}

GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
{
	if (!ld) return GF_BAD_PARAM;
	switch (ld->aux_video_type) {
	case 0x10:
		*outSize = 5;
		break;
	case 0x11:
		*outSize = 11;
		break;
	default:
		*outSize = 3;
		break;
	}
	return GF_OK;
}

GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
{
	GF_Err e;
	u32 size;
	if (!ld) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ld->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, ld->aux_video_type, 8);
	gf_bs_write_int(bs, ld->position_offset_h, 8);
	gf_bs_write_int(bs, ld->position_offset_v, 8);
	switch (ld->aux_video_type) {
	case 0x10:
		gf_bs_write_int(bs, ld->kfar, 8);
		gf_bs_write_int(bs, ld->knear, 8);
		break;
	case 0x11:
		gf_bs_write_int(bs, ld->parallax_zero, 16);
		gf_bs_write_int(bs, ld->parallax_scale, 16);
		gf_bs_write_int(bs, ld->dref, 16);
		gf_bs_write_int(bs, ld->wref, 16);
		break;
	}
	return GF_OK;
}



GF_Descriptor *gf_odf_new_muxinfo()
{
	GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_MuxInfo));
	newDesc->tag = GF_ODF_MUXINFO_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
{
	if (!mi) return GF_BAD_PARAM;
	if (mi->file_name) gf_free(mi->file_name);
	if (mi->src_url) gf_free(mi->src_url);
	if (mi->streamFormat) gf_free(mi->streamFormat);
	if (mi->textNode) gf_free(mi->textNode);
	if (mi->fontNode) gf_free(mi->fontNode);
	gf_free(mi);
	return GF_OK;
}

GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize)
{
	*outSize = 0;
	return GF_OK;
}
GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi)
{
	return GF_OK;
}

GF_Descriptor *gf_odf_New_ElemMask()
{
	GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_ElementaryMask));
	newDesc->tag = GF_ODF_ELEM_MASK_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
{
	if (desc->node_name) gf_free(desc->node_name);
	gf_free(desc);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_bifs_cfg()
{
	GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_BIFSConfig));
	newDesc->tag = GF_ODF_BIFS_CFG_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
{
	if (desc->elementaryMasks) {
		u32 i, count = gf_list_count(desc->elementaryMasks);
		for (i=0; i<count; i++) {
			GF_ElementaryMask *tmp = (GF_ElementaryMask *)gf_list_get(desc->elementaryMasks, i);
			if (tmp->node_name) gf_free(tmp->node_name);
			gf_free(tmp);
		}
		gf_list_del(desc->elementaryMasks);
	}
	gf_free(desc);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_laser_cfg()
{
	GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_LASERConfig));
	newDesc->tag = GF_ODF_LASER_CFG_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
{
	gf_free(desc);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_ui_cfg()
{
	GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_UIConfig));
	newDesc->tag = GF_ODF_UI_CFG_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
{
	if (desc->deviceName) gf_free(desc->deviceName);
	if (desc->ui_data) gf_free(desc->ui_data);
	gf_free(desc);
	return GF_OK;
}

#ifndef GPAC_MINIMAL_ODF

GF_Descriptor *gf_odf_new_mediatime()
{
	GF_MediaTime *newDesc = (GF_MediaTime *) gf_malloc(sizeof(GF_MediaTime));
	if (!newDesc) return NULL;

	memset(newDesc, 0, sizeof(GF_MediaTime));
	newDesc->tag = GF_ODF_MEDIATIME_TAG;
	return (GF_Descriptor *) newDesc;
}
GF_Err gf_odf_del_mediatime(GF_MediaTime *mt)
{
	if (!mt) return GF_BAD_PARAM;
	gf_free(mt);
	return GF_OK;
}
GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize)
{
	if (!mt) return GF_BAD_PARAM;
	mt->mediaTimeStamp = gf_bs_read_double(bs);
	return GF_OK;
}
GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize)
{
	if (!mt) return GF_BAD_PARAM;
	*outSize = 8;
	return GF_OK;
}
GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt)
{
	GF_Err e;
	u32 size;
	if (!mt) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, mt->tag, size);
	if (e) return e;
	gf_bs_write_double(bs, mt->mediaTimeStamp);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_cc()
{
	GF_CCDescriptor *newDesc = (GF_CCDescriptor *) gf_malloc(sizeof(GF_CCDescriptor));
	if (!newDesc) return NULL;

	newDesc->contentClassificationData = NULL;
	newDesc->dataLength = 0;
	newDesc->classificationEntity = 0;
	newDesc->classificationTable = 0;
	newDesc->tag = GF_ODF_CC_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd)
{
	if (!ccd) return GF_BAD_PARAM;
	if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData);
	gf_free(ccd);
	return GF_OK;
}

GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!ccd) return GF_BAD_PARAM;

	ccd->classificationEntity = gf_bs_read_int(bs, 32);
	ccd->classificationTable = gf_bs_read_int(bs, 16);
	nbBytes += 6;
	if (DescSize < 6) return GF_ODF_INVALID_DESCRIPTOR;

	ccd->dataLength = DescSize - 6;
	ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength);
	if (!ccd->contentClassificationData) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength);
	nbBytes += ccd->dataLength;

	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize)
{
	if (!ccd) return GF_BAD_PARAM;
	*outSize = 6 + ccd->dataLength;
	return GF_OK;
}

GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd)
{
	u32 size;
	GF_Err e;
	if (!ccd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ccd->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, ccd->classificationEntity, 32);
	gf_bs_write_int(bs, ccd->classificationTable, 16);
	gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_cc_date()
{
	GF_CC_Date *newDesc = (GF_CC_Date *) gf_malloc(sizeof(GF_CC_Date));
	if (!newDesc) return NULL;
	memset(newDesc->contentCreationDate, 0, 5);
	newDesc->tag = GF_ODF_CC_DATE_TAG;
	return (GF_Descriptor *) newDesc;
}


GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd)
{
	if (!cdd) return GF_BAD_PARAM;
	gf_free(cdd);
	return GF_OK;
}

GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!cdd) return GF_BAD_PARAM;

	gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
	nbBytes += DATE_CODING_LEN;
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize)
{
	if (!cdd) return GF_BAD_PARAM;
	*outSize = DATE_CODING_LEN;
	return GF_OK;
}

GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd)
{
	u32 size;
	GF_Err e;
	if (!cdd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, cdd->tag, size);
	if (e) return e;

	gf_bs_write_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_cc_name()
{
	GF_CC_Name *newDesc = (GF_CC_Name *) gf_malloc(sizeof(GF_CC_Name));
	if (!newDesc) return NULL;

	newDesc->ContentCreators = gf_list_new();
	if (! newDesc->ContentCreators) {
		gf_free(newDesc);
		return NULL;
	}
	newDesc->tag = GF_ODF_CC_NAME_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd)
{
	u32 i;
	GF_ContentCreatorInfo *tmp;
	if (!cnd) return GF_BAD_PARAM;

	i=0;
	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
		if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName);
		gf_free(tmp);
	}
	gf_list_del(cnd->ContentCreators);
	gf_free(cnd);
	return GF_OK;
}

GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize)
{
	GF_Err e;
	u32 i, count, len, nbBytes = 0;
	if (!cnd) return GF_BAD_PARAM;

	count = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	for (i = 0; i< count; i++) {
		GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo));
		if (! tmp) return GF_OUT_OF_MEM;
		memset(tmp , 0, sizeof(GF_ContentCreatorInfo));
		tmp->langCode = gf_bs_read_int(bs, 24);
		tmp->isUTF8 = gf_bs_read_int(bs, 1);
		/*aligned = */gf_bs_read_int(bs, 7);
		nbBytes += 4;

		e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len);
		if (e) {
			gf_free(tmp);
			return e;
		}
		nbBytes += len;
		e = gf_list_add(cnd->ContentCreators, tmp);
		if (e) return e;
	}
	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize)
{
	u32 i;
	GF_ContentCreatorInfo *tmp;
	if (!cnd) return GF_BAD_PARAM;

	*outSize = 1;
	i=0;
	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
		*outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8);
	}
	return GF_OK;
}

GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd)
{
	GF_Err e;
	GF_ContentCreatorInfo *tmp;
	u32 i, size;
	if (!cnd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, cnd->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8);

	i=0;
	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
		gf_bs_write_int(bs, tmp->langCode, 24);
		gf_bs_write_int(bs, tmp->isUTF8, 1);
		gf_bs_write_int(bs, 0, 7);		//aligned
		OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8);
	}
	return GF_OK;
}


GF_Descriptor *gf_odf_new_ci()
{
	GF_CIDesc *newDesc = (GF_CIDesc *) gf_malloc(sizeof(GF_CIDesc));
	if (!newDesc) return NULL;

	newDesc->compatibility = 0;
	newDesc->contentIdentifier = NULL;
	newDesc->tag = GF_ODF_CI_TAG;
	newDesc->contentIdentifierFlag = 0;
	newDesc->contentIdentifierType = 0;
	newDesc->contentType = 0;
	newDesc->contentTypeFlag = 0;
	newDesc->protectedContent = 0;
	return (GF_Descriptor *) newDesc;
}


GF_Err gf_odf_del_ci(GF_CIDesc *cid)
{
	if (!cid) return GF_BAD_PARAM;

	if (cid->contentIdentifier) gf_free(cid->contentIdentifier);
	gf_free(cid);
	return GF_OK;
}


GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! cid) return GF_BAD_PARAM;

	cid->compatibility = gf_bs_read_int(bs, 2);	//MUST BE NULL
	if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR;

	cid->contentTypeFlag = gf_bs_read_int(bs, 1);
	cid->contentIdentifierFlag = gf_bs_read_int(bs, 1);
	cid->protectedContent = gf_bs_read_int(bs, 1);
	/*reserved = */gf_bs_read_int(bs, 3);
	nbBytes += 1;

	if (cid->contentTypeFlag) {
		cid->contentType = gf_bs_read_int(bs, 8);
		nbBytes += 1;
	}
	if (cid->contentIdentifierFlag) {
		cid->contentIdentifierType = gf_bs_read_int(bs, 8);
		if (DescSize < (u32) 2 + cid->contentTypeFlag) return GF_ODF_INVALID_DESCRIPTOR;
		cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag);
		if (! cid->contentIdentifier) return GF_OUT_OF_MEM;

		gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag);
		nbBytes += DescSize - 1 - cid->contentTypeFlag;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize)
{
	if (! cid) return GF_BAD_PARAM;

	*outSize = 1;
	if (cid->contentTypeFlag) *outSize += 1;

	if (cid->contentIdentifierFlag)
		*outSize += (u32) strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag;
	return GF_OK;
}

GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid)
{
	GF_Err e;
	u32 size;
	if (! cid) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, cid->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, cid->compatibility, 2);
	gf_bs_write_int(bs, cid->contentTypeFlag, 1);
	gf_bs_write_int(bs, cid->contentIdentifierFlag, 1);
	gf_bs_write_int(bs, cid->protectedContent, 1);
	gf_bs_write_int(bs, 7, 3);		//reserved 0b111 = 7

	if (cid->contentTypeFlag) {
		gf_bs_write_int(bs, cid->contentType, 8);
	}

	if (cid->contentIdentifierFlag) {
		gf_bs_write_int(bs, cid->contentIdentifierType, 8);
		gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_exp_text()
{
	GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) gf_malloc(sizeof(GF_ExpandedTextual));
	if (!newDesc) return NULL;

	newDesc->itemDescriptionList = gf_list_new();
	if (! newDesc->itemDescriptionList) {
		gf_free(newDesc);
		return NULL;
	}
	newDesc->itemTextList = gf_list_new();
	if (! newDesc->itemTextList) {
		gf_free(newDesc->itemDescriptionList);
		gf_free(newDesc);
		return NULL;
	}
	newDesc->isUTF8 = 0;
	newDesc->langCode = 0;
	newDesc->NonItemText = NULL;
	newDesc->tag = GF_ODF_TEXT_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd)
{
	if (!etd) return GF_BAD_PARAM;

	while (gf_list_count(etd->itemDescriptionList)) {
		GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0);
		if (tmp) {
			if (tmp->text) gf_free(tmp->text);
			gf_free(tmp);
		}
		gf_list_rem(etd->itemDescriptionList, 0);
	}
	gf_list_del(etd->itemDescriptionList);

	while (gf_list_count(etd->itemTextList)) {
		GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0);
		if (tmp) {
			if (tmp->text) gf_free(tmp->text);
			gf_free(tmp);
		}
		gf_list_rem(etd->itemTextList, 0);
	}
	gf_list_del(etd->itemTextList);

	if (etd->NonItemText) gf_free(etd->NonItemText);
	gf_free(etd);
	return GF_OK;
}

GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0;
	u32 i, len, nonLen, count;
	if (!etd) return GF_BAD_PARAM;

	etd->langCode = gf_bs_read_int(bs, 24);
	etd->isUTF8 = gf_bs_read_int(bs, 1);
	/*aligned = */gf_bs_read_int(bs, 7);
	count = gf_bs_read_int(bs, 8);
	nbBytes += 5;

	for (i = 0; i< count; i++) {
		//description
		GF_ETD_ItemText *description, *Text;
		description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
		if (! description) return GF_OUT_OF_MEM;
		description->text = NULL;
		e = OD_ReadUTF8String(bs, & description->text, etd->isUTF8, &len);
		if (e) {
			gf_free(description);
			return e;
		}
		e = gf_list_add(etd->itemDescriptionList, description);
		if (e) return e;
		nbBytes += len;

		//text
		Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
		if (! Text) return GF_OUT_OF_MEM;
		Text->text = NULL;
		e = OD_ReadUTF8String(bs, & Text->text, etd->isUTF8, &len);
		if (e) return e;
		e = gf_list_add(etd->itemTextList, Text);
		if (e) return e;
		nbBytes += len;
	}
	len = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	nonLen = 0;
	while (len == 255) {
		nonLen += len;
		len = gf_bs_read_int(bs, 8);
		nbBytes += 1;
	}
	nonLen += len;
	if (nonLen) {
		//here we have no choice but do the job ourselves
		//because the length is not encoded on 8 bits
		etd->NonItemText = (char *) gf_malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2));
		if (! etd->NonItemText) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
		nbBytes += nonLen * (etd->isUTF8 ? 1 : 2);
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}


GF_Err gf_odf_size_exp_text(GF_ExpandedTextual *etd, u32 *outSize)
{
	u32 i, len, nonLen, lentmp, count;
	if (!etd) return GF_BAD_PARAM;

	*outSize = 5;
	if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;

	count = gf_list_count(etd->itemDescriptionList);
	for (i=0; i<count; i++) {
		GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
		*outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
		tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
		*outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
	}
	*outSize += 1;
	if (etd->NonItemText) {
		if (etd->isUTF8) {
			nonLen = (u32) strlen((const char*)etd->NonItemText);
		} else {
			nonLen = gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
		}
	} else {
		nonLen = 0;
	}
	len = 255;
	lentmp = nonLen;
	if (lentmp < 255) {
		len = lentmp;
	}
	while (len == 255) {
		*outSize += 1;
		lentmp -= 255;
		if (lentmp < 255) {
			len = lentmp;
		}
	}
	*outSize += nonLen * (etd->isUTF8 ? 1 : 2);
	return GF_OK;
}

GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd)
{
	GF_Err e;
	u32 size, i, len, nonLen, lentmp, count;
	if (!etd) return GF_BAD_PARAM;

	if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;

	e = gf_odf_size_descriptor((GF_Descriptor *)etd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, etd->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, etd->langCode, 24);
	gf_bs_write_int(bs, etd->isUTF8, 1);
	gf_bs_write_int(bs, 0, 7);		//aligned
	gf_bs_write_int(bs, gf_list_count(etd->itemDescriptionList), 8);

	count = gf_list_count(etd->itemDescriptionList);
	for (i=0; i<count; i++) {
		GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
		OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
		tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
		OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
	}
	if (etd->NonItemText) {
		if (etd->isUTF8) {
			nonLen = (u32) strlen((const char*)etd->NonItemText);
		} else {
			nonLen = gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
		}
	} else {
		nonLen = 0;
	}
	lentmp = nonLen;
	len = lentmp < 255 ? lentmp : 255;
	while (len == 255) {
		gf_bs_write_int(bs, len, 8);
		lentmp -= len;
		len = lentmp < 255 ? lentmp : 255;
	}
	gf_bs_write_int(bs, len, 8);
	gf_bs_write_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
	return GF_OK;
}

GF_Descriptor *gf_odf_new_pl_ext()
{
	GF_PLExt *newDesc = (GF_PLExt *) gf_malloc(sizeof(GF_PLExt));
	if (!newDesc) return NULL;
	newDesc->AudioProfileLevelIndication = 0;
	newDesc->GraphicsProfileLevelIndication = 0;
	newDesc->MPEGJProfileLevelIndication = 0;
	newDesc->ODProfileLevelIndication = 0;
	newDesc->profileLevelIndicationIndex = 0;
	newDesc->SceneProfileLevelIndication = 0;
	newDesc->VisualProfileLevelIndication = 0;
	newDesc->tag = GF_ODF_EXT_PL_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_pl_ext(GF_PLExt *pld)
{
	if (!pld) return GF_BAD_PARAM;

	gf_free(pld);
	return GF_OK;
}

GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!pld) return GF_BAD_PARAM;

	pld->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
	pld->ODProfileLevelIndication = gf_bs_read_int(bs, 8);
	pld->SceneProfileLevelIndication = gf_bs_read_int(bs, 8);
	pld->AudioProfileLevelIndication = gf_bs_read_int(bs, 8);
	pld->VisualProfileLevelIndication = gf_bs_read_int(bs, 8);
	pld->GraphicsProfileLevelIndication = gf_bs_read_int(bs, 8);
	pld->MPEGJProfileLevelIndication = gf_bs_read_int(bs, 8);

	nbBytes += 7;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize)
{
	if (!pld) return GF_BAD_PARAM;

	*outSize = 7;
	return GF_OK;
}

GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld)
{
	GF_Err e;
	u32 size;
	if (!pld) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, pld->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8);
	gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8);
	gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8);
	gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8);
	gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8);
	gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8);
	gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_ipi_ptr()
{
	GF_IPIPtr *newDesc = (GF_IPIPtr *) gf_malloc(sizeof(GF_IPIPtr));
	if (!newDesc) return NULL;
	newDesc->IPI_ES_Id = 0;
	newDesc->tag = GF_ODF_IPI_PTR_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid)
{
	if (!ipid) return GF_BAD_PARAM;
	gf_free(ipid);
	return GF_OK;
}

GF_Err gf_odf_read_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! ipid) return GF_BAD_PARAM;

	ipid->IPI_ES_Id = gf_bs_read_int(bs, 16);
	nbBytes += 2;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_ipi_ptr(GF_IPIPtr *ipid, u32 *outSize)
{
	if (! ipid) return GF_BAD_PARAM;
	*outSize = 2;
	return GF_OK;
}

GF_Err gf_odf_write_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid)
{
	GF_Err e;
	u32 size;
	if (! ipid) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)ipid, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipid->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, ipid->IPI_ES_Id, 16);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_ipmp()
{
	GF_IPMP_Descriptor *newDesc;
	GF_SAFEALLOC(newDesc, GF_IPMP_Descriptor);
	if (!newDesc) return NULL;

	newDesc->ipmpx_data = gf_list_new();
	newDesc->tag = GF_ODF_IPMP_TAG;
	return (GF_Descriptor *) newDesc;
}
GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp)
{
	if (!ipmp) return GF_BAD_PARAM;
	if (ipmp->opaque_data) gf_free(ipmp->opaque_data);
#ifndef GPAC_MINIMAL_ODF
	/*TODO DELETE IPMPX*/
	while (gf_list_count(ipmp->ipmpx_data)) {
		GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0);
		gf_list_rem(ipmp->ipmpx_data, 0);
		gf_ipmpx_data_del(p);
	}
#endif
	gf_list_del(ipmp->ipmpx_data);
	gf_free(ipmp);
	return GF_OK;
}

GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize)
{
	u32 size;
	u64 nbBytes = 0;
	if (!ipmp) return GF_BAD_PARAM;

	ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
	ipmp->IPMPS_Type = gf_bs_read_int(bs, 16);
	nbBytes += 3;
	if (DescSize<3) return GF_ODF_INVALID_DESCRIPTOR;

	size = DescSize - 3;

	/*IPMPX escape*/
	if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
		ipmp->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
		if (gf_bs_available(bs) < 16) return GF_ODF_INVALID_DESCRIPTOR;
		gf_bs_read_data(bs, (char*)ipmp->IPMP_ToolID, 16);
		ipmp->control_point = gf_bs_read_int(bs, 8);
		nbBytes += 19;
		if (ipmp->control_point) {
			ipmp->cp_sequence_code = gf_bs_read_int(bs, 8);
			nbBytes += 1;
		}
		while (nbBytes<DescSize) {
			u64 pos;
			GF_Err e;
			GF_IPMPX_Data *p;
			pos = gf_bs_get_position(bs);
			e = gf_ipmpx_data_parse(bs, &p);
			if (e) return e;
			gf_list_add(ipmp->ipmpx_data, p);
			nbBytes += gf_bs_get_position(bs) - pos;
		}
	}
	/*URL*/
	else if (! ipmp->IPMPS_Type) {
		ipmp->opaque_data = (char*)gf_malloc(size + 1);
		if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ipmp->opaque_data, size);
		nbBytes += size;
		ipmp->opaque_data[size] = 0;
		ipmp->opaque_data_size = size;

	}
	/*data*/
	else {
		ipmp->opaque_data_size = size;
		ipmp->opaque_data = (char*)gf_malloc(size);
		if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ipmp->opaque_data, size);
		nbBytes += size;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_ipmp(GF_IPMP_Descriptor *ipmp, u32 *outSize)
{
	u32 i, s;
	if (!ipmp) return GF_BAD_PARAM;

	*outSize = 3;
	/*IPMPX escape*/
	if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
		GF_IPMPX_Data *p;
		*outSize += 19;
		if (ipmp->control_point) *outSize += 1;
		s = 0;
		i=0;
		while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
			s += gf_ipmpx_data_full_size(p);
		}
		(*outSize) += s;
	}
	else if (! ipmp->IPMPS_Type) {
		if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
		*outSize += (u32) strlen(ipmp->opaque_data);
	} else {
		*outSize += ipmp->opaque_data_size;
	}
	return GF_OK;
}

GF_Err gf_odf_write_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp)
{
	GF_Err e;
	u32 size, i;
	if (!ipmp) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ipmp, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmp->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, ipmp->IPMP_DescriptorID, 8);
	gf_bs_write_int(bs, ipmp->IPMPS_Type, 16);

	if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
		GF_IPMPX_Data *p;
		gf_bs_write_int(bs, ipmp->IPMP_DescriptorIDEx, 16);
		gf_bs_write_data(bs, (char*)ipmp->IPMP_ToolID, 16);
		gf_bs_write_int(bs, ipmp->control_point, 8);
		if (ipmp->control_point) gf_bs_write_int(bs, ipmp->cp_sequence_code, 8);

		i=0;
		while ((p = (GF_IPMPX_Data *) gf_list_enum(ipmp->ipmpx_data, &i))) {
			gf_ipmpx_data_write(bs, p);
		}
	}
	else if (!ipmp->IPMPS_Type) {
		if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
		gf_bs_write_data(bs, ipmp->opaque_data, (u32) strlen(ipmp->opaque_data));
	} else {
		gf_bs_write_data(bs, ipmp->opaque_data, ipmp->opaque_data_size);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_ipmp_ptr()
{
	GF_IPMPPtr *newDesc;
	GF_SAFEALLOC(newDesc, GF_IPMPPtr);
	if (!newDesc) return NULL;
	newDesc->tag = GF_ODF_IPMP_PTR_TAG;
	return (GF_Descriptor *) newDesc;
}
GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd)
{
	if (!ipmpd) return GF_BAD_PARAM;
	gf_free(ipmpd);
	return GF_OK;
}

GF_Err gf_odf_read_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (! ipmpd) return GF_BAD_PARAM;
	ipmpd->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	if (ipmpd->IPMP_DescriptorID == 0xFF) {
		ipmpd->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
		ipmpd->IPMP_ES_ID = gf_bs_read_int(bs, 16);
		nbBytes += 4;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}
GF_Err gf_odf_size_ipmp_ptr(GF_IPMPPtr *ipmpd, u32 *outSize)
{
	if (! ipmpd) return GF_BAD_PARAM;
	*outSize = 1;
	if (ipmpd->IPMP_DescriptorID == 0xFF) *outSize += 4;
	return GF_OK;
}
GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd)
{
	GF_Err e;
	u32 size;
	if (! ipmpd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ipmpd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmpd->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, ipmpd->IPMP_DescriptorID, 8);
	if (ipmpd->IPMP_DescriptorID == 0xFF) {
		gf_bs_write_int(bs, ipmpd->IPMP_DescriptorIDEx, 16);
		gf_bs_write_int(bs, ipmpd->IPMP_ES_ID, 16);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_kw()
{
	GF_KeyWord *newDesc = (GF_KeyWord *) gf_malloc(sizeof(GF_KeyWord));
	if (!newDesc) return NULL;

	newDesc->keyWordsList = gf_list_new();
	if (! newDesc->keyWordsList) {
		gf_free(newDesc);
		return NULL;
	}
	newDesc->isUTF8 = 0;
	newDesc->languageCode = 0;
	newDesc->tag = GF_ODF_KW_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_kw(GF_KeyWord *kwd)
{
	if (!kwd) return GF_BAD_PARAM;

	while (gf_list_count(kwd->keyWordsList)) {
		GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0);
		if (tmp) {
			if (tmp->keyWord) gf_free(tmp->keyWord);
			tmp->keyWord = NULL;
			gf_list_rem(kwd->keyWordsList, 0);
			gf_free(tmp);
		}
	}
	gf_list_del(kwd->keyWordsList);
	gf_free(kwd);
	return GF_OK;
}

GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0, i, kwcount, len;
	if (!kwd) return GF_BAD_PARAM;

	kwd->languageCode = gf_bs_read_int(bs, 24);
	kwd->isUTF8 = gf_bs_read_int(bs, 1);
	/*aligned = */gf_bs_read_int(bs, 7);
	kwcount = gf_bs_read_int(bs, 8);
	nbBytes += 5;

	for (i = 0 ; i < kwcount; i++) {
		GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem));
		if (! tmp) return GF_OUT_OF_MEM;
		e = OD_ReadUTF8String(bs, & tmp->keyWord, kwd->isUTF8, &len);
		if (e) {
			if (tmp->keyWord) gf_free(tmp->keyWord);
			gf_free(tmp);
			return e;
		}
		nbBytes += len;
		if (nbBytes > DescSize) {
			gf_free(tmp->keyWord);
			gf_free(tmp);
			return GF_ODF_INVALID_DESCRIPTOR;
		}
		e = gf_list_add(kwd->keyWordsList, tmp);
		if (e) {
			if (tmp) gf_free(tmp);
			return e;
		}
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}


GF_Err gf_odf_size_kw(GF_KeyWord *kwd, u32 *outSize)
{
	u32 i;
	GF_KeyWordItem *tmp;
	if (!kwd) return GF_BAD_PARAM;

	*outSize = 5;
	i=0;
	while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
		*outSize += OD_SizeUTF8String(tmp->keyWord, kwd->isUTF8);
	}
	return GF_OK;
}
GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd)
{
	GF_Err e;
	u32 size, i;
	GF_KeyWordItem *tmp;
	if (!kwd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)kwd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, kwd->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, kwd->languageCode, 24);
	gf_bs_write_int(bs, kwd->isUTF8, 1);
	gf_bs_write_int(bs, 0, 7);		//aligned(8)
	gf_bs_write_int(bs, gf_list_count(kwd->keyWordsList), 8);

	i=0;
	while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
		OD_WriteUTF8String(bs, tmp->keyWord, kwd->isUTF8);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_oci_date()
{
	GF_OCI_Data *newDesc = (GF_OCI_Data *) gf_malloc(sizeof(GF_OCI_Data));
	if (!newDesc) return NULL;
	memset(newDesc->OCICreationDate, 0, 5);
	newDesc->tag = GF_ODF_OCI_DATE_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd)
{
	if (!ocd) return GF_BAD_PARAM;
	gf_free(ocd);
	return GF_OK;
}

GF_Err gf_odf_read_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!ocd) return GF_BAD_PARAM;

	gf_bs_read_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
	nbBytes += DATE_CODING_LEN;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_oci_date(GF_OCI_Data *ocd, u32 *outSize)
{
	if (!ocd) return GF_BAD_PARAM;
	*outSize = DATE_CODING_LEN;
	return GF_OK;
}

GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd)
{
	GF_Err e;
	u32 size;
	if (!ocd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ocd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ocd->tag, size);
	if (e) return e;
	gf_bs_write_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_oci_name()
{
	GF_OCICreators *newDesc = (GF_OCICreators *) gf_malloc(sizeof(GF_OCICreators));
	if (!newDesc) return NULL;

	newDesc->OCICreators = gf_list_new();
	if (! newDesc->OCICreators) {
		gf_free(newDesc);
		return NULL;
	}
	newDesc->tag = GF_ODF_OCI_NAME_TAG;
	return (GF_Descriptor *) newDesc;
}
GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn)
{
	u32 i;
	GF_OCICreator_item *tmp;
	if (!ocn) return GF_BAD_PARAM;

	i=0;
	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
		if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName);
		gf_free(tmp);
	}
	gf_list_del(ocn->OCICreators);
	gf_free(ocn);
	return GF_OK;
}

GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0;
	u32 i, count, len;
	if (!ocn) return GF_BAD_PARAM;

	count = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	for (i = 0; i< count; i++) {
		GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item));
		if (! tmp) return GF_OUT_OF_MEM;
		tmp->langCode = gf_bs_read_int(bs, 24);
		tmp->isUTF8 = gf_bs_read_int(bs, 1);
		/*aligned = */gf_bs_read_int(bs, 7);
		nbBytes += 4;
		e = OD_ReadUTF8String(bs, & tmp->OCICreatorName, tmp->isUTF8, &len);
		if (e) {
			gf_free(tmp);
			return e;
		}
		nbBytes += len;
		e = gf_list_add(ocn->OCICreators, tmp);
		if (e) return e;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_oci_name(GF_OCICreators *ocn, u32 *outSize)
{
	u32 i;
	GF_OCICreator_item *tmp;
	if (!ocn) return GF_BAD_PARAM;

	*outSize = 1;
	i=0;
	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
		*outSize += 4 + OD_SizeUTF8String(tmp->OCICreatorName, tmp->isUTF8);
	}
	return GF_OK;
}

GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn)
{
	GF_Err e;
	u32 size;
	u32 i;
	GF_OCICreator_item *tmp;
	if (!ocn) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)ocn, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ocn->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, gf_list_count(ocn->OCICreators), 8);

	i=0;
	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
		gf_bs_write_int(bs, tmp->langCode, 24);
		gf_bs_write_int(bs, tmp->isUTF8, 1);
		gf_bs_write_int(bs, 0, 7);		//aligned
		gf_bs_write_int(bs, (u32) strlen(tmp->OCICreatorName) , 8);
		OD_WriteUTF8String(bs, tmp->OCICreatorName, tmp->isUTF8);
	}
	return GF_OK;
}


GF_Descriptor *gf_odf_new_pl_idx()
{
	GF_PL_IDX *newDesc = (GF_PL_IDX *) gf_malloc(sizeof(GF_PL_IDX));
	if (!newDesc) return NULL;
	newDesc->profileLevelIndicationIndex = 0;
	newDesc->tag = GF_ODF_PL_IDX_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid)
{
	if (!plid) return GF_BAD_PARAM;
	gf_free(plid);
	return GF_OK;
}

GF_Err gf_odf_read_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!plid) return GF_BAD_PARAM;

	plid->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
	nbBytes += 1;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}
GF_Err gf_odf_size_pl_idx(GF_PL_IDX *plid, u32 *outSize)
{
	if (!plid) return GF_BAD_PARAM;
	*outSize = 1;
	return GF_OK;
}
GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid)
{
	GF_Err e;
	u32 size;
	if (!plid) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)plid, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, plid->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, plid->profileLevelIndicationIndex, 8);
	return GF_OK;
}


GF_Descriptor *gf_odf_new_rating()
{
	GF_Rating *newDesc = (GF_Rating *) gf_malloc(sizeof(GF_Rating));
	if (!newDesc) return NULL;

	newDesc->infoLength = 0;
	newDesc->ratingInfo = NULL;
	newDesc->ratingCriteria = 0;
	newDesc->ratingEntity = 0;
	newDesc->tag = GF_ODF_RATING_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_rating(GF_Rating *rd)
{
	if (!rd) return GF_BAD_PARAM;

	if (rd->ratingInfo) gf_free(rd->ratingInfo);
	gf_free(rd);
	return GF_OK;
}

GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!rd) return GF_BAD_PARAM;

	rd->ratingEntity = gf_bs_read_int(bs, 32);
	rd->ratingCriteria = gf_bs_read_int(bs, 16);
	if (DescSize<6) return GF_ODF_INVALID_DESCRIPTOR;
	rd->infoLength = DescSize - 6;
	nbBytes += 6;

	rd->ratingInfo = (char*)gf_malloc(rd->infoLength);
	if (! rd->ratingInfo) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength);
	nbBytes += rd->infoLength;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_rating(GF_Rating *rd, u32 *outSize)
{
	if (!rd) return GF_BAD_PARAM;

	*outSize = 6 + rd->infoLength;
	return GF_OK;
}

GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd)
{
	GF_Err e;
	u32 size;
	if (!rd) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)rd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, rd->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, rd->ratingEntity, 32);
	gf_bs_write_int(bs, rd->ratingCriteria, 16);
	gf_bs_write_data(bs, rd->ratingInfo, rd->infoLength);
	return GF_OK;
}


GF_Descriptor *gf_odf_new_reg()
{
	GF_Registration *newDesc = (GF_Registration *) gf_malloc(sizeof(GF_Registration));
	if (!newDesc) return NULL;
	newDesc->additionalIdentificationInfo = NULL;
	newDesc->dataLength = 0;
	newDesc->formatIdentifier = 0;
	newDesc->tag = GF_ODF_REG_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_reg(GF_Registration *reg)
{
	if (!reg) return GF_BAD_PARAM;

	if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo);
	gf_free(reg);
	return GF_OK;
}

GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize)
{
	u32 nbBytes = 0;
	if (!reg) return GF_BAD_PARAM;

	reg->formatIdentifier = gf_bs_read_int(bs, 32);
	if (DescSize<4) return GF_ODF_INVALID_DESCRIPTOR;
	reg->dataLength = DescSize - 4;
	reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength);
	if (! reg->additionalIdentificationInfo) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
	nbBytes += reg->dataLength + 4;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}


GF_Err gf_odf_size_reg(GF_Registration *reg, u32 *outSize)
{
	if (!reg) return GF_BAD_PARAM;

	*outSize = 4 + reg->dataLength;
	return GF_OK;
}

GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg)
{
	GF_Err e;
	u32 size;
	if (!reg) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)reg, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, reg->tag, size);
	if (e) return e;

	gf_bs_write_int(bs, reg->formatIdentifier, 32);
	gf_bs_write_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_short_text()
{
	GF_ShortTextual *newDesc = (GF_ShortTextual *) gf_malloc(sizeof(GF_ShortTextual));
	if (!newDesc) return NULL;

	newDesc->eventName = NULL;
	newDesc->eventText = NULL;
	newDesc->isUTF8 = 0;
	newDesc->langCode = 0;
	newDesc->tag = GF_ODF_SHORT_TEXT_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_short_text(GF_ShortTextual *std)
{
	if (!std) return GF_BAD_PARAM;

	if (std->eventName) gf_free(std->eventName);
	if (std->eventText) gf_free(std->eventText);
	gf_free(std);
	return GF_OK;
}

GF_Err gf_odf_read_short_text(GF_BitStream *bs, GF_ShortTextual *std, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0, len;
	if (!std) return GF_BAD_PARAM;

	std->langCode = gf_bs_read_int(bs, 24);
	std->isUTF8 = gf_bs_read_int(bs, 1);
	/*aligned = */gf_bs_read_int(bs, 7);
	nbBytes += 4;

	e = OD_ReadUTF8String(bs, & std->eventName, std->isUTF8, &len);
	if (e) return e;
	nbBytes += len;
	e = OD_ReadUTF8String(bs, & std->eventText, std->isUTF8, &len);
	if (e) return e;
	nbBytes += len;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_short_text(GF_ShortTextual *std, u32 *outSize)
{
	if (!std) return GF_BAD_PARAM;
	*outSize = 4;
	*outSize += OD_SizeUTF8String(std->eventName, std->isUTF8) + OD_SizeUTF8String(std->eventText, std->isUTF8);
	return GF_OK;
}

GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std)
{
	GF_Err e;
	u32 size;
	if (!std) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)std, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, std->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, std->langCode, 24);
	gf_bs_write_int(bs, std->isUTF8, 1);
	gf_bs_write_int(bs, 0, 7);
	OD_WriteUTF8String(bs, std->eventName, std->isUTF8);
	OD_WriteUTF8String(bs, std->eventText, std->isUTF8);
	return GF_OK;
}

GF_Descriptor *gf_odf_new_smpte_camera()
{
	GF_SMPTECamera *newDesc = (GF_SMPTECamera *) gf_malloc(sizeof(GF_SMPTECamera));
	if (!newDesc) return NULL;

	newDesc->ParamList = gf_list_new();
	if (! newDesc->ParamList) {
		gf_free(newDesc);
		return NULL;
	}
	newDesc->cameraID = 0;
	newDesc->tag = GF_ODF_SMPTE_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd)
{
	u32 i;
	GF_SmpteParam *tmp;
	if (!cpd) return GF_BAD_PARAM;

	i=0;
	while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
		gf_free(tmp);
	}
	gf_list_del(cpd->ParamList);
	gf_free(cpd);
	return GF_OK;
}
GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0, i, count;
	if (!cpd) return GF_BAD_PARAM;

	cpd->cameraID = gf_bs_read_int(bs, 8);
	count = gf_bs_read_int(bs, 8);
	nbBytes += 2;

	for (i=0; i< count ; i++) {
		GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam));
		if (! tmp) return GF_OUT_OF_MEM;
		tmp->paramID = gf_bs_read_int(bs, 8);
		tmp->param = gf_bs_read_int(bs, 32);
		nbBytes += 5;
		e = gf_list_add(cpd->ParamList, tmp);
		if (e) return e;
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}

GF_Err gf_odf_size_smpte_camera(GF_SMPTECamera *cpd, u32 *outSize)
{
	if (!cpd) return GF_BAD_PARAM;
	*outSize = 2 + 5 * gf_list_count(cpd->ParamList);
	return GF_OK;
}

GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd)
{
	GF_Err e;
	GF_SmpteParam *tmp;
	u32 size, i;
	if (!cpd) return GF_BAD_PARAM;

	e = gf_odf_size_descriptor((GF_Descriptor *)cpd, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, cpd->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, cpd->cameraID, 8);
	gf_bs_write_int(bs, gf_list_count(cpd->ParamList), 8);

	i=0;
	while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
		gf_bs_write_int(bs, tmp->paramID, 8);
		gf_bs_write_int(bs, tmp->param, 32);
	}
	return GF_OK;
}

GF_Descriptor *gf_odf_new_sup_cid()
{
	GF_SCIDesc *newDesc = (GF_SCIDesc *) gf_malloc(sizeof(GF_SCIDesc));
	if (!newDesc) return NULL;
	newDesc->supplContentIdentifierTitle = NULL;
	newDesc->supplContentIdentifierValue  =NULL;
	newDesc->languageCode = 0;
	newDesc->tag = GF_ODF_SCI_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid)
{
	if (!scid) return GF_BAD_PARAM;

	if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle);
	if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue);
	gf_free(scid);
	return GF_OK;
}

GF_Err gf_odf_read_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid, u32 DescSize)
{
	GF_Err e;
	u32 nbBytes = 0, len;
	if (! scid) return GF_BAD_PARAM;

	scid->languageCode = gf_bs_read_int(bs, 24);
	nbBytes += 3;
	e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierTitle, GF_TRUE, &len);
	if (e) return e;
	nbBytes += len;
	e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierValue, GF_TRUE, &len);
	if (e) return e;
	nbBytes += len;
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}


GF_Err gf_odf_size_sup_cid(GF_SCIDesc *scid, u32 *outSize)
{
	if (! scid) return GF_BAD_PARAM;
	*outSize = 3 + OD_SizeUTF8String(scid->supplContentIdentifierTitle, GF_TRUE) + OD_SizeUTF8String(scid->supplContentIdentifierValue, GF_TRUE);
	return GF_OK;
}
GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid)
{
	GF_Err e;
	u32 size;
	if (! scid) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)scid, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, scid->tag, size);
	if (e) return e;
	gf_bs_write_int(bs, scid->languageCode, 24);
	OD_WriteUTF8String(bs, scid->supplContentIdentifierTitle, GF_TRUE);
	OD_WriteUTF8String(bs, scid->supplContentIdentifierValue, GF_TRUE);
	return GF_OK;
}


/*IPMPX stuff*/
GF_Descriptor *gf_odf_new_ipmp_tool_list()
{
	GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) gf_malloc(sizeof(GF_IPMP_ToolList));
	if (!newDesc) return NULL;
	newDesc->ipmp_tools = gf_list_new();
	newDesc->tag = GF_ODF_IPMP_TL_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl)
{
	if (!ipmptl) return GF_BAD_PARAM;

	while (gf_list_count(ipmptl->ipmp_tools)) {
		GF_Descriptor *t = (GF_Descriptor *) gf_list_get(ipmptl->ipmp_tools, 0);
		gf_list_rem(ipmptl->ipmp_tools, 0);
		gf_odf_delete_descriptor(t);
	}
	gf_list_del(ipmptl->ipmp_tools);
	gf_free(ipmptl);
	return GF_OK;
}

GF_Err gf_odf_read_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl, u32 DescSize)
{
	GF_Err e;
	u32 tmpSize;
	u32 nbBytes = 0;
	if (! ipmptl) return GF_BAD_PARAM;

	while (nbBytes < DescSize) {
		GF_Descriptor *tmp = NULL;
		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
		if (e) return e;
		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
		e = gf_list_add(ipmptl->ipmp_tools, tmp);
		if (e) return e;
		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
	}
	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
	return GF_OK;
}


GF_Err gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList *ipmptl, u32 *outSize)
{
	if (!ipmptl) return GF_BAD_PARAM;
	*outSize = 0;
	return gf_odf_size_descriptor_list(ipmptl->ipmp_tools, outSize);
}

GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl)
{
	GF_Err e;
	u32 size;
	if (!ipmptl) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)ipmptl, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmptl->tag, size);
	if (e) return e;
	return gf_odf_write_descriptor_list(bs, ipmptl->ipmp_tools);
}

GF_Descriptor *gf_odf_new_ipmp_tool()
{
	GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) gf_malloc(sizeof(GF_IPMP_Tool));
	if (!newDesc) return NULL;
	memset(newDesc, 0, sizeof(GF_IPMP_Tool));
	newDesc->tag = GF_ODF_IPMP_TL_TAG;
	return (GF_Descriptor *) newDesc;
}

GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt)
{
	if (!ipmpt) return GF_BAD_PARAM;
	if (ipmpt->tool_url) gf_free(ipmpt->tool_url);
	gf_free(ipmpt);
	return GF_OK;
}

GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize)
{
	Bool is_alt, is_param;
	u32 nbBytes = 0;
	if (! ipmpt) return GF_BAD_PARAM;
	gf_bs_read_data(bs, (char*) ipmpt->IPMP_ToolID, 16);
	is_alt = (Bool)gf_bs_read_int(bs, 1);
	is_param = (Bool)gf_bs_read_int(bs, 1);
	gf_bs_read_int(bs, 6);
	nbBytes = 17;

	if (is_alt) {
		u32 i;
		ipmpt->num_alternate = gf_bs_read_int(bs, 8);
		nbBytes += 1;
		if (ipmpt->num_alternate > MAX_IPMP_ALT_TOOLS)
			return GF_ODF_INVALID_DESCRIPTOR;
		for (i=0; i<ipmpt->num_alternate; i++) {
			if (nbBytes + 16 > DescSize) return GF_ODF_INVALID_DESCRIPTOR;
			gf_bs_read_data(bs, (char*)ipmpt->specificToolID[i], 16);
			nbBytes += 16;
		}
	}
	if (nbBytes>DescSize) return GF_ODF_INVALID_DESCRIPTOR;

	if (is_param) { }

	if (nbBytes<DescSize) {
		u32 s;
		nbBytes += gf_ipmpx_array_size(bs, &s);
		if (s>0xFFFFFF) return GF_ODF_INVALID_DESCRIPTOR;

		if (s) {
			ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s+1));
			gf_bs_read_data(bs, ipmpt->tool_url, s);
			ipmpt->tool_url[s] = 0;
			nbBytes += s;
		}
	}

	if (nbBytes!=DescSize) return GF_NON_COMPLIANT_BITSTREAM;
	return GF_OK;
}


GF_Err gf_odf_size_ipmp_tool(GF_IPMP_Tool *ipmpt, u32 *outSize)
{
	if (!ipmpt) return GF_BAD_PARAM;
	*outSize = 17;
	if (ipmpt->num_alternate) *outSize += 1 + 16*ipmpt->num_alternate;

	if (ipmpt->tool_url) {
		u32 s = (u32) strlen(ipmpt->tool_url);
		*outSize += gf_odf_size_field_size(s) - 1 + s;
	}
	return GF_OK;
}

GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt)
{
	GF_Err e;
	u32 size;
	if (!ipmpt) return GF_BAD_PARAM;
	e = gf_odf_size_descriptor((GF_Descriptor *)ipmpt, &size);
	if (e) return e;
	e = gf_odf_write_base_descriptor(bs, ipmpt->tag, size);
	if (e) return e;

	gf_bs_write_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
	gf_bs_write_int(bs, ipmpt->num_alternate ? 1 : 0, 1);
	gf_bs_write_int(bs, 0, 1);
	gf_bs_write_int(bs, 0, 6);

	if (ipmpt->num_alternate) {
		u32 i;
		gf_bs_write_int(bs, ipmpt->num_alternate, 8);
		for (i=0; i<ipmpt->num_alternate; i++) gf_bs_write_data(bs, (char*)ipmpt->specificToolID[i], 16);
	}
	if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, (u32) strlen(ipmpt->tool_url));
	return GF_OK;
}

#endif /*GPAC_MINIMAL_ODF*/
