GF_Err apply_edits(GF_ISOFile *dest, u32 track, char *edits)
{
	GF_Err e = GF_OK;
	u32 movie_ts = gf_isom_get_timescale(dest);
	u32 media_ts = gf_isom_get_media_timescale(dest, track);
	u64 media_dur = gf_isom_get_media_duration(dest, track);

	while (edits) {
		char c=0;
		char *sep = strchr(edits+1, 'r');
		if (!sep) sep = strchr(edits+1, 'e');
		if (sep) {
			c = sep[0];
			sep[0] = 0;
		}

		//remove all edits
		if (edits[0] == 'r') {
			e = gf_isom_remove_edits(dest, track);
			if (e) goto error;
		}
		else if (edits[0]=='e') {
			u64 movie_t, media_t, edur;
			u32 rate;
			GF_Fraction64 movie_time, media_time, media_rate, edit_dur;
			char *mtime_sep;

			edits+=1;
			mtime_sep = strchr(edits, ',');
			movie_time.den = media_time.den = media_rate.den = 0;
			if (!mtime_sep) {
				e = parse_fracs(edits, &movie_time, &edit_dur);
				if (e) goto error;
			}
			else {
				mtime_sep[0] = 0;
				e = parse_fracs(edits, &movie_time, &edit_dur);
				if (e) goto error;
				mtime_sep[0] = ',';
				edits = mtime_sep+1;
				mtime_sep = strchr(edits, ',');
				if (!mtime_sep) {
					e = parse_fracs(edits, &media_time, NULL);
					if (e) goto error;
					media_rate.num = media_rate.den = 1;
				} else {
					mtime_sep[0] = 0;
					e = parse_fracs(edits, &media_time, NULL);
					if (e) goto error;
					mtime_sep[0] = ',';
					e = parse_fracs(mtime_sep+1, &media_rate, NULL);
					if (e) goto error;
				}
			}
			if (!movie_time.den || (movie_time.num<0)) {
				e = GF_BAD_PARAM;
				fprintf(stderr, "Wrong edit format %s, movie time must be valid and >= 0\n", edits);
				goto error;
			}
			movie_t = movie_time.num * movie_ts / movie_time.den;
			if (!edit_dur.den || !edit_dur.num) {
				edur = media_dur;
				edur *= movie_ts;
				edur /= media_ts;
			} else {
				edur = edit_dur.num;
				edur *= movie_ts;
				edur /= edit_dur.den;
				edur /= movie_time.den;
				if (edur>media_dur)
					edur = media_dur;
			}
			if (!media_time.den) {
				e = gf_isom_set_edit(dest, track, movie_t, edur, 0, GF_ISOM_EDIT_EMPTY);
			} else {
				rate = 0;
				if (media_rate.den) {
					u64 frac;
					rate = (u32) ( media_rate.num / media_rate.den );
					frac = media_rate.num - rate*media_rate.den;
					frac *= 0xFFFF;
					frac /= media_rate.den;
					rate = (rate<<16) | (u32) frac;
				}
				media_t = media_time.num * media_ts / media_time.den;
				e = gf_isom_set_edit_with_rate(dest, track, movie_t, edur, media_t, rate);
			}
			if (e==GF_EOS) {
				fprintf(stderr, "Inserted empty edit before edit at start time "LLD"/"LLU"\n", movie_time.num, movie_time.den);
				e = GF_OK;
			}
			if (e) goto error;
		} else {
			e = GF_BAD_PARAM;
			fprintf(stderr, "Wrong edit format %s, should start with 'e' or 'r'\n", edits);
			goto error;
		}
error:
		if (sep) sep[0] = c;
		if (e) return e;

		if (!sep) break;
		edits = sep;
	}
	return GF_OK;
}
GF_Err apply_edits(GF_ISOFile *dest, u32 track, char *edits)
{
	GF_Err e = GF_OK;
	u32 movie_ts = gf_isom_get_timescale(dest);
	u32 media_ts = gf_isom_get_media_timescale(dest, track);
	u64 media_dur = gf_isom_get_media_duration(dest, track);

	while (edits) {
		char c=0;
		char *sep = strchr(edits+1, 'r');
		if (!sep) sep = strchr(edits+1, 'e');
		if (sep) {
			c = sep[0];
			sep[0] = 0;
		}

		 
		if (edits[0] == 'r') {
			e = gf_isom_remove_edits(dest, track);
			if (e) goto error;
		}
		else if (edits[0]=='e') {
			u64 movie_t, media_t, edur;
			u32 rate;
			GF_Fraction64 movie_time, media_time, media_rate, edit_dur;
			char *mtime_sep;

			edits+=1;
			mtime_sep = strchr(edits, ',');
			movie_time.den = media_time.den = media_rate.den = 0;
			if (!mtime_sep) {
				e = parse_fracs(edits, &movie_time, &edit_dur);
				if (e) goto error;
			}
			else {
				mtime_sep[0] = 0;
				e = parse_fracs(edits, &movie_time, &edit_dur);
				if (e) goto error;
				mtime_sep[0] = ',';
				edits = mtime_sep+1;
				mtime_sep = strchr(edits, ',');
				if (!mtime_sep) {
					e = parse_fracs(edits, &media_time, NULL);
					if (e) goto error;
					media_rate.num = media_rate.den = 1;
				} else {
					mtime_sep[0] = 0;
					e = parse_fracs(edits, &media_time, NULL);
					if (e) goto error;
					mtime_sep[0] = ',';
					e = parse_fracs(mtime_sep+1, &media_rate, NULL);
					if (e) goto error;
				}
			}
			if (!movie_time.den || (movie_time.num<0)) {
				e = GF_BAD_PARAM;
				fprintf(stderr, "Wrong edit format %s, movie time must be valid and >= 0\n", edits);
				goto error;
			}
			movie_t = movie_time.num * movie_ts / movie_time.den;
			if (!edit_dur.den || !edit_dur.num) {
				edur = media_dur;
				edur *= movie_ts;
				edur /= media_ts;
			} else {
				edur = edit_dur.num;
				edur *= movie_ts;
				edur /= edit_dur.den;
				edur /= movie_time.den;
				if (edur>media_dur)
					edur = media_dur;
			}
			if (!media_time.den) {
				e = gf_isom_set_edit(dest, track, movie_t, edur, 0, GF_ISOM_EDIT_EMPTY);
			} else {
				rate = 0;
				if (media_rate.den) {
					u64 frac;
					rate = (u32) ( media_rate.num / media_rate.den );
					frac = media_rate.num - rate*media_rate.den;
					frac *= 0xFFFF;
					frac /= media_rate.den;
					rate = (rate<<16) | (u32) frac;
				}
				media_t = media_time.num * media_ts / media_time.den;
				e = gf_isom_set_edit_with_rate(dest, track, movie_t, edur, media_t, rate);
			}
			if (e==GF_EOS) {
				fprintf(stderr, "Inserted empty edit before edit at start time "LLD"/"LLU"\n", movie_time.num, movie_time.den);
				e = GF_OK;
			}
			if (e) goto error;
		} else {
			e = GF_BAD_PARAM;
			fprintf(stderr, "Wrong edit format %s, should start with 'e' or 'r'\n", edits);
			goto error;
		}
error:
		if (sep) sep[0] = c;
		if (e) return e;

		if (!sep) break;
		edits = sep;
	}
	return GF_OK;
}