GF_Err ctxload_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
{
	CTXLoadPriv *priv = gf_filter_get_udta(filter);
	const GF_PropertyValue *prop;

	if (is_remove) {
		priv->in_pid = NULL;
		if (priv->out_pid) {
			gf_filter_pid_remove(priv->out_pid);
			priv->out_pid = NULL;
		}
		return GF_OK;
	}

	if (! gf_filter_pid_check_caps(pid))
		return GF_NOT_SUPPORTED;

	//we must have a file path
	prop = gf_filter_pid_get_property(pid, GF_PROP_PID_FILEPATH);
	if (!prop || ! prop->value.string) {
		return GF_NOT_SUPPORTED;
	}

	if (!priv->in_pid) {
		GF_FilterEvent fevt;
		priv->in_pid = pid;

		//we work with full file only, send a play event on source to indicate that
		GF_FEVT_INIT(fevt, GF_FEVT_PLAY, pid);
		fevt.play.start_range = 0;
		fevt.base.on_pid = priv->in_pid;
		fevt.play.full_file_only = GF_TRUE;
		gf_filter_pid_send_event(priv->in_pid, &fevt);

	} else {
		if (pid != priv->in_pid) {
			return GF_REQUIRES_NEW_INSTANCE;
		}
		//update of PID filename
		if (!prop->value.string || !priv->file_name || strcmp(prop->value.string, priv->file_name))
			return GF_NOT_SUPPORTED;
		return GF_OK;
	}

	priv->file_name = prop->value.string;
	priv->nb_streams = 1;

	//declare a new output PID of type scene, codecid RAW
	priv->out_pid = gf_filter_pid_new(filter);

	gf_filter_pid_copy_properties(priv->out_pid, pid);
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_SCENE) );
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_IN_IOD, &PROP_BOOL(GF_TRUE) );

	gf_filter_pid_set_udta(pid, priv->out_pid);


	priv->file_size = 0;
	priv->load_flags = 0;
	prop = gf_filter_pid_get_property(pid, GF_PROP_PID_ESID);
	priv->base_stream_id = prop ? prop->value.uint : -1;

	priv->pck_time = -1;


	switch (priv->load.type) {
	case GF_SM_LOAD_BT:
		gf_filter_set_name(filter, "Load:BT");
		break;
	case GF_SM_LOAD_VRML:
		gf_filter_set_name(filter, "Load:VRML97");
		break;
	case GF_SM_LOAD_X3DV:
		gf_filter_set_name(filter, "Load:X3D+vrml");
		break;
	case GF_SM_LOAD_XMTA:
		gf_filter_set_name(filter, "Load:XMTA");
		break;
	case GF_SM_LOAD_X3D:
		gf_filter_set_name(filter, "Load:X3D+XML Syntax");
		break;
	case GF_SM_LOAD_SWF:
		gf_filter_set_name(filter, "Load:SWF");
		break;
	case GF_SM_LOAD_XSR:
		gf_filter_set_name(filter, "Load:LASeRML");
		break;
	case GF_SM_LOAD_MP4:
		gf_filter_set_name(filter, "Load:MP4BIFSMemory");
		break;
	default:
		break;
	}

	return GF_OK;
}
GF_Err ctxload_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
{
	CTXLoadPriv *priv = gf_filter_get_udta(filter);
	const GF_PropertyValue *prop;

	if (is_remove) {
		priv->in_pid = NULL;
		if (priv->out_pid) {
			gf_filter_pid_remove(priv->out_pid);
			priv->out_pid = NULL;
		}
		return GF_OK;
	}

	if (! gf_filter_pid_check_caps(pid))
		return GF_NOT_SUPPORTED;

	 
	prop = gf_filter_pid_get_property(pid, GF_PROP_PID_FILEPATH);
	if (!prop || ! prop->value.string) {
		return GF_NOT_SUPPORTED;
	}

	if (!priv->in_pid) {
		GF_FilterEvent fevt;
		priv->in_pid = pid;

		 
		GF_FEVT_INIT(fevt, GF_FEVT_PLAY, pid);
		fevt.play.start_range = 0;
		fevt.base.on_pid = priv->in_pid;
		fevt.play.full_file_only = GF_TRUE;
		gf_filter_pid_send_event(priv->in_pid, &fevt);

	} else {
		if (pid != priv->in_pid) {
			return GF_REQUIRES_NEW_INSTANCE;
		}
		 
		if (!prop->value.string || !priv->file_name || strcmp(prop->value.string, priv->file_name))
			return GF_NOT_SUPPORTED;
		return GF_OK;
	}

	priv->file_name = prop->value.string;
	priv->nb_streams = 1;

	 
	priv->out_pid = gf_filter_pid_new(filter);

	gf_filter_pid_copy_properties(priv->out_pid, pid);
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_SCENE) );
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
	gf_filter_pid_set_property(priv->out_pid, GF_PROP_PID_IN_IOD, &PROP_BOOL(GF_TRUE) );

	gf_filter_pid_set_udta(pid, priv->out_pid);


	priv->file_size = 0;
	priv->load_flags = 0;
	prop = gf_filter_pid_get_property(pid, GF_PROP_PID_ESID);
	priv->base_stream_id = prop ? prop->value.uint : -1;

	priv->pck_time = -1;


	switch (priv->load.type) {
	case GF_SM_LOAD_BT:
		gf_filter_set_name(filter, "Load:BT");
		break;
	case GF_SM_LOAD_VRML:
		gf_filter_set_name(filter, "Load:VRML97");
		break;
	case GF_SM_LOAD_X3DV:
		gf_filter_set_name(filter, "Load:X3D+vrml");
		break;
	case GF_SM_LOAD_XMTA:
		gf_filter_set_name(filter, "Load:XMTA");
		break;
	case GF_SM_LOAD_X3D:
		gf_filter_set_name(filter, "Load:X3D+XML Syntax");
		break;
	case GF_SM_LOAD_SWF:
		gf_filter_set_name(filter, "Load:SWF");
		break;
	case GF_SM_LOAD_XSR:
		gf_filter_set_name(filter, "Load:LASeRML");
		break;
	case GF_SM_LOAD_MP4:
		gf_filter_set_name(filter, "Load:MP4BIFSMemory");
		break;
	default:
		break;
	}

	return GF_OK;
}