GF_Err gf_isom_tmcd_config_new(GF_ISOFile *the_file, u32 trackNumber, u32 fps_num, u32 fps_den, s32 frames_per_counter_tick, Bool is_drop, Bool is_counter, u32 *outDescriptionIndex)
{
	GF_TrackBox *trak;
	GF_Err e;
	u32 dataRefIndex;
	GF_Box *tmcd;
	GF_GenericMediaHeaderInfoBox *gmin;
	GF_TimeCodeMediaInformationBox *tcmi;
	GF_TimeCodeSampleEntryBox *entry;

	e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
	if (e) return e;

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

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

	gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
	if (!gmin) {
		gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
		if (!gmin) return GF_OUT_OF_MEM;
	}

	tmcd = gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_TMCD);
	if (!tmcd) {
		//default container box, use GMHD to create it
		tmcd = gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_ISOM_BOX_TYPE_GMHD);
		if (!tmcd) return GF_OUT_OF_MEM;
		tmcd->type = GF_QT_BOX_TYPE_TMCD;
	}
	tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_find_child(tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
	if (!tcmi) {
		tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_new_parent(&tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
		if (!tcmi) return GF_OUT_OF_MEM;
	}

	entry = (GF_TimeCodeSampleEntryBox *) gf_isom_box_new_ex(GF_QT_BOX_TYPE_TMCD, GF_ISOM_BOX_TYPE_STSD, GF_FALSE, GF_FALSE);
	if (!entry) return GF_OUT_OF_MEM;
	entry->flags = 0;
	if (is_drop) entry->flags |= 0x00000001;
	if (is_counter) entry->flags |= 0x00000008;

	entry->timescale = fps_num;
	entry->frame_duration = fps_den;
	entry->frames_per_counter_tick = (u8) frames_per_counter_tick;
	
	entry->dataReferenceIndex = dataRefIndex;
	e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, entry);
	*outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
	return e;
}
GF_Err gf_isom_tmcd_config_new(GF_ISOFile *the_file, u32 trackNumber, u32 fps_num, u32 fps_den, s32 frames_per_counter_tick, Bool is_drop, Bool is_counter, u32 *outDescriptionIndex)
{
	GF_TrackBox *trak;
	GF_Err e;
	u32 dataRefIndex;
	GF_Box *tmcd;
	GF_GenericMediaHeaderInfoBox *gmin;
	GF_TimeCodeMediaInformationBox *tcmi;
	GF_TimeCodeSampleEntryBox *entry;

	e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE);
	if (e) return e;

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

	 
	e = Media_FindDataRef(trak->Media->information->dataInformation->dref, NULL, NULL, &dataRefIndex);
	if (e) return e;
	if (!dataRefIndex) {
		e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, NULL, NULL, &dataRefIndex);
		if (e) return e;
	}
	if (!the_file->keep_utc)
		trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time();

	gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
	if (!gmin) {
		gmin = (GF_GenericMediaHeaderInfoBox *) gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_GMIN);
		if (!gmin) return GF_OUT_OF_MEM;
	}

	tmcd = gf_isom_box_find_child(trak->Media->information->InfoHeader->child_boxes, GF_QT_BOX_TYPE_TMCD);
	if (!tmcd) {
		 
		tmcd = gf_isom_box_new_parent(&trak->Media->information->InfoHeader->child_boxes, GF_ISOM_BOX_TYPE_GMHD);
		if (!tmcd) return GF_OUT_OF_MEM;
		tmcd->type = GF_QT_BOX_TYPE_TMCD;
	}
	tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_find_child(tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
	if (!tcmi) {
		tcmi = (GF_TimeCodeMediaInformationBox *) gf_isom_box_new_parent(&tmcd->child_boxes, GF_QT_BOX_TYPE_TCMI);
		if (!tcmi) return GF_OUT_OF_MEM;
	}

	entry = (GF_TimeCodeSampleEntryBox *) gf_isom_box_new_ex(GF_QT_BOX_TYPE_TMCD, GF_ISOM_BOX_TYPE_STSD, GF_FALSE, GF_FALSE);
	if (!entry) return GF_OUT_OF_MEM;
	entry->flags = 0;
	if (is_drop) entry->flags |= 0x00000001;
	if (is_counter) entry->flags |= 0x00000008;

	entry->timescale = fps_num;
	entry->frame_duration = fps_den;
	entry->frames_per_counter_tick = (u8) frames_per_counter_tick;
	
	entry->dataReferenceIndex = dataRefIndex;
	e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->child_boxes, entry);
	*outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->child_boxes);
	return e;
}