From 737a84a10dfd126e9d430b4e135aaa30354f9642 Mon Sep 17 00:00:00 2001 From: jeanlf Date: Tue, 23 Apr 2024 10:52:19 +0200 Subject: [PATCH] defer link mode improvements --- applications/gpac/gpac.c | 105 ++++++++++++++++++++++------ applications/gpac/gpac_help.c | 8 ++- include/gpac/filters.h | 17 ++++- src/export.cpp | 1 + src/filter_core/filter.c | 50 ++++++++++--- src/filter_core/filter_pid.c | 27 +++++-- src/filter_core/filter_session.h | 7 +- src/filter_core/filter_session_js.c | 2 +- 8 files changed, 174 insertions(+), 43 deletions(-) diff --git a/applications/gpac/gpac.c b/applications/gpac/gpac.c index 6b603ec147..d1c8fa4ab1 100644 --- a/applications/gpac/gpac.c +++ b/applications/gpac/gpac.c @@ -122,6 +122,7 @@ static Bool revert_cache_file(void *cbck, char *item_name, char *item_path, GF_F #ifdef GPAC_DEFER_MODE static GF_Err print_pid_props(char *arg); static GF_Err probe_pid_link(char *arg); +static GF_Err print_pid_dests(char *arg); #endif #ifdef WIN32 @@ -1004,6 +1005,7 @@ int gpac_main(int _argc, char **_argv) || !strcmp(arg, "-g") || !strcmp(arg, "-pi") || !strcmp(arg, "-pl") + || !strcmp(arg, "-pd") || !strcmp(arg, "-se") ) { #endif @@ -1215,11 +1217,11 @@ static int gpac_run() f = gf_list_get(loaded_filters, gf_list_count(loaded_filters)-1-relink); } if (!f) { - fprintf(stderr, "Invalid filter index in %s\n", arg); + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Invalid filter index in %s\n", arg)); e=GF_BAD_PARAM; ERR_EXIT } - fprintf(stderr, "Relinking filter %s\n", gf_filter_get_name(f)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Relinking filter %s\n", gf_filter_get_name(f))); while (retry && gf_fs_check_filter(session, f)) { retry--; e = gf_filter_reconnect_output(f, NULL); @@ -1232,7 +1234,7 @@ static int gpac_run() continue; } if (e) { - fprintf(stderr, "Error relinking filter %s\n", gf_filter_get_name(f)); + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Error relinking filter %s\n", gf_filter_get_name(f))); ERR_EXIT } if (do_run) @@ -1247,24 +1249,20 @@ static int gpac_run() e = GF_NOT_SUPPORTED; ERR_EXIT } - fprintf(stderr, "\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); } continue; } else if (!strcmp(arg, "-f")) { - fprintf(stderr, "Running session\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Running session\n")); run_sess(); continue; } else if (!strcmp(arg, "-g")) { gf_fs_print_connections(session); - fprintf(stderr, "\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); continue; } else if (!strcmp(arg, "-s")) { gf_fs_print_stats(session); - fprintf(stderr, "\n"); - continue; - } else if (!strcmp(arg, "-stat")) { - //gf_fs_print_stats(session); - fprintf(stderr, "\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); continue; } else if (!strncmp(arg, "-pi", 3)) { e = print_pid_props(arg); @@ -1276,8 +1274,14 @@ static int gpac_run() ERR_EXIT } continue; + } else if (!strncmp(arg, "-pd", 3)) { + e = print_pid_dests(arg); + if (e) { + ERR_EXIT + } + continue; } else if (!strncmp(arg, "-se", 3)) { - fprintf(stderr, "Sending PLAY event\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Sending PLAY event\n")); gf_fs_send_deferred_play(session); } } @@ -1932,7 +1936,7 @@ static GF_Err print_pid_props(char *arg) if (e) return e; u32 j, count = gf_filter_get_opid_count(f); if (!count) { - fprintf(stderr, "Filter %s has no output\n", gf_filter_get_name(f)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Filter %s has no output\n", gf_filter_get_name(f))); return GF_OK; } for (j=0; j=0) && (p_idx != j)) continue; if (prefix=='-') { - fprintf(stderr, "Filter %s PID #%d name: %s\n", gf_filter_get_name(f), j, gf_filter_pid_get_name(pid) ); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Filter %s PID #%d name: %s\n", gf_filter_get_name(f), j, gf_filter_pid_get_name(pid) )); continue; } - fprintf(stderr, "Filter %s PID %s properties:\n", gf_filter_get_name(f), gf_filter_pid_get_name(pid) ); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Filter %s PID %s properties:\n", gf_filter_get_name(f), gf_filter_pid_get_name(pid) )); while (1) { u32 p4cc=0; const char *pname=NULL; const GF_PropertyValue *p = gf_filter_pid_enum_properties(pid, &prop_idx, &p4cc, &pname); if (!p) break; - fprintf(stdout, "Prop %s: %s\n", p4cc ? gf_props_4cc_get_name(p4cc) : pname, gf_props_dump(p4cc, p, szDump, GF_PROP_DUMP_DATA_NONE)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Prop %s: %s\n", p4cc ? gf_props_4cc_get_name(p4cc) : pname, gf_props_dump(p4cc, p, szDump, GF_PROP_DUMP_DATA_NONE))); } prop_idx=0; while (prefix=='+') { @@ -1958,9 +1962,12 @@ static GF_Err print_pid_props(char *arg) const char *pname=NULL; const GF_PropertyValue *p = gf_filter_pid_enum_info(pid, &prop_idx, &p4cc, &pname); if (!p) break; - fprintf(stdout, "Info %s: %s\n", p4cc ? gf_props_4cc_get_name(p4cc) : pname, gf_props_dump(p4cc, p, szDump, GF_PROP_DUMP_DATA_NONE)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Info %s: %s\n", p4cc ? gf_props_4cc_get_name(p4cc) : pname, gf_props_dump(p4cc, p, szDump, GF_PROP_DUMP_DATA_NONE))); } - fprintf(stderr, "\n"); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); + } + if (prefix=='-') { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); } return GF_OK; } @@ -1968,20 +1975,72 @@ static GF_Err probe_pid_link(char *arg) { GF_Filter *f; s32 opid_idx; + u8 prefix; char *fname = strchr(arg, '@'); - if (!fname) return GF_BAD_PARAM; + if (!fname) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Missing `@` directive in probe link\n")); + return GF_BAD_PARAM; + } - GF_Err e = extract_filter_and_pid(arg, &f, &opid_idx, NULL); + GF_Err e = extract_filter_and_pid(arg, &f, &opid_idx, &prefix); if (e) return e; if (opid_idx<0) opid_idx=0; char *res = NULL; - e = gf_filter_probe_link(f, opid_idx, fname+1, &res); + if (prefix=='+') + e = gf_filter_probe_links(f, opid_idx, fname+1, &res); + else + e = gf_filter_probe_link(f, opid_idx, fname+1, &res); + if (res) { - fprintf(stdout, "Probed chain from %s to %s: %s\n\n", gf_filter_get_name(f), fname+1, res); + if (!res[0]) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Probed chain from %s to %s: direct connection\n\n", gf_filter_get_name(f), fname+1)); + } else if (strchr(res, '|')) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Probed chains from %s to %s:\n", gf_filter_get_name(f), fname+1)); + char *cur=res; + while (1) { + u32 distance=0; + u32 priority=0; + char *sep = strchr(cur, '|'); + if (sep) sep[0] = 0; + char *w_sep = strchr(cur, ','); + if (w_sep) { + w_sep[0] = 0; + sscanf(cur, "%u;%u", &distance, &priority); + w_sep[0] = ','; + } + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\t- %s (priority %u distance %u)\n", w_sep ? w_sep+1 : cur, priority, distance)); + if (!sep) break; + sep[0] = '|'; + cur = sep+1; + } + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\n")); + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Probed chain from %s to %s: %s\n", gf_filter_get_name(f), fname+1, res)); + } gf_free(res); } else { - fprintf(stdout, "No filter chain from %s to %s: %s\n\n", gf_filter_get_name(f), fname+1, gf_error_to_string(e)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("No filter chain from %s to %s: %s\n\n", gf_filter_get_name(f), fname+1, gf_error_to_string(e))); + } + return GF_OK; +} + +static GF_Err print_pid_dests(char *arg) +{ + GF_Filter *f; + s32 p_idx; + u8 prefix; + char *res; + GF_Err e = extract_filter_and_pid(arg, &f, &p_idx, &prefix); + if (e) return e; + e = gf_filter_get_possible_destinations(f, p_idx, &res); + if (res) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Possible destinations for %s: %s\n", gf_filter_get_name(f), res)); + gf_free(res); + } else if (e==GF_FILTER_NOT_FOUND){ + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("No destinations for %s\n", gf_filter_get_name(f))); + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Failed to probe possible destinations for %s: %s\n\n", gf_filter_get_name(f), gf_error_to_string(e))); } return GF_OK; } diff --git a/applications/gpac/gpac_help.c b/applications/gpac/gpac_help.c index c1cd0da2b3..b22daf2135 100644 --- a/applications/gpac/gpac_help.c +++ b/applications/gpac/gpac_help.c @@ -888,9 +888,9 @@ static const char *gpac_defer = "This mode can be used to test loading filters one by one and asking for link resolution explicitly.\n" "This is mostly used to reproduce how sessions are build in more complex applications.\n" "\n" -"The options `rl`, `pi` and `pl` allow adressing a filter by index `F` in a list.\n" +"The options `rl`, `pi`, `pl` and `pd` allow adressing a filter by index `F` in a list.\n" "- if the option is suffixed with an `x` (e.g. `rlx=`), `F=0` means the last filter in the list of filters in the session\n" -"- otherwise, `F=0` means the last filter located before the option\n" +"- otherwise, `F=0` means the last filter declared before the option\n" "\n" "The relink options `-rl` and `-rlx` always flush the session (run until no more tasks are scheduled).\n" "The last run can be omitted.\n" @@ -910,7 +910,9 @@ static GF_GPACArg gpac_defer_args[] = GF_DEF_ARG("pi=[+|-][F[:i]]", NULL, "print PID properties (all or of index `i`) of filter `F` (default 0)\n" "- if prefixed with `-`: only list PIDs\n" "- if prefixed with `+`: also print PID info", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), - GF_DEF_ARG("pl=[F[:i]]@NAME", NULL, "probe filter chain from filter `F` (default 0) to the given filter `NAME`", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("pl=[+][F[:i]]@NAME", NULL, "probe filter chain from filter `F` (default 0) to the given filter `NAME`: \n" + "- if prefixed with `+`: print all known chains and their priorities", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("pd=[F[:i]]", NULL, "print possible PID destinations (all or of index `i`) of filter `F` (default 0)", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), GF_DEF_ARG("f", NULL, "flush session until no more tasks", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), GF_DEF_ARG("g", NULL, "print graph", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), GF_DEF_ARG("s", NULL, "print stats", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), diff --git a/include/gpac/filters.h b/include/gpac/filters.h index 65a4215eb5..c6f1b6374d 100644 --- a/include/gpac/filters.h +++ b/include/gpac/filters.h @@ -3315,11 +3315,26 @@ Bool gf_filter_relocate_url(GF_Filter *filter, const char *service_url, const ch */ GF_Err gf_filter_probe_link(GF_Filter *filter, u32 opid_idx, const char *fname, char **result_chain); +/*! Probes for possible link resolution towards a given filter description. Same as \ref gf_filter_probe_link but tests multiple links + +The syntax for each chain is `D;P,filters` with: +- `D`: distance between the source and target, as seen by the graph resolver (some filters may hide their distance) +- `P`: priority of the chain +- `filters`: comma-separated list of filters + +\param filter target filter +\param opid_idx output pid index of target filter +\param fname textual description of filter - If a source is used, returns an error. Destination can be identified using dst=URL pattern +\param result_chain resulting chains separated by a pipe character ('|') or NULL if error. MUST be freed by caller +\return error if any +*/ +GF_Err gf_filter_probe_links(GF_Filter *filter, u32 opid_idx, const char *fname, char **result_chain); + /*! Gets list of possible destinations for this filter \param filter target filter \param opid_idx output pid index of target filter. If negative, will check destinations for any of the output pids \param result_list resulting list as comma-separated list, or NULL if error. MUST be freed by caller. An empty chain means direct connection is possible -\return error if any, GF_FILTER_NOT_FOUND if no available chain +\return error if any, GF_FILTER_NOT_FOUND if no available destinations */ GF_Err gf_filter_get_possible_destinations(GF_Filter *filter, s32 opid_idx, char **result_list); diff --git a/src/export.cpp b/src/export.cpp index 772550fe42..179eb0cd43 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -2545,6 +2545,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_filter_meta_set_instances ) ) #pragma comment (linker, EXPORT_SYMBOL(gf_filter_meta_get_instances ) ) #pragma comment (linker, EXPORT_SYMBOL(gf_filter_probe_link ) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_filter_probe_links ) ) #pragma comment (linker, EXPORT_SYMBOL(gf_filter_get_possible_destinations ) ) #pragma comment (linker, EXPORT_SYMBOL(gf_filter_pck_discard ) ) diff --git a/src/filter_core/filter.c b/src/filter_core/filter.c index 59635ca624..1a26841723 100644 --- a/src/filter_core/filter.c +++ b/src/filter_core/filter.c @@ -5593,8 +5593,7 @@ void gf_filter_dump_buffers(GF_Filter *f) } #endif -GF_EXPORT -GF_Err gf_filter_probe_link(GF_Filter *filter, u32 opid_idx, const char *fname, char **res_chain) +static GF_Err gf_filter_probe_link_internal(GF_Filter *filter, u32 opid_idx, const char *fname, Bool all_links, char **res_chain) { char *fdesc=NULL; char szFmt[20]; @@ -5602,6 +5601,7 @@ GF_Err gf_filter_probe_link(GF_Filter *filter, u32 opid_idx, const char *fname, GF_Err e; GF_FilterPid *opid=NULL; GF_FilterSession *fs; + GF_List *tmp_blacklist; if (!filter || !fname || !res_chain) return GF_BAD_PARAM; *res_chain = NULL; fs = filter->session; @@ -5632,27 +5632,58 @@ GF_Err gf_filter_probe_link(GF_Filter *filter, u32 opid_idx, const char *fname, gf_fs_lock_filters(fs, GF_FALSE); return e; } + tmp_blacklist = gf_list_new(); + while (1) { + GF_LinkInfo link_info; + const GF_FilterRegister *last_freg = NULL; + GF_List *fchain = gf_filter_pid_compute_link(opid, new_f, tmp_blacklist, &link_info); + if (!fchain) break; + if (*res_chain && (*res_chain)[0]) { + gf_dynstrcat(res_chain, "|", NULL); + } + if (all_links) { + char szTmp[20]; + sprintf(szTmp, "%u;%u,", link_info.distance, link_info.priority); + gf_dynstrcat(res_chain, szTmp, NULL); + } - GF_List *fchain = gf_filter_pid_compute_link(opid, new_f); - if (fchain) { u32 i, count = gf_list_count(fchain); for (i=0; iname, ","); + if ((i+2==count) && (freg == new_f->freg)) + break; + gf_dynstrcat(res_chain, freg->name, i ? "," : NULL); + last_freg = freg; } gf_list_del(fchain); - } else { - e = GF_FILTER_NOT_FOUND; + if (! *res_chain) *res_chain = gf_strdup(""); + if (!last_freg) break; + gf_list_add(tmp_blacklist, (void*)last_freg); + if (!all_links) break; } + gf_list_del(tmp_blacklist); + gf_list_del_item(fs->filters, new_f); if (!new_f->finalized && new_f->freg->finalize) { new_f->freg->finalize(new_f); } gf_filter_del(new_f); gf_fs_lock_filters(fs, GF_FALSE); - return e; + if (*res_chain) return GF_OK; + return GF_FILTER_NOT_FOUND; } +GF_EXPORT +GF_Err gf_filter_probe_links(GF_Filter *filter, u32 opid_idx, const char *fname, char **res_chain) +{ + return gf_filter_probe_link_internal(filter, opid_idx, fname, GF_TRUE, res_chain); +} + +GF_EXPORT +GF_Err gf_filter_probe_link(GF_Filter *filter, u32 opid_idx, const char *fname, char **res_chain) +{ + return gf_filter_probe_link_internal(filter, opid_idx, fname, GF_FALSE, res_chain); +} GF_EXPORT @@ -5664,6 +5695,8 @@ GF_Err gf_filter_get_possible_destinations(GF_Filter *filter, s32 opid_idx, char if (opid_idx>=0) { opid = gf_list_get(filter->output_pids, opid_idx); if (opid==NULL) return GF_BAD_PARAM; + } else { + if (!filter->num_output_pids) return GF_FILTER_NOT_FOUND; } *res_list = NULL; count = gf_list_count(filter->session->links); @@ -5696,5 +5729,6 @@ GF_Err gf_filter_get_possible_destinations(GF_Filter *filter, s32 opid_idx, char gf_dynstrcat(res_list, src->freg->name, ","); } } + if (! *res_list) return GF_FILTER_NOT_FOUND; return GF_OK; } diff --git a/src/filter_core/filter_pid.c b/src/filter_core/filter_pid.c index 29b719f16e..2c2b747ecc 100644 --- a/src/filter_core/filter_pid.c +++ b/src/filter_core/filter_pid.c @@ -3113,7 +3113,7 @@ void dump_graph_edges(Bool is_before, GF_FilterRegDesc *reg_dst, GF_List *dijkst } #endif -static void gf_filter_pid_resolve_link_dijkstra(GF_FilterPid *pid, GF_Filter *dst, const char *prefRegister, Bool reconfigurable_only, GF_List *out_reg_chain) +static void gf_filter_pid_resolve_link_dijkstra(GF_FilterPid *pid, GF_Filter *dst, const char *prefRegister, Bool reconfigurable_only, GF_List *tmp_blacklist, GF_LinkInfo *link_info, GF_List *out_reg_chain) { GF_FilterRegDesc *reg_dst, *result; u32 orig_nb_bundles=0; @@ -3159,6 +3159,8 @@ static void gf_filter_pid_resolve_link_dijkstra(GF_FilterPid *pid, GF_Filter *ds Bool reconf_only = reconfigurable_only; GF_FilterRegDesc *reg_desc = gf_list_get(fsess->links, i); const GF_FilterRegister *freg = reg_desc->freg; + if (tmp_blacklist && (gf_list_find(tmp_blacklist, (void*)freg)>=0)) + continue; if (check_codec_id_raw) { Bool has_raw_out=GF_FALSE, has_non_raw_in=GF_FALSE; @@ -3464,10 +3466,22 @@ static void gf_filter_pid_resolve_link_dijkstra(GF_FilterPid *pid, GF_Filter *ds dijkstra_time_us = gf_sys_clock_high_res() - start_time_us; GF_LOG(GF_LOG_DEBUG, GF_LOG_FILTER, ("[Filters] Dijkstra: sorted filters in "LLU" us, Dijkstra done in "LLU" us on %d nodes %d edges\n", sort_time_us, dijkstra_time_us, dijsktra_node_count, dijsktra_edge_count)); + if (link_info) { + link_info->distance = 0; + link_info->priority = 0; + } if (result && result->destination) { GF_LOG(GF_LOG_DEBUG, GF_LOG_FILTER, ("[Filters] Dijkstra result: %s(%d)", result->freg->name, result->cap_idx)); + if (link_info) { + link_info->distance += result->dist; + link_info->priority += result->priority; + } result = result->destination; while (result->destination) { + if (link_info) { + link_info->distance += result->dist; + link_info->priority += result->priority; + } GF_LOG(GF_LOG_DEBUG, GF_LOG_FILTER, (" %s(%d)", result->freg->name, result->cap_idx )); gf_list_add(out_reg_chain, (void *) result->freg); gf_list_add(out_reg_chain, (void *) &result->freg->caps[result->cap_idx]); @@ -3523,7 +3537,7 @@ static GF_Filter *gf_filter_pid_resolve_link_internal(GF_FilterPid *pid, GF_Filt concat_reg(pid->filter->session, prefRegister, szForceReg, dst->dst_args); gf_mx_p(fsess->links_mx); - gf_filter_pid_resolve_link_dijkstra(pid, dst, prefRegister, reconfigurable_only, filter_chain); + gf_filter_pid_resolve_link_dijkstra(pid, dst, prefRegister, reconfigurable_only, NULL, NULL, filter_chain); gf_mx_v(fsess->links_mx); count = gf_list_count(filter_chain); @@ -3849,7 +3863,7 @@ u32 gf_filter_pid_resolve_link_length(GF_FilterPid *pid, GF_Filter *dst) static Bool gf_filter_pid_needs_explicit_resolution(GF_FilterPid *pid, GF_Filter *dst); -GF_List *gf_filter_pid_compute_link(GF_FilterPid *pid, GF_Filter *dst) +GF_List *gf_filter_pid_compute_link(GF_FilterPid *pid, GF_Filter *dst, GF_List *tmp_blacklist, GF_LinkInfo *link_info) { GF_FilterSession *fsess = pid->filter->session; GF_List *filter_chain; @@ -3882,7 +3896,7 @@ GF_List *gf_filter_pid_compute_link(GF_FilterPid *pid, GF_Filter *dst) concat_reg(pid->filter->session, prefRegister, szForceReg, dst->dst_args); gf_mx_p(fsess->links_mx); - gf_filter_pid_resolve_link_dijkstra(pid, dst, prefRegister, GF_FALSE, filter_chain); + gf_filter_pid_resolve_link_dijkstra(pid, dst, prefRegister, GF_FALSE, tmp_blacklist, link_info, filter_chain); gf_mx_v(fsess->links_mx); if (!gf_list_count(filter_chain)) { gf_list_del(filter_chain); @@ -5475,8 +5489,9 @@ static void gf_filter_pid_init_task(GF_FSTask *task) return; } - GF_LOG(pid->not_connected_ok ? GF_LOG_DEBUG : GF_LOG_WARNING, GF_LOG_FILTER, ("No filter chain found for PID %s in filter %s to any loaded filters - NOT CONNECTED\n", pid->name, pid->filter->name)); - + if (!(filter->session->flags & GF_FS_FLAG_FORCE_DEFER_LINK) && !filter->deferred_link) { + GF_LOG(pid->not_connected_ok ? GF_LOG_DEBUG : GF_LOG_WARNING, GF_LOG_FILTER, ("No filter chain found for PID %s in filter %s to any loaded filters - NOT CONNECTED\n", pid->name, pid->filter->name)); + } if (pid->filter->freg->process_event) { GF_FEVT_INIT(evt, GF_FEVT_CONNECT_FAIL, pid); pid->filter->freg->process_event(filter, &evt); diff --git a/src/filter_core/filter_session.h b/src/filter_core/filter_session.h index 83f0e894f5..bfc3a1a6b0 100644 --- a/src/filter_core/filter_session.h +++ b/src/filter_core/filter_session.h @@ -1276,8 +1276,13 @@ Bool gf_fs_check_filter_register_cap_ex(const GF_FilterRegister *f_reg, u32 inco Bool gf_filter_update_arg_apply(GF_Filter *filter, const char *arg_name, const char *arg_value, Bool is_sync_call); +typedef struct +{ + u32 distance; + u32 priority; +} GF_LinkInfo; -GF_List *gf_filter_pid_compute_link(GF_FilterPid *pid, GF_Filter *dst); +GF_List *gf_filter_pid_compute_link(GF_FilterPid *pid, GF_Filter *dst, GF_List *tmp_blacklist, GF_LinkInfo *link_info); GF_PropertyValue gf_filter_parse_prop_solve_env_var(GF_FilterSession *fs, GF_Filter *f, u32 type, const char *name, const char *value, const char *enum_values); diff --git a/src/filter_core/filter_session_js.c b/src/filter_core/filter_session_js.c index 1200660aec..8cad053c79 100644 --- a/src/filter_core/filter_session_js.c +++ b/src/filter_core/filter_session_js.c @@ -1518,7 +1518,7 @@ static JSValue jsff_compute_link(JSContext *ctx, JSValueConst this_val, int argc } JSValue res; - GF_List *fchain = gf_filter_pid_compute_link(opid, new_f); + GF_List *fchain = gf_filter_pid_compute_link(opid, new_f, NULL, 0); if (fchain) { res = JS_NewArray(ctx); u32 i, count = gf_list_count(fchain);