Bool gf_filter_swap_source_register(GF_Filter *filter)
{
	u32 i;
	char *src_url=NULL;
	GF_Filter *target_filter=NULL;
	GF_Err e;
	const GF_FilterArgs *src_arg=NULL;

	while (gf_list_count(filter->postponed_packets)) {
		GF_FilterPacket *pck = gf_list_pop_front(filter->postponed_packets);
		gf_filter_packet_destroy(pck);
	}

	while (gf_list_count(filter->output_pids)) {
		GF_FilterPid *pid = gf_list_pop_back(filter->output_pids);
		pid->destroyed = GF_TRUE;
		gf_fs_post_task(filter->session, gf_filter_pid_del_task, filter, pid, "pid_delete", NULL);
	}
	gf_mx_p(filter->tasks_mx);
	filter->num_output_pids = 0;
	gf_mx_v(filter->tasks_mx);

	if (filter->freg->finalize) {
		FSESS_CHECK_THREAD(filter)
		filter->freg->finalize(filter);
		filter->finalized = GF_TRUE;
	}
	gf_list_add(filter->blacklisted, (void *)filter->freg);

	i=0;
	while (filter->freg->args) {
		src_arg = &filter->freg->args[i];
		if (!src_arg || !src_arg->arg_name) {
			src_arg=NULL;
			break;
		}
		i++;
		if (strcmp(src_arg->arg_name, "src")) continue;
		//found it, get the url
		if (src_arg->offset_in_private<0) continue;

#ifdef WIN32
		src_url = *(char **)( ((char *)filter->filter_udta) + src_arg->offset_in_private);
		*(char **)(((char *)filter->filter_udta) + src_arg->offset_in_private) = NULL;
#else
		src_url = *(char **) (filter->filter_udta + src_arg->offset_in_private);
		*(char **)(filter->filter_udta + src_arg->offset_in_private) = NULL;
#endif
		 break;
	}

	gf_free(filter->filter_udta);
	filter->filter_udta = NULL;
	if (!src_url) return GF_FALSE;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_FILTER, ("Swaping source filter for URL %s\n", src_url));

	target_filter = filter->target_filter;
	filter->finalized = GF_FALSE;
	gf_fs_load_source_dest_internal(filter->session, src_url, NULL, NULL, &e, filter, filter->target_filter ? filter->target_filter : filter->dst_filter, GF_TRUE, filter->no_dst_arg_inherit, NULL);
	//we manage to reassign an input registry
	if (e==GF_OK) {
		gf_free(src_url);
		if (target_filter) filter->dst_filter = NULL;
		return GF_TRUE;
	}
	if (!filter->finalized) {
		gf_free(src_url);
		return gf_filter_swap_source_register(filter);
	}

	for (i=0; i<gf_list_count(filter->destination_links); i++) {
		GF_Filter *af = gf_list_get(filter->destination_links, i);
		gf_mx_p(af->tasks_mx);
		if (af->num_input_pids) {
			u32 j;
			for (j=0; j<af->num_input_pids; j++) {
				GF_FilterPidInst *pidi = gf_list_get(af->input_pids, j);
				pidi->is_end_of_stream = GF_TRUE;
			}
		}
		gf_mx_v(af->tasks_mx);
		if (af->sticky) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_FILTER, ("Failed to find any filter for URL %s\n", src_url));
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_FILTER, ("Failed to find any filter for URL %s, disabling destination filter %s\n", src_url, af->name));
			af->removed = GF_TRUE;
		}
	}
	if (e==GF_NOT_SUPPORTED)
		e = GF_FILTER_NOT_FOUND;
	//nope ...
	gf_filter_setup_failure(filter, e);
	gf_free(src_url);
	return GF_FALSE;
}
Bool gf_filter_swap_source_register(GF_Filter *filter)
{
	u32 i;
	char *src_url=NULL;
	GF_Filter *target_filter=NULL;
	GF_Err e;
	const GF_FilterArgs *src_arg=NULL;

	while (gf_list_count(filter->postponed_packets)) {
		GF_FilterPacket *pck = gf_list_pop_front(filter->postponed_packets);
		gf_filter_packet_destroy(pck);
	}

	while (gf_list_count(filter->output_pids)) {
		GF_FilterPid *pid = gf_list_pop_back(filter->output_pids);
		pid->destroyed = GF_TRUE;
		gf_fs_post_task(filter->session, gf_filter_pid_del_task, filter, pid, "pid_delete", NULL);
	}
	gf_mx_p(filter->tasks_mx);
	filter->num_output_pids = 0;
	gf_mx_v(filter->tasks_mx);

	if (filter->freg->finalize) {
		FSESS_CHECK_THREAD(filter)
		filter->freg->finalize(filter);
		filter->finalized = GF_TRUE;
	}
	gf_list_add(filter->blacklisted, (void *)filter->freg);

	i=0;
	while (filter->freg->args) {
		src_arg = &filter->freg->args[i];
		if (!src_arg || !src_arg->arg_name) {
			src_arg=NULL;
			break;
		}
		i++;
		if (strcmp(src_arg->arg_name, "src")) continue;
		 
		if (src_arg->offset_in_private<0) continue;

#ifdef WIN32
		src_url = *(char **)( ((char *)filter->filter_udta) + src_arg->offset_in_private);
		*(char **)(((char *)filter->filter_udta) + src_arg->offset_in_private) = NULL;
#else
		src_url = *(char **) (filter->filter_udta + src_arg->offset_in_private);
		*(char **)(filter->filter_udta + src_arg->offset_in_private) = NULL;
#endif
		 break;
	}

	gf_free(filter->filter_udta);
	filter->filter_udta = NULL;
	if (!src_url) return GF_FALSE;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_FILTER, ("Swaping source filter for URL %s\n", src_url));

	target_filter = filter->target_filter;
	filter->finalized = GF_FALSE;
	gf_fs_load_source_dest_internal(filter->session, src_url, NULL, NULL, &e, filter, filter->target_filter ? filter->target_filter : filter->dst_filter, GF_TRUE, filter->no_dst_arg_inherit, NULL);
	 
	if (e==GF_OK) {
		gf_free(src_url);
		if (target_filter) filter->dst_filter = NULL;
		return GF_TRUE;
	}
	if (!filter->finalized) {
		gf_free(src_url);
		return gf_filter_swap_source_register(filter);
	}

	for (i=0; i<gf_list_count(filter->destination_links); i++) {
		GF_Filter *af = gf_list_get(filter->destination_links, i);
		gf_mx_p(af->tasks_mx);
		if (af->num_input_pids) {
			u32 j;
			for (j=0; j<af->num_input_pids; j++) {
				GF_FilterPidInst *pidi = gf_list_get(af->input_pids, j);
				pidi->is_end_of_stream = GF_TRUE;
			}
		}
		gf_mx_v(af->tasks_mx);
		if (af->sticky) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_FILTER, ("Failed to find any filter for URL %s\n", src_url));
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_FILTER, ("Failed to find any filter for URL %s, disabling destination filter %s\n", src_url, af->name));
			af->removed = GF_TRUE;
		}
	}
	if (e==GF_NOT_SUPPORTED)
		e = GF_FILTER_NOT_FOUND;
	 
	gf_filter_setup_failure(filter, e);
	gf_free(src_url);
	return GF_FALSE;
}