GF_Filter *gf_filter_connect_source(GF_Filter *filter, const char *url, const char *parent_url, Bool inherit_args, GF_Err *err)
{
	GF_Filter *filter_src;
	const char *args;
	char *full_args = NULL;
	if (!filter) {
		if (err) *err = GF_BAD_PARAM;
		return NULL;
	}
	args = inherit_args ? gf_filter_get_dst_args(filter) : NULL;
	if (args) {
		char *rem_opts[] = {"FID", "SID", "N", "clone", NULL};
		char szSep[10];
		char *loc_args;
		u32 opt_idx;
		u32 dst_offset = 0;
		u32 len = (u32) strlen(args);
		sprintf(szSep, "%cgfloc%c", filter->session->sep_args, filter->session->sep_args);
		loc_args = strstr(args, szSep);
		if (loc_args) {
			len = (u32) (ptrdiff_t) (loc_args - args);
		}
		if (len) {
			gf_dynstrcat(&full_args, url, NULL);
			sprintf(szSep, "%cgpac%c", filter->session->sep_args, filter->session->sep_args);
			if ((filter->session->sep_args==':') && strstr(url, "://") && !strstr(url, szSep)) {
				gf_dynstrcat(&full_args, szSep, NULL);
			} else {
				sprintf(szSep, "%c", filter->session->sep_args);
				gf_dynstrcat(&full_args, szSep, NULL);
			}
			if (full_args)
				dst_offset = (u32) strlen(full_args);

			gf_dynstrcat(&full_args, args, NULL);
			sprintf(szSep, "%cgfloc%c", filter->session->sep_args, filter->session->sep_args);
			loc_args = strstr(full_args, "gfloc");
			if (loc_args) loc_args[0] = 0;

			//remove all internal options FIS, SID, N
			opt_idx = 0;
			while (rem_opts[opt_idx]) {
				sprintf(szSep, "%c%s%c", filter->session->sep_args, rem_opts[opt_idx], filter->session->sep_name);
				loc_args = strstr(full_args + dst_offset, szSep);
				if (loc_args) {
					char *sep = strchr(loc_args+1, filter->session->sep_args);
					if (sep) memmove(loc_args, sep, strlen(sep)+1);
					else loc_args[0] = 0;
				}
				opt_idx++;
			}
			url = full_args;
		}
	}

	filter_src = gf_fs_load_source_dest_internal(filter->session, url, NULL, parent_url, err, NULL, filter, GF_TRUE, GF_TRUE, NULL);
	if (full_args) gf_free(full_args);

	if (!filter_src) return NULL;

	gf_mx_p(filter->tasks_mx);
	if (!filter->source_filters)
		filter->source_filters = gf_list_new();
	gf_list_add(filter->source_filters, filter_src);
	gf_mx_v(filter->tasks_mx);
	return filter_src;
}
GF_Filter *gf_filter_connect_source(GF_Filter *filter, const char *url, const char *parent_url, Bool inherit_args, GF_Err *err)
{
	GF_Filter *filter_src;
	const char *args;
	char *full_args = NULL;
	if (!filter) {
		if (err) *err = GF_BAD_PARAM;
		return NULL;
	}
	args = inherit_args ? gf_filter_get_dst_args(filter) : NULL;
	if (args) {
		char *rem_opts[] = {"FID", "SID", "N", "clone", NULL};
		char szSep[10];
		char *loc_args;
		u32 opt_idx;
		u32 dst_offset = 0;
		u32 len = (u32) strlen(args);
		sprintf(szSep, "%cgfloc%c", filter->session->sep_args, filter->session->sep_args);
		loc_args = strstr(args, szSep);
		if (loc_args) {
			len = (u32) (ptrdiff_t) (loc_args - args);
		}
		if (len) {
			gf_dynstrcat(&full_args, url, NULL);
			sprintf(szSep, "%cgpac%c", filter->session->sep_args, filter->session->sep_args);
			if ((filter->session->sep_args==':') && strstr(url, "://") && !strstr(url, szSep)) {
				gf_dynstrcat(&full_args, szSep, NULL);
			} else {
				sprintf(szSep, "%c", filter->session->sep_args);
				gf_dynstrcat(&full_args, szSep, NULL);
			}
			if (full_args)
				dst_offset = (u32) strlen(full_args);

			gf_dynstrcat(&full_args, args, NULL);
			sprintf(szSep, "%cgfloc%c", filter->session->sep_args, filter->session->sep_args);
			loc_args = strstr(full_args, "gfloc");
			if (loc_args) loc_args[0] = 0;

			 
			opt_idx = 0;
			while (rem_opts[opt_idx]) {
				sprintf(szSep, "%c%s%c", filter->session->sep_args, rem_opts[opt_idx], filter->session->sep_name);
				loc_args = strstr(full_args + dst_offset, szSep);
				if (loc_args) {
					char *sep = strchr(loc_args+1, filter->session->sep_args);
					if (sep) memmove(loc_args, sep, strlen(sep)+1);
					else loc_args[0] = 0;
				}
				opt_idx++;
			}
			url = full_args;
		}
	}

	filter_src = gf_fs_load_source_dest_internal(filter->session, url, NULL, parent_url, err, NULL, filter, GF_TRUE, GF_TRUE, NULL);
	if (full_args) gf_free(full_args);

	if (!filter_src) return NULL;

	gf_mx_p(filter->tasks_mx);
	if (!filter->source_filters)
		filter->source_filters = gf_list_new();
	gf_list_add(filter->source_filters, filter_src);
	gf_mx_v(filter->tasks_mx);
	return filter_src;
}