GF_Err gf_isom_new_mpha_description(GF_ISOFile *movie, u32 trackNumber, const char *URLname, const char *URNname, u32 *outDescriptionIndex, u8 *dsi, u32 dsi_size)
{
	GF_TrackBox *trak;
	GF_Err e;
	u32 dataRefIndex;
	GF_MPEGAudioSampleEntryBox *mpa;

	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	if (dsi_size<6) return GF_BAD_PARAM;

	trak = gf_isom_get_track_from_file(movie, trackNumber);
	if (!trak || !trak->Media) return GF_BAD_PARAM;

	switch (trak->Media->handler->handlerType) {
	case GF_ISOM_MEDIA_AUDIO:
		break;
	default:
		return GF_BAD_PARAM;
	}

	//get or create the data ref
	e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
	if (e) return e;
	if (!dataRefIndex) {
		e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
		if (e) return e;
	}
	if (!movie->keep_utc)
		trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();

	mpa = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MHA1);
	if (!mpa) return GF_OUT_OF_MEM;
	mpa->dataReferenceIndex = dataRefIndex;
	gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, mpa);
	if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);

	mpa->cfg_mha = (GF_MHAConfigBox *) gf_isom_box_new_parent(&mpa->child_boxes, GF_ISOM_BOX_TYPE_MHAC);
	if (!mpa->cfg_mha) return GF_OUT_OF_MEM;
	mpa->cfg_mha->configuration_version = dsi[0];
	mpa->cfg_mha->mha_pl_indication = dsi[1];
	mpa->cfg_mha->reference_channel_layout = dsi[2];
	mpa->cfg_mha->mha_config_size = dsi[3];
	mpa->cfg_mha->mha_config_size <<= 8;
	mpa->cfg_mha->mha_config_size |= dsi[4];
	mpa->cfg_mha->mha_config = gf_malloc(sizeof(u8) * mpa->cfg_mha->mha_config_size);
	if (!mpa->cfg_mha->mha_config) return GF_OUT_OF_MEM;
	memcpy(mpa->cfg_mha->mha_config, dsi+5, dsi_size-5);
	return GF_OK;
}
GF_Err gf_isom_new_mpha_description(GF_ISOFile *movie, u32 trackNumber, const char *URLname, const char *URNname, u32 *outDescriptionIndex, u8 *dsi, u32 dsi_size)
{
	GF_TrackBox *trak;
	GF_Err e;
	u32 dataRefIndex;
	GF_MPEGAudioSampleEntryBox *mpa;

	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	if (dsi_size<6) return GF_BAD_PARAM;

	trak = gf_isom_get_track_from_file(movie, trackNumber);
	if (!trak || !trak->Media) return GF_BAD_PARAM;

	switch (trak->Media->handler->handlerType) {
	case GF_ISOM_MEDIA_AUDIO:
		break;
	default:
		return GF_BAD_PARAM;
	}

	 
	e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
	if (e) return e;
	if (!dataRefIndex) {
		e = Media_CreateDataRef(movie, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex);
		if (e) return e;
	}
	if (!movie->keep_utc)
		trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();

	mpa = (GF_MPEGAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MHA1);
	if (!mpa) return GF_OUT_OF_MEM;
	mpa->dataReferenceIndex = dataRefIndex;
	gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, mpa);
	if (outDescriptionIndex) *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);

	mpa->cfg_mha = (GF_MHAConfigBox *) gf_isom_box_new_parent(&mpa->child_boxes, GF_ISOM_BOX_TYPE_MHAC);
	if (!mpa->cfg_mha) return GF_OUT_OF_MEM;
	mpa->cfg_mha->configuration_version = dsi[0];
	mpa->cfg_mha->mha_pl_indication = dsi[1];
	mpa->cfg_mha->reference_channel_layout = dsi[2];
	mpa->cfg_mha->mha_config_size = dsi[3];
	mpa->cfg_mha->mha_config_size <<= 8;
	mpa->cfg_mha->mha_config_size |= dsi[4];
	mpa->cfg_mha->mha_config = gf_malloc(sizeof(u8) * mpa->cfg_mha->mha_config_size);
	if (!mpa->cfg_mha->mha_config) return GF_OUT_OF_MEM;
	memcpy(mpa->cfg_mha->mha_config, dsi+5, dsi_size-5);
	return GF_OK;
}