void gf_filter_remove(GF_Filter *filter)
{
	u32 i;
	if (!filter) return;

	//locate source filter(s)
	gf_mx_p(filter->tasks_mx);
	for (i=0; i<filter->num_input_pids; i++) {
		GF_FilterPidInst *pidi = gf_list_get(filter->input_pids, i);
		//fanout, only disconnect this pid instance
		if (pidi->pid->num_destinations>1) {
			//post disconnect
			gf_fs_post_task(filter->session, gf_filter_pid_disconnect_task, filter, pidi->pid, "pidinst_disconnect", NULL);
		}
		//this is a source for the chain
		else if (!pidi->pid->filter->num_input_pids) {
			gf_filter_remove_internal(pidi->pid->filter, NULL, GF_FALSE);
		}
		//otherwise walk down the chain
		else {
			gf_filter_remove(pidi->pid->filter);
		}
	}
	gf_mx_v(filter->tasks_mx);
}
void gf_filter_remove(GF_Filter *filter)
{
	u32 i;
	if (!filter) return;

	 
	gf_mx_p(filter->tasks_mx);
	for (i=0; i<filter->num_input_pids; i++) {
		GF_FilterPidInst *pidi = gf_list_get(filter->input_pids, i);
		 
		if (pidi->pid->num_destinations>1) {
			 
			gf_fs_post_task(filter->session, gf_filter_pid_disconnect_task, filter, pidi->pid, "pidinst_disconnect", NULL);
		}
		 
		else if (!pidi->pid->filter->num_input_pids) {
			gf_filter_remove_internal(pidi->pid->filter, NULL, GF_FALSE);
		}
		 
		else {
			gf_filter_remove(pidi->pid->filter);
		}
	}
	gf_mx_v(filter->tasks_mx);
}