				a_ds->force_timescale = ds->timescale;
		}
	}
}

GF_Err gf_cryptfout_push_key(GF_Filter *filter, bin128 *key, bin128 *IV);

static void dasher_open_destination(GF_Filter *filter, GF_DasherCtx *ctx, GF_MPD_Representation *rep, const char *szInitURL, Bool trash_init)
{
	GF_Err e;
	Bool has_frag=GF_FALSE;
	Bool has_subs=GF_FALSE;
	Bool has_strun=GF_FALSE;
	Bool has_vodcache=GF_FALSE;
	Bool has_cmaf=GF_FALSE;
	char sep_args = gf_filter_get_sep(filter, GF_FS_SEP_ARGS);
	char sep_name = gf_filter_get_sep(filter, GF_FS_SEP_NAME);
	const char *dst_args, *trailer_args=NULL;
	char *szDST = NULL;
	char szSRC[100];

	if (ctx->sigfrag || ctx->gencues)
		return;

	GF_DashStream *ds = rep->playback.udta;
	if (ds->muxed_base) return;


	ctx->check_connections = GF_TRUE;
	gf_dynstrcat(&szDST, szInitURL, NULL);
	if (ctx->out_path) {
		char *rel = NULL;
		if (ctx->do_m3u8 && ds->hls_vp_name) {
			char *tmp = gf_url_concatenate(ctx->out_path, ds->hls_vp_name);
			if (tmp) {
				rel = gf_url_concatenate(tmp, szInitURL);
				gf_free(tmp);
			}
		}
		if (!rel)
			rel = gf_url_concatenate(ctx->out_path, szInitURL);
		if (rel) {
			gf_free(szDST);
			szDST = rel;
		}
	}
	if (ds->tci) {
		char *tmp = szDST;
		szDST = NULL;
		gf_dynstrcat(&szDST, "gcryp://", NULL);
		gf_dynstrcat(&szDST, tmp, NULL);
		gf_free(tmp);
	}

	sprintf(szSRC, "%cgfopt", sep_args);
	gf_dynstrcat(&szDST, szSRC, NULL);

	dst_args = gf_filter_get_dst_args(filter);
	if (dst_args) {
		char szKey[20], *sep;
		sprintf(szSRC, "%c", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
		
		gf_dynstrcat(&szDST, dst_args, NULL);
		sprintf(szKey, "%c%c", sep_args, sep_args);
		sep = strstr(szDST, szKey);
		if (sep) {
			sep[0] = 0;
			trailer_args = strstr(dst_args, szKey);
		}
		//look for frag arg
		sprintf(szKey, "%cfrag", sep_args);
		if (strstr(dst_args, szKey)) has_frag = GF_TRUE;
		else {
			sprintf(szKey, "%csfrag", sep_args);
			if (strstr(dst_args, szKey)) has_frag = GF_TRUE;
		}
		//look for subs_sidx arg
		sprintf(szKey, "%csubs_sidx", sep_args);
		if (strstr(dst_args, szKey)) has_subs = GF_TRUE;

		sprintf(szKey, "%cstrun", sep_args);
		if (strstr(dst_args, szKey)) has_strun = GF_TRUE;

		sprintf(szKey, "%cvodcache", sep_args);
		if (strstr(dst_args, szKey)) has_vodcache = GF_TRUE;

		sprintf(szKey, "%ccmaf", sep_args);
		if (strstr(dst_args, szKey)) has_cmaf = GF_TRUE;
	}

	if (trash_init) {
		if (ds->rawmux)
			sprintf(szSRC, "%cnoinitraw", sep_args);
		else
			sprintf(szSRC, "%cnoinit", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (!has_frag) {
		sprintf(szSRC, "%cfrag", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (!ctx->forward_mode) {
		if (!has_subs && ctx->sseg) {
			sprintf(szSRC, "%csubs_sidx%c0", sep_args, sep_name);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
		if (ctx->cues && !has_strun) {
			sprintf(szSRC, "%cstrun", sep_args);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
		if (ctx->styp) {
			sprintf(szSRC, "%cstyp=%s", sep_args, ctx->styp);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
	}

	//override xps inband declaration in args
	sprintf(szSRC, "%cxps_inband%c%s", sep_args, sep_name,
		(ds->inband_params==2) ? "pps" : (ds->inband_params ? "all" : "no") );
	gf_dynstrcat(&szDST, szSRC, NULL);

	if (ctx->no_fragments_defaults) {
		sprintf(szSRC, "%cnofragdef", sep_args );
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	switch (ctx->pssh) {
	case GF_DASH_PSSH_MPD:
		sprintf(szSRC, "%cpsshs%cnone", sep_args, sep_name);
		break;
	case GF_DASH_PSSH_MOOF:
	case GF_DASH_PSSH_MOOF_MPD:
		sprintf(szSRC, "%cpsshs%cmoof", sep_args, sep_name);
		break;
	default:
		sprintf(szSRC, "%cpsshs%cmoov", sep_args, sep_name);
		break;
	}
	gf_dynstrcat(&szDST, szSRC, NULL);

	//patch for old arch: make sure we don't have any extra free box before the sidx
	//we could also use vodcache=insert but this might break http outputs
	if (gf_sys_old_arch_compat() && !has_vodcache && ctx->sseg) {
		sprintf(szSRC, "%cvodcache%con", sep_args, sep_name );
		if (!strstr(szDST, szSRC))
			gf_dynstrcat(&szDST, szSRC, NULL);
	}

	//we don't append mime in case of raw streams, raw format (writegen doesn't use mime types for raw media, only file ext)
	if (!ds->rawmux && ((ctx->muxtype!=DASHER_MUX_RAW) || (ds->codec_id != GF_CODECID_RAW)) ) {
		sprintf(szSRC, "%cmime%c%s", sep_args, sep_name, rep->mime_type);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}

	if (ds->moof_sn>1) {
		sprintf(szSRC, "%cmsn%c%d", sep_args, sep_name, ds->moof_sn);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (ds->moof_sn_inc>1) {
		sprintf(szSRC, "%cmsninc%c%d", sep_args, sep_name, ds->moof_sn_inc);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (ds->sscale) {
		sprintf(szSRC, "%cmoovts%c-1", sep_args, sep_name);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}

	if (!has_cmaf && ctx->cmaf) {
		sprintf(szSRC, "%ccmaf%c%s", sep_args, sep_name, (ctx->cmaf==DASHER_CMAF_CMF2) ? "cmf2" : "cmfc");
		gf_dynstrcat(&szDST, szSRC, NULL);
	}


	if (trailer_args)
		gf_dynstrcat(&szDST, trailer_args, NULL);
		
	ds->dst_filter = gf_filter_connect_destination(filter, szDST, &e);
	gf_free(szDST);
	szDST = NULL;
	if (e) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[Dasher] Couldn't create output file %s: %s\n", szInitURL, gf_error_to_string(e) ));
		ctx->in_error = GF_TRUE;
		return;
	}
	//reset any sourceID given in the dst_arg and assign sourceID to be the dasher filter
	sprintf(szSRC, "MuxSrc%cdasher_%p", sep_name, ds->dst_filter);
	gf_filter_reset_source(ds->dst_filter);
				a_ds->force_timescale = ds->timescale;
		}
	}
}

GF_Err gf_cryptfout_push_key(GF_Filter *filter, bin128 *key, bin128 *IV);

static void dasher_open_destination(GF_Filter *filter, GF_DasherCtx *ctx, GF_MPD_Representation *rep, const char *szInitURL, Bool trash_init)
{
	GF_Err e;
	Bool has_frag=GF_FALSE;
	Bool has_subs=GF_FALSE;
	Bool has_strun=GF_FALSE;
	Bool has_vodcache=GF_FALSE;
	Bool has_cmaf=GF_FALSE;
	char sep_args = gf_filter_get_sep(filter, GF_FS_SEP_ARGS);
	char sep_name = gf_filter_get_sep(filter, GF_FS_SEP_NAME);
	const char *dst_args, *trailer_args=NULL;
	char *szDST = NULL;
	char szSRC[100];

	if (ctx->sigfrag || ctx->gencues)
		return;

	GF_DashStream *ds = rep->playback.udta;
	if (ds->muxed_base) return;


	ctx->check_connections = GF_TRUE;
	gf_dynstrcat(&szDST, szInitURL, NULL);
	if (ctx->out_path) {
		char *rel = NULL;
		if (ctx->do_m3u8 && ds->hls_vp_name) {
			char *tmp = gf_url_concatenate(ctx->out_path, ds->hls_vp_name);
			if (tmp) {
				rel = gf_url_concatenate(tmp, szInitURL);
				gf_free(tmp);
			}
		}
		if (!rel)
			rel = gf_url_concatenate(ctx->out_path, szInitURL);
		if (rel) {
			gf_free(szDST);
			szDST = rel;
		}
	}
	if (ds->tci) {
		char *tmp = szDST;
		szDST = NULL;
		gf_dynstrcat(&szDST, "gcryp://", NULL);
		gf_dynstrcat(&szDST, tmp, NULL);
		gf_free(tmp);
	}

	sprintf(szSRC, "%cgfopt", sep_args);
	gf_dynstrcat(&szDST, szSRC, NULL);

	dst_args = gf_filter_get_dst_args(filter);
	if (dst_args) {
		char szKey[20], *sep;
		sprintf(szSRC, "%c", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
		
		gf_dynstrcat(&szDST, dst_args, NULL);
		sprintf(szKey, "%c%c", sep_args, sep_args);
		sep = strstr(szDST, szKey);
		if (sep) {
			sep[0] = 0;
			trailer_args = strstr(dst_args, szKey);
		}
		 
		sprintf(szKey, "%cfrag", sep_args);
		if (strstr(dst_args, szKey)) has_frag = GF_TRUE;
		else {
			sprintf(szKey, "%csfrag", sep_args);
			if (strstr(dst_args, szKey)) has_frag = GF_TRUE;
		}
		 
		sprintf(szKey, "%csubs_sidx", sep_args);
		if (strstr(dst_args, szKey)) has_subs = GF_TRUE;

		sprintf(szKey, "%cstrun", sep_args);
		if (strstr(dst_args, szKey)) has_strun = GF_TRUE;

		sprintf(szKey, "%cvodcache", sep_args);
		if (strstr(dst_args, szKey)) has_vodcache = GF_TRUE;

		sprintf(szKey, "%ccmaf", sep_args);
		if (strstr(dst_args, szKey)) has_cmaf = GF_TRUE;
	}

	if (trash_init) {
		if (ds->rawmux)
			sprintf(szSRC, "%cnoinitraw", sep_args);
		else
			sprintf(szSRC, "%cnoinit", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (!has_frag) {
		sprintf(szSRC, "%cfrag", sep_args);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (!ctx->forward_mode) {
		if (!has_subs && ctx->sseg) {
			sprintf(szSRC, "%csubs_sidx%c0", sep_args, sep_name);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
		if (ctx->cues && !has_strun) {
			sprintf(szSRC, "%cstrun", sep_args);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
		if (ctx->styp) {
			sprintf(szSRC, "%cstyp=%s", sep_args, ctx->styp);
			gf_dynstrcat(&szDST, szSRC, NULL);
		}
	}

	 
	sprintf(szSRC, "%cxps_inband%c%s", sep_args, sep_name,
		(ds->inband_params==2) ? "pps" : (ds->inband_params ? "all" : "no") );
	gf_dynstrcat(&szDST, szSRC, NULL);

	if (ctx->no_fragments_defaults) {
		sprintf(szSRC, "%cnofragdef", sep_args );
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	switch (ctx->pssh) {
	case GF_DASH_PSSH_MPD:
		sprintf(szSRC, "%cpsshs%cnone", sep_args, sep_name);
		break;
	case GF_DASH_PSSH_MOOF:
	case GF_DASH_PSSH_MOOF_MPD:
		sprintf(szSRC, "%cpsshs%cmoof", sep_args, sep_name);
		break;
	default:
		sprintf(szSRC, "%cpsshs%cmoov", sep_args, sep_name);
		break;
	}
	gf_dynstrcat(&szDST, szSRC, NULL);

	 
	 
	if (gf_sys_old_arch_compat() && !has_vodcache && ctx->sseg) {
		sprintf(szSRC, "%cvodcache%con", sep_args, sep_name );
		if (!strstr(szDST, szSRC))
			gf_dynstrcat(&szDST, szSRC, NULL);
	}

	 
	if (!ds->rawmux && ((ctx->muxtype!=DASHER_MUX_RAW) || (ds->codec_id != GF_CODECID_RAW)) ) {
		sprintf(szSRC, "%cmime%c%s", sep_args, sep_name, rep->mime_type);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}

	if (ds->moof_sn>1) {
		sprintf(szSRC, "%cmsn%c%d", sep_args, sep_name, ds->moof_sn);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (ds->moof_sn_inc>1) {
		sprintf(szSRC, "%cmsninc%c%d", sep_args, sep_name, ds->moof_sn_inc);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}
	if (ds->sscale) {
		sprintf(szSRC, "%cmoovts%c-1", sep_args, sep_name);
		gf_dynstrcat(&szDST, szSRC, NULL);
	}

	if (!has_cmaf && ctx->cmaf) {
		sprintf(szSRC, "%ccmaf%c%s", sep_args, sep_name, (ctx->cmaf==DASHER_CMAF_CMF2) ? "cmf2" : "cmfc");
		gf_dynstrcat(&szDST, szSRC, NULL);
	}


	if (trailer_args)
		gf_dynstrcat(&szDST, trailer_args, NULL);
		
	ds->dst_filter = gf_filter_connect_destination(filter, szDST, &e);
	gf_free(szDST);
	szDST = NULL;
	if (e) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[Dasher] Couldn't create output file %s: %s\n", szInitURL, gf_error_to_string(e) ));
		ctx->in_error = GF_TRUE;
		return;
	}
	 
	sprintf(szSRC, "MuxSrc%cdasher_%p", sep_name, ds->dst_filter);
	gf_filter_reset_source(ds->dst_filter);