GF_Err gf_filter_pid_raw_new(GF_Filter *filter, const char *url, const char *local_file, const char *mime_type, const char *fext, u8 *probe_data, u32 probe_size, Bool trust_mime, GF_FilterPid **out_pid)
{
	char tmp_ext[50];
	u32 ext_len=0;
	Bool ext_not_trusted, is_new_pid = GF_FALSE;
	GF_FilterPid *pid = *out_pid;
	if (!pid) {
		pid = gf_filter_pid_new(filter);
		if (!pid) {
			return GF_OUT_OF_MEM;
		}
		pid->max_buffer_unit = 1;
		is_new_pid = GF_TRUE;
		*out_pid = pid;
	}

	gf_filter_pid_set_property(pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_FILE) );

	if (local_file)
        	gf_filter_pid_set_property(pid, GF_PROP_PID_FILEPATH, &PROP_STRING(local_file));


	if (url) {
		gf_filter_pid_set_property(pid, GF_PROP_PID_URL, &PROP_STRING(url));

		if (!strnicmp(url, "isobmff://", 10)) {
			gf_filter_pid_set_name(pid, "isobmff://");
			fext = "mp4";
			mime_type = "video/mp4";
			if (is_new_pid)
				gf_filter_pid_set_eos(pid);
		} else {
			char *sep = gf_file_basename(url);

			gf_filter_pid_set_name(pid, sep);
		}

		if (fext) {
			strncpy(tmp_ext, fext, 20);
			tmp_ext[20] = 0;
			strlwr(tmp_ext);
			gf_filter_pid_set_property(pid, GF_PROP_PID_FILE_EXT, &PROP_STRING(tmp_ext));
			ext_len = (u32) strlen(tmp_ext);
		} else {
			char *ext = gf_file_ext_start(url);
			if (ext) ext++;

			if (ext) {
				char *s = strchr(ext, '#');
				if (s) s[0] = 0;

				strncpy(tmp_ext, ext, 20);
				tmp_ext[20] = 0;
				strlwr(tmp_ext);
				gf_filter_pid_set_property(pid, GF_PROP_PID_FILE_EXT, &PROP_STRING(tmp_ext));
				ext_len = (u32) strlen(tmp_ext);
				if (s) s[0] = '#';
			}
		}
	}

	ext_not_trusted = GF_FALSE;
	//probe data
	if ((!mime_type || !trust_mime) && !filter->no_probe && is_new_pid && probe_data && probe_size && !(filter->session->flags & GF_FS_FLAG_NO_PROBE)) {
		u32 i, count;
		GF_FilterProbeScore score, max_score = GF_FPROBE_NOT_SUPPORTED;
		const char *probe_mime = NULL;
		gf_mx_p(filter->session->filters_mx);
		count = gf_list_count(filter->session->registry);
		for (i=0; i<count; i++) {
			const char *a_mime;
			const GF_FilterRegister *freg = gf_list_get(filter->session->registry, i);
			if (!freg || !freg->probe_data) continue;
			score = GF_FPROBE_NOT_SUPPORTED;
			a_mime = freg->probe_data(probe_data, probe_size, &score);
			if (score==GF_FPROBE_NOT_SUPPORTED) {
				u32 k;
				for (k=0;k<freg->nb_caps && !ext_not_trusted && ext_len; k++) {
					const char *value;
					const GF_FilterCapability *cap = &freg->caps[k];
					if (!(cap->flags & GF_CAPFLAG_IN_BUNDLE)) continue;
					if (!(cap->flags & GF_CAPFLAG_INPUT)) continue;
					if (cap->code != GF_PROP_PID_FILE_EXT) continue;
					value = cap->val.value.string;
					while (value && ext_len) {
						const char *match = strstr(value, tmp_ext);
						if (!match) break;
						if (!match[ext_len] || (match[ext_len]=='|')) {
							ext_not_trusted = GF_TRUE;
							break;
						}
						value = match+ext_len;
					}
				}
			} else if (score==GF_FPROBE_EXT_MATCH) {
				if (a_mime && ext_len && strstr(a_mime, tmp_ext)) {
					ext_not_trusted = GF_FALSE;
					probe_mime = NULL;
					break;
				}
			} else {
				if (a_mime) {
					GF_LOG(GF_LOG_INFO, GF_LOG_FILTER, ("Data Prober (filter %s) detected format is%s mime %s\n", freg->name, (score==GF_FPROBE_SUPPORTED) ? "" :  "maybe", a_mime));
				}
				if (a_mime && (score > max_score)) {
					probe_mime = a_mime;
					max_score = score;
				}
			}
		}
		gf_mx_v(filter->session->filters_mx);

		pid->ext_not_trusted = ext_not_trusted;

		if (probe_mime) {
			mime_type = probe_mime;
		}
	}
	//we ignore mime type on pid reconfigure - some server will overwrite valid type to application/octet-string or binary/octet-string
	//on a byte-range request or secondary fetch
	//this is safe for now as the only reconfig we do is in HTTP streaming context
	//we furthermore blacklist *octet-* mimes
	if (mime_type && is_new_pid && !strstr(mime_type, "/octet-")) {
		strncpy(tmp_ext, mime_type, 50);
		tmp_ext[49] = 0;
		strlwr(tmp_ext);
		gf_filter_pid_set_property(pid, GF_PROP_PID_MIME, &PROP_STRING( tmp_ext ));
		//we have a mime, disable extension checking
		pid->ext_not_trusted = GF_TRUE;
	}

	return GF_OK;
}
GF_Err gf_filter_pid_raw_new(GF_Filter *filter, const char *url, const char *local_file, const char *mime_type, const char *fext, u8 *probe_data, u32 probe_size, Bool trust_mime, GF_FilterPid **out_pid)
{
	char tmp_ext[50];
	u32 ext_len=0;
	Bool ext_not_trusted, is_new_pid = GF_FALSE;
	GF_FilterPid *pid = *out_pid;
	if (!pid) {
		pid = gf_filter_pid_new(filter);
		if (!pid) {
			return GF_OUT_OF_MEM;
		}
		pid->max_buffer_unit = 1;
		is_new_pid = GF_TRUE;
		*out_pid = pid;
	}

	gf_filter_pid_set_property(pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_FILE) );

	if (local_file)
        	gf_filter_pid_set_property(pid, GF_PROP_PID_FILEPATH, &PROP_STRING(local_file));


	if (url) {
		gf_filter_pid_set_property(pid, GF_PROP_PID_URL, &PROP_STRING(url));

		if (!strnicmp(url, "isobmff://", 10)) {
			gf_filter_pid_set_name(pid, "isobmff://");
			fext = "mp4";
			mime_type = "video/mp4";
			if (is_new_pid)
				gf_filter_pid_set_eos(pid);
		} else {
			char *sep = gf_file_basename(url);

			gf_filter_pid_set_name(pid, sep);
		}

		if (fext) {
			strncpy(tmp_ext, fext, 20);
			tmp_ext[20] = 0;
			strlwr(tmp_ext);
			gf_filter_pid_set_property(pid, GF_PROP_PID_FILE_EXT, &PROP_STRING(tmp_ext));
			ext_len = (u32) strlen(tmp_ext);
		} else {
			char *ext = gf_file_ext_start(url);
			if (ext) ext++;

			if (ext) {
				char *s = strchr(ext, '#');
				if (s) s[0] = 0;

				strncpy(tmp_ext, ext, 20);
				tmp_ext[20] = 0;
				strlwr(tmp_ext);
				gf_filter_pid_set_property(pid, GF_PROP_PID_FILE_EXT, &PROP_STRING(tmp_ext));
				ext_len = (u32) strlen(tmp_ext);
				if (s) s[0] = '#';
			}
		}
	}

	ext_not_trusted = GF_FALSE;
	 
	if ((!mime_type || !trust_mime) && !filter->no_probe && is_new_pid && probe_data && probe_size && !(filter->session->flags & GF_FS_FLAG_NO_PROBE)) {
		u32 i, count;
		GF_FilterProbeScore score, max_score = GF_FPROBE_NOT_SUPPORTED;
		const char *probe_mime = NULL;
		gf_mx_p(filter->session->filters_mx);
		count = gf_list_count(filter->session->registry);
		for (i=0; i<count; i++) {
			const char *a_mime;
			const GF_FilterRegister *freg = gf_list_get(filter->session->registry, i);
			if (!freg || !freg->probe_data) continue;
			score = GF_FPROBE_NOT_SUPPORTED;
			a_mime = freg->probe_data(probe_data, probe_size, &score);
			if (score==GF_FPROBE_NOT_SUPPORTED) {
				u32 k;
				for (k=0;k<freg->nb_caps && !ext_not_trusted && ext_len; k++) {
					const char *value;
					const GF_FilterCapability *cap = &freg->caps[k];
					if (!(cap->flags & GF_CAPFLAG_IN_BUNDLE)) continue;
					if (!(cap->flags & GF_CAPFLAG_INPUT)) continue;
					if (cap->code != GF_PROP_PID_FILE_EXT) continue;
					value = cap->val.value.string;
					while (value && ext_len) {
						const char *match = strstr(value, tmp_ext);
						if (!match) break;
						if (!match[ext_len] || (match[ext_len]=='|')) {
							ext_not_trusted = GF_TRUE;
							break;
						}
						value = match+ext_len;
					}
				}
			} else if (score==GF_FPROBE_EXT_MATCH) {
				if (a_mime && ext_len && strstr(a_mime, tmp_ext)) {
					ext_not_trusted = GF_FALSE;
					probe_mime = NULL;
					break;
				}
			} else {
				if (a_mime) {
					GF_LOG(GF_LOG_INFO, GF_LOG_FILTER, ("Data Prober (filter %s) detected format is%s mime %s\n", freg->name, (score==GF_FPROBE_SUPPORTED) ? "" :  "maybe", a_mime));
				}
				if (a_mime && (score > max_score)) {
					probe_mime = a_mime;
					max_score = score;
				}
			}
		}
		gf_mx_v(filter->session->filters_mx);

		pid->ext_not_trusted = ext_not_trusted;

		if (probe_mime) {
			mime_type = probe_mime;
		}
	}
	 
	 
	 
	 
	if (mime_type && is_new_pid && !strstr(mime_type, "/octet-")) {
		strncpy(tmp_ext, mime_type, 50);
		tmp_ext[49] = 0;
		strlwr(tmp_ext);
		gf_filter_pid_set_property(pid, GF_PROP_PID_MIME, &PROP_STRING( tmp_ext ));
		 
		pid->ext_not_trusted = GF_TRUE;
	}

	return GF_OK;
}