void gf_filter_del(GF_Filter *filter)
{
	GF_LOG(GF_LOG_INFO, GF_LOG_FILTER, ("Filter %s destruction\n", filter->name));
	assert(filter);
//	assert(!filter->detached_pid_inst);
	assert(!filter->detach_pid_tasks_pending);
//	assert(!filter->swap_pidinst_dst);
	assert(!filter->swap_pidinst_src);


#ifdef GPAC_HAS_QJS
	jsfs_on_filter_destroyed(filter);
#endif

	if (filter->session->on_filter_create_destroy)
		filter->session->on_filter_create_destroy(filter->session->rt_udta, filter, GF_TRUE);

#ifndef GPAC_DISABLE_3D
	gf_list_del_item(filter->session->gl_providers, filter);
	gf_fs_check_gl_provider(filter->session);
#endif

#ifdef GPAC_MEMORY_TRACKING
	if (filter->session->check_allocs) {
		if (filter->max_nb_process>10 && (filter->max_nb_consecutive_process * 10 < filter->max_nb_process)) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\nFilter %s extensively uses memory alloc/free in process(): \n", filter->name));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\tmax stats of over %d calls (%d consecutive calls with no alloc/free):\n", filter->max_nb_process, filter->max_nb_consecutive_process));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\t\t%d allocs %d callocs %d reallocs %d free\n", filter->max_stats_nb_alloc, filter->max_stats_nb_calloc, filter->max_stats_nb_realloc, filter->max_stats_nb_free));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\tPlease consider rewriting the code\n"));
		}
	}
#endif

	//may happen when a filter is removed from the chain
	if (filter->postponed_packets) {
		while (gf_list_count(filter->postponed_packets)) {
			GF_FilterPacket *pck = gf_list_pop_front(filter->postponed_packets);
			gf_filter_packet_destroy(pck);
		}
		gf_list_del(filter->postponed_packets);
		filter->postponed_packets = NULL;
	}

	//delete output pids before the packet reservoir
	while (gf_list_count(filter->output_pids)) {
		gf_filter_pid_del(gf_list_pop_back(filter->output_pids));
	}
	gf_list_del(filter->output_pids);

	gf_list_del(filter->blacklisted);
	gf_list_del(filter->destination_filters);
	gf_list_del(filter->destination_links);
	gf_list_del(filter->source_filters);
	gf_list_del(filter->temp_input_pids);

	gf_list_del(filter->input_pids);
	gf_fq_del(filter->tasks, task_del);
	gf_fq_del(filter->pending_pids, NULL);

	reset_filter_args(filter);
	if (filter->src_args) gf_free(filter->src_args);

	if (filter->pcks_shared_reservoir)
		gf_fq_del(filter->pcks_shared_reservoir, gf_void_del);
	if (filter->pcks_inst_reservoir)
		gf_fq_del(filter->pcks_inst_reservoir, gf_void_del);
	if (filter->pcks_alloc_reservoir)
		gf_fq_del(filter->pcks_alloc_reservoir, gf_filterpacket_del);

	gf_mx_del(filter->pcks_mx);
	if (filter->tasks_mx)
		gf_mx_del(filter->tasks_mx);

	if (filter->id) gf_free(filter->id);
	if (filter->source_ids) gf_free(filter->source_ids);
	if (filter->dynamic_source_ids) gf_free(filter->dynamic_source_ids);
	if (filter->filter_udta) gf_free(filter->filter_udta);
	if (filter->orig_args) gf_free(filter->orig_args);
	if (filter->dst_args) gf_free(filter->dst_args);
	if (filter->name) gf_free(filter->name);
	if (filter->status_str) gf_free(filter->status_str);
	if (filter->restricted_source_id) gf_free(filter->restricted_source_id);

	if (!filter->session->in_final_flush && !filter->session->run_status) {
		u32 i, count;
		gf_mx_p(filter->session->filters_mx);
		count = gf_list_count(filter->session->filters);
		for (i=0; i<count; i++) {
			GF_Filter *a_filter = gf_list_get(filter->session->filters, i);
			gf_mx_p(a_filter->tasks_mx);
			gf_list_del_item(a_filter->destination_filters, filter);
			gf_list_del_item(a_filter->destination_links, filter);
			gf_list_del_item(a_filter->source_filters, filter);
			if (a_filter->cap_dst_filter==filter)
				a_filter->cap_dst_filter = NULL;
			if (a_filter->cloned_from == filter)
				a_filter->cloned_from = NULL;
			if (a_filter->on_setup_error_filter == filter)
				a_filter->on_setup_error_filter = NULL;
			if (a_filter->target_filter == filter)
				a_filter->target_filter = NULL;
			if (a_filter->dst_filter == filter)
				a_filter->dst_filter = NULL;
			gf_mx_v(a_filter->tasks_mx);
		}
		gf_mx_v(filter->session->filters_mx);
	}
	if (filter->instance_description)
		gf_free(filter->instance_description);
	if (filter->instance_version)
		gf_free(filter->instance_version);
	if (filter->instance_author)
		gf_free(filter->instance_author);
	if (filter->instance_help)
		gf_free(filter->instance_help);

#ifdef GPAC_HAS_QJS
	if (filter->iname)
		gf_free(filter->iname);
#endif

	if (filter->freg && (filter->freg->flags & GF_FS_REG_CUSTOM)) {
		if (! (filter->freg->flags & GF_FS_REG_SCRIPT))
			if (filter->forced_caps) gf_free( (void *) filter->forced_caps);
		gf_free( (char *) filter->freg->name);
		gf_free( (void *) filter->freg);
	}
	gf_free(filter);
}
void gf_filter_del(GF_Filter *filter)
{
	GF_LOG(GF_LOG_INFO, GF_LOG_FILTER, ("Filter %s destruction\n", filter->name));
	assert(filter);
 
	assert(!filter->detach_pid_tasks_pending);
 
	assert(!filter->swap_pidinst_src);


#ifdef GPAC_HAS_QJS
	jsfs_on_filter_destroyed(filter);
#endif

	if (filter->session->on_filter_create_destroy)
		filter->session->on_filter_create_destroy(filter->session->rt_udta, filter, GF_TRUE);

#ifndef GPAC_DISABLE_3D
	gf_list_del_item(filter->session->gl_providers, filter);
	gf_fs_check_gl_provider(filter->session);
#endif

#ifdef GPAC_MEMORY_TRACKING
	if (filter->session->check_allocs) {
		if (filter->max_nb_process>10 && (filter->max_nb_consecutive_process * 10 < filter->max_nb_process)) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\nFilter %s extensively uses memory alloc/free in process(): \n", filter->name));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\tmax stats of over %d calls (%d consecutive calls with no alloc/free):\n", filter->max_nb_process, filter->max_nb_consecutive_process));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\t\t%d allocs %d callocs %d reallocs %d free\n", filter->max_stats_nb_alloc, filter->max_stats_nb_calloc, filter->max_stats_nb_realloc, filter->max_stats_nb_free));
			GF_LOG(GF_LOG_WARNING, GF_LOG_FILTER, ("\tPlease consider rewriting the code\n"));
		}
	}
#endif

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

	 
	while (gf_list_count(filter->output_pids)) {
		gf_filter_pid_del(gf_list_pop_back(filter->output_pids));
	}
	gf_list_del(filter->output_pids);

	gf_list_del(filter->blacklisted);
	gf_list_del(filter->destination_filters);
	gf_list_del(filter->destination_links);
	gf_list_del(filter->source_filters);
	gf_list_del(filter->temp_input_pids);

	gf_list_del(filter->input_pids);
	gf_fq_del(filter->tasks, task_del);
	gf_fq_del(filter->pending_pids, NULL);

	reset_filter_args(filter);
	if (filter->src_args) gf_free(filter->src_args);

	if (filter->pcks_shared_reservoir)
		gf_fq_del(filter->pcks_shared_reservoir, gf_void_del);
	if (filter->pcks_inst_reservoir)
		gf_fq_del(filter->pcks_inst_reservoir, gf_void_del);
	if (filter->pcks_alloc_reservoir)
		gf_fq_del(filter->pcks_alloc_reservoir, gf_filterpacket_del);

	gf_mx_del(filter->pcks_mx);
	if (filter->tasks_mx)
		gf_mx_del(filter->tasks_mx);

	if (filter->id) gf_free(filter->id);
	if (filter->source_ids) gf_free(filter->source_ids);
	if (filter->dynamic_source_ids) gf_free(filter->dynamic_source_ids);
	if (filter->filter_udta) gf_free(filter->filter_udta);
	if (filter->orig_args) gf_free(filter->orig_args);
	if (filter->dst_args) gf_free(filter->dst_args);
	if (filter->name) gf_free(filter->name);
	if (filter->status_str) gf_free(filter->status_str);
	if (filter->restricted_source_id) gf_free(filter->restricted_source_id);

	if (!filter->session->in_final_flush && !filter->session->run_status) {
		u32 i, count;
		gf_mx_p(filter->session->filters_mx);
		count = gf_list_count(filter->session->filters);
		for (i=0; i<count; i++) {
			GF_Filter *a_filter = gf_list_get(filter->session->filters, i);
			gf_mx_p(a_filter->tasks_mx);
			gf_list_del_item(a_filter->destination_filters, filter);
			gf_list_del_item(a_filter->destination_links, filter);
			gf_list_del_item(a_filter->source_filters, filter);
			if (a_filter->cap_dst_filter==filter)
				a_filter->cap_dst_filter = NULL;
			if (a_filter->cloned_from == filter)
				a_filter->cloned_from = NULL;
			if (a_filter->on_setup_error_filter == filter)
				a_filter->on_setup_error_filter = NULL;
			if (a_filter->target_filter == filter)
				a_filter->target_filter = NULL;
			if (a_filter->dst_filter == filter)
				a_filter->dst_filter = NULL;
			gf_mx_v(a_filter->tasks_mx);
		}
		gf_mx_v(filter->session->filters_mx);
	}
	if (filter->instance_description)
		gf_free(filter->instance_description);
	if (filter->instance_version)
		gf_free(filter->instance_version);
	if (filter->instance_author)
		gf_free(filter->instance_author);
	if (filter->instance_help)
		gf_free(filter->instance_help);

#ifdef GPAC_HAS_QJS
	if (filter->iname)
		gf_free(filter->iname);
#endif

	if (filter->freg && (filter->freg->flags & GF_FS_REG_CUSTOM)) {
		if (! (filter->freg->flags & GF_FS_REG_SCRIPT))
			if (filter->forced_caps) gf_free( (void *) filter->forced_caps);
		gf_free( (char *) filter->freg->name);
		gf_free( (void *) filter->freg);
	}
	gf_free(filter);
}