media-session: detect and block passthrough-only streams

If we see that the stream only has passthrough formats, make them
error immediately for now.
This commit is contained in:
Wim Taymans 2021-08-23 13:03:50 +02:00
parent 1a713e963a
commit 10c3bf5ff3

View file

@ -130,13 +130,14 @@ struct node {
unsigned int capture_sink:1; unsigned int capture_sink:1;
unsigned int virtual:1; unsigned int virtual:1;
unsigned int linking:1; unsigned int linking:1;
unsigned int passthrough_only:1;
}; };
static bool find_format(struct node *node) static bool find_format(struct node *node)
{ {
struct impl *impl = node->impl; struct impl *impl = node->impl;
struct sm_param *p; struct sm_param *p;
bool have_format = false; bool have_format = false, have_passthrough = false;
spa_list_for_each(p, &node->obj->param_list, link) { spa_list_for_each(p, &node->obj->param_list, link) {
struct spa_audio_info info = { 0, }; struct spa_audio_info info = { 0, };
@ -149,10 +150,14 @@ static bool find_format(struct node *node)
if (spa_format_parse(p->param, &info.media_type, &info.media_subtype) < 0) if (spa_format_parse(p->param, &info.media_type, &info.media_subtype) < 0)
continue; continue;
if (info.media_type != SPA_MEDIA_TYPE_audio || if (info.media_type != SPA_MEDIA_TYPE_audio)
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
continue; continue;
if (info.media_subtype != SPA_MEDIA_SUBTYPE_raw) {
have_passthrough = true;
continue;
}
spa_pod_object_fixate((struct spa_pod_object*)p->param); spa_pod_object_fixate((struct spa_pod_object*)p->param);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_pod(2, NULL, p->param); spa_debug_pod(2, NULL, p->param);
@ -182,6 +187,11 @@ static bool find_format(struct node *node)
have_format = true; have_format = true;
} }
if (!have_format && have_passthrough) {
pw_log_info("passthrough only stream found");
node->passthrough_only = true;
have_format = true;
}
return have_format; return have_format;
} }
@ -880,6 +890,13 @@ static int rescan_node(struct impl *impl, struct node *n)
} }
} }
if (n->passthrough_only) {
path_id = SPA_ID_INVALID;
peer = NULL;
reconnect = false;
goto do_link;
}
pw_log_info("trying to link node %d exclusive:%d reconnect:%d target:%d", pw_log_info("trying to link node %d exclusive:%d reconnect:%d target:%d",
n->id, exclusive, reconnect, path_id); n->id, exclusive, reconnect, path_id);
@ -900,7 +917,6 @@ static int rescan_node(struct impl *impl, struct node *n)
pw_log_warn("node %d target:%d not found, find fallback:%d", n->id, pw_log_warn("node %d target:%d not found, find fallback:%d", n->id,
path_id, reconnect); path_id, reconnect);
} }
if (path_id == SPA_ID_INVALID && (reconnect || n->connect_count == 0)) { if (path_id == SPA_ID_INVALID && (reconnect || n->connect_count == 0)) {
/* find fallback */ /* find fallback */
struct find_data find; struct find_data find;
@ -923,8 +939,6 @@ static int rescan_node(struct impl *impl, struct node *n)
do_link: do_link:
if (peer == NULL) { if (peer == NULL) {
struct sm_object *obj;
if (!reconnect) { if (!reconnect) {
pw_log_info("don-reconnect target node destroyed: destroy %d", n->id); pw_log_info("don-reconnect target node destroyed: destroy %d", n->id);
sm_media_session_destroy_object(impl->session, n->id); sm_media_session_destroy_object(impl->session, n->id);