From 5ea10b5c301d3da92836e575ebae994bad6dc07c Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 11 Mar 2017 19:58:58 +0100 Subject: [PATCH] linuxdvb: improve handling of la_exlusive mode, fixes #4278 --- src/input/mpegts/linuxdvb/linuxdvb_frontend.c | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 35a46c62f..65bb71117 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -482,6 +482,7 @@ linuxdvb_frontend_is_enabled linuxdvb_adapter_t *la; tvh_hardware_t *th; char ubuf[UUID_HEX_SIZE]; + int w; if (lfe->lfe_fe_path == NULL) return MI_IS_ENABLED_NEVER; @@ -492,7 +493,7 @@ linuxdvb_frontend_is_enabled if (lfe->lfe_in_setup) return MI_IS_ENABLED_RETRY; if (lfe->lfe_type != DVB_TYPE_S) - return MI_IS_ENABLED_OK; + goto ok; /* check if any "blocking" tuner is running */ LIST_FOREACH(th, &tvh_hardware, th_link) { @@ -506,19 +507,34 @@ linuxdvb_frontend_is_enabled return MI_IS_ENABLED_NEVER; /* invalid master */ if (lfe2->lfe_refcount <= 0) return MI_IS_ENABLED_RETRY; /* prefer master */ - return linuxdvb_satconf_match_mux(lfe2->lfe_satconf, mm) ? - MI_IS_ENABLED_OK : MI_IS_ENABLED_RETRY; + if (linuxdvb_satconf_match_mux(lfe2->lfe_satconf, mm)) + goto ok; + return MI_IS_ENABLED_RETRY; } if (lfe2->lfe_master && !strcmp(lfe2->lfe_master, idnode_uuid_as_str(&lfe->ti_id, ubuf)) && lfe2->lfe_refcount > 0) { if (lfe->lfe_satconf == NULL) return MI_IS_ENABLED_NEVER; - return linuxdvb_satconf_match_mux(lfe->lfe_satconf, mm) ? - MI_IS_ENABLED_OK : MI_IS_ENABLED_RETRY; + if (linuxdvb_satconf_match_mux(lfe->lfe_satconf, mm)) + goto ok; + return MI_IS_ENABLED_RETRY; } } } + + +ok: + if (lfe->lfe_adapter->la_exclusive) { + w = -1; + LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + if (lfe2 == lfe) continue; + w = MAX(w, mpegts_input_get_weight((mpegts_input_t *)lfe2, mm, flags, weight)); + } + if (w >= weight) + return MI_IS_ENABLED_RETRY; + } + return MI_IS_ENABLED_OK; } @@ -584,6 +600,31 @@ linuxdvb_frontend_stop_mux mpegts_pid_done(&lfe->lfe_pids); } +static int +linuxdvb_frontend_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) +{ + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; + mpegts_mux_instance_t *lmmi; + + if (!lfe->lfe_adapter->la_exclusive) + return 0; + + /* Stop other active frontend */ + LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + if (lfe2 == lfe) continue; + pthread_mutex_lock(&lfe->mi_output_lock); + lmmi = LIST_FIRST(&lfe->mi_mux_active); + pthread_mutex_unlock(&lfe->mi_output_lock); + if (lmmi) + break; + } + if (lmmi) { + /* Stop */ + lmmi->mmi_mux->mm_stop(lmmi->mmi_mux, 1, SM_CODE_ABORTED); + } + return 0; +} + static int linuxdvb_frontend_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) @@ -1989,6 +2030,7 @@ linuxdvb_frontend_create lfe->ti_wizard_get = linuxdvb_frontend_wizard_get; lfe->ti_wizard_set = linuxdvb_frontend_wizard_set; lfe->mi_is_enabled = linuxdvb_frontend_is_enabled; + lfe->mi_warm_mux = linuxdvb_frontend_warm_mux; lfe->mi_start_mux = linuxdvb_frontend_start_mux; lfe->mi_stop_mux = linuxdvb_frontend_stop_mux; lfe->mi_network_list = linuxdvb_frontend_network_list; -- 2.47.2