From 0cd6b6d12f7520ce0b84511be699b325ad533cf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20=C3=96man?=
Date: Mon, 21 Apr 2008 17:29:11 +0000
Subject: [PATCH] Add code for deleting a DVB mux (and transports)
---
ajaxui/ajaxui_config_dvb.c | 39 +++++++++++++++++++++++++++++
avgen.c | 1 -
dvb.c | Bin 15195 -> 16108 bytes
dvb.h | 8 ++++++
dvb_fe.c | 49 ++++++++++++++++++++++++++++++++++---
file_input.c | 1 -
iptv_input.c | 6 -----
transports.c | 31 +++++++++++++++++++++++
transports.h | 2 ++
tvhead.h | 17 ++++++-------
v4l.c | 1 -
11 files changed, 133 insertions(+), 22 deletions(-)
diff --git a/ajaxui/ajaxui_config_dvb.c b/ajaxui/ajaxui_config_dvb.c
index c6172f07..65bda45c 100644
--- a/ajaxui/ajaxui_config_dvb.c
+++ b/ajaxui/ajaxui_config_dvb.c
@@ -142,6 +142,12 @@ dvb_make_add_link(tcp_queue_t *tq, th_dvb_adapter_t *tda, const char *result)
"onClick=\"new Ajax.Updater('addmux', "
"'/ajax/dvbadapteraddmux/%s', {method: 'get'})\""
">Add new...
", tda->tda_identifier);
+
+ tcp_qprintf(tq,
+ "Delete all muxes
", tda->tda_identifier);
}
if(result) {
@@ -641,6 +647,38 @@ ajax_dvbmuxeditor(http_connection_t *hc, http_reply_t *hr,
return 0;
}
+
+/**
+ * Delete all muxes on an adapter
+ */
+static int
+ajax_adapterdelmuxes(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
+{
+ th_dvb_adapter_t *tda;
+ th_dvb_mux_instance_t *tdmi;
+ tcp_queue_t *tq = &hr->hr_tq;
+
+ if(remain == NULL || (tda = dvb_adapter_find_by_identifier(remain)) == NULL)
+ return HTTP_STATUS_NOT_FOUND;
+
+ printf("Deleting all muxes on %s\n", tda->tda_identifier);
+
+ while((tdmi = LIST_FIRST(&tda->tda_muxes)) != NULL) {
+ printf("\tdeleting mux %s\n", tdmi->tdmi_identifier);
+ dvb_mux_destroy(tdmi);
+ }
+
+ tcp_qprintf(tq,
+ "new Ajax.Updater('dvbadaptereditor', "
+ "'/ajax/dvbadaptereditor/%s', "
+ "{method: 'get', evalScripts: true});",
+ tda->tda_identifier);
+
+ http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0);
+ return 0;
+}
+
/**
*
*/
@@ -651,6 +689,7 @@ ajax_config_dvb_init(void)
http_path_add("/ajax/dvbadaptersummary" , NULL, ajax_adaptersummary);
http_path_add("/ajax/dvbadaptereditor", NULL, ajax_adaptereditor);
http_path_add("/ajax/dvbadapteraddmux", NULL, ajax_adapteraddmux);
+ http_path_add("/ajax/dvbadapterdelmuxes", NULL, ajax_adapterdelmuxes);
http_path_add("/ajax/dvbadaptercreatemux", NULL, ajax_adaptercreatemux);
http_path_add("/ajax/dvbmuxeditor", NULL, ajax_dvbmuxeditor);
diff --git a/avgen.c b/avgen.c
index e9879e9c..6b71702b 100644
--- a/avgen.c
+++ b/avgen.c
@@ -114,7 +114,6 @@ avgen_init(void)
t->tht_name = strdup(ch->ch_name);
t->tht_provider = strdup("HTS Tvheadend");
- t->tht_network = strdup("Internal");
t->tht_identifier = strdup("test1");
diff --git a/dvb.c b/dvb.c
index cb2daf274806f9df5e6b3694c07b1c8d599c26f3..1eb8cfa62ab340315e63d509029a7542516cb477 100644
GIT binary patch
delta 783
zcmZuv!A=`75LG28>fVY1qNRtaMA2@fC_=q~!U001NP(&$Aob)ryI$7HuD!Bn15p*_
zBm5(%d`?f?EAqDelzdQ{2u+8+#bUQCIxRCx}7MN#sZ-Qd*<8P`@8S(
zYvrg}uLn?v3t@vmq2E6302K+y61fyK&&QA|#(<-RHG`4lNsx>Nq^NF4hw7>
zWu&Bv7J7koN$t%N&y=>AMkU8qYy0vDtPBV_Lcy;xgjf~~1~eYRU~Cm@mZvacY7AOR
z0hr0^Duey#(TVki70CnZ+zhk1wl!T6OcPonQ%(YA1Qiv!lnMz#9S@x7>x}0t3|)7+
zo%25V(&?S|!`&r{`6nGk@UaDF7u~Kc#Th%Ndn^O3e)-o6r+h98)P>mm+{c0pl&d!zj{hHShk00Ug^wF!2ESFZnK60Jf*C}|4ApWg1a}L
HdYk_M&0+qP
delta 21
dcmaD;d%J9dv%=(1cCpPx3Y%Cq&(R1F0|0F{2&(`9
diff --git a/dvb.h b/dvb.h
index fab485a1..ce73cf8f 100644
--- a/dvb.h
+++ b/dvb.h
@@ -60,4 +60,12 @@ void dvb_tdmi_save(th_dvb_mux_instance_t *tdmi);
void dvb_tda_save(th_dvb_adapter_t *tda);
+void dvb_mux_unref(th_dvb_mux_instance_t *tdmi);
+
+void dvb_fe_flush(th_dvb_mux_instance_t *tdmi);
+
+void dvb_mux_destroy(th_dvb_mux_instance_t *tdmi);
+
+void tdmi_stop(th_dvb_mux_instance_t *tdmi);
+
#endif /* DVB_H_ */
diff --git a/dvb_fe.c b/dvb_fe.c
index f600eb80..32931dde 100644
--- a/dvb_fe.c
+++ b/dvb_fe.c
@@ -72,10 +72,14 @@ dvb_fe_manager(void *aux)
pthread_mutex_lock(&tda->tda_lock);
pthread_cond_timedwait(&tda->tda_cond, &tda->tda_lock, &ts);
c = TAILQ_FIRST(&tda->tda_fe_cmd_queue);
- if(c != NULL)
- TAILQ_REMOVE(&tda->tda_fe_cmd_queue, c, link);
+ if(c != NULL) {
+
+ if(tdmi != NULL)
+ dvb_mux_unref(tdmi);
+
+ TAILQ_REMOVE(&tda->tda_fe_cmd_queue, c, link);
+ }
- pthread_mutex_unlock(&tda->tda_lock);
if(c != NULL) {
@@ -83,6 +87,15 @@ dvb_fe_manager(void *aux)
tdmi = c->tdmi;
+ if(tdmi->tdmi_refcnt == 1) {
+ dvb_mux_unref(tdmi);
+ tdmi = NULL;
+ pthread_mutex_unlock(&tda->tda_lock);
+ continue;
+ }
+
+ pthread_mutex_unlock(&tda->tda_lock);
+
p = *tdmi->tdmi_fe_params;
if(tda->tda_type == FE_QPSK) {
@@ -141,6 +154,8 @@ dvb_fe_manager(void *aux)
ioctl(tda->tda_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &v);
}
+ pthread_mutex_unlock(&tda->tda_lock);
+
if(tdmi == NULL)
continue;
@@ -188,11 +203,13 @@ dvb_fe_start(th_dvb_adapter_t *tda)
/**
* Stop the given TDMI
*/
-static void
+void
tdmi_stop(th_dvb_mux_instance_t *tdmi)
{
th_dvb_table_t *tdt;
+ tdmi->tdmi_adapter->tda_mux_current = NULL;
+
pthread_mutex_lock(&tdmi->tdmi_table_lock);
while((tdt = LIST_FIRST(&tdmi->tdmi_tables)) != NULL)
@@ -242,7 +259,31 @@ dvb_tune_tdmi(th_dvb_mux_instance_t *tdmi, int maylog, tdmi_state_t state)
c = malloc(sizeof(dvb_fe_cmd_t));
c->tdmi = tdmi;
pthread_mutex_lock(&tda->tda_lock);
+ tdmi->tdmi_refcnt++;
TAILQ_INSERT_TAIL(&tda->tda_fe_cmd_queue, c, link);
pthread_cond_signal(&tda->tda_cond);
pthread_mutex_unlock(&tda->tda_lock);
}
+
+
+/**
+ * Flush pending tuning commands for frontend
+ *
+ * tda_lock must be held
+ */
+void
+dvb_fe_flush(th_dvb_mux_instance_t *tdmi)
+{
+ dvb_fe_cmd_t *c;
+ th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+
+ TAILQ_FOREACH(c, &tda->tda_fe_cmd_queue, link)
+ if(c->tdmi == tdmi)
+ break;
+ if(c == NULL)
+ return;
+
+ TAILQ_REMOVE(&tda->tda_fe_cmd_queue, c, link);
+ dvb_mux_unref(tdmi);
+ free(c);
+}
diff --git a/file_input.c b/file_input.c
index 30e4d315..6694e9bc 100644
--- a/file_input.c
+++ b/file_input.c
@@ -154,7 +154,6 @@ file_input_init(void)
t->tht_name = strdup(ch->ch_name);
t->tht_provider = strdup("HTS Tvheadend");
- t->tht_network = strdup("Internal");
t->tht_identifier = strdup(ch->ch_name);
t->tht_file_input = fi;
transport_set_channel(t, ch->ch_name);
diff --git a/iptv_input.c b/iptv_input.c
index a43213ad..e87a8a13 100644
--- a/iptv_input.c
+++ b/iptv_input.c
@@ -232,12 +232,6 @@ iptv_configure_transport(th_transport_t *t, const char *iptv_type,
else
t->tht_provider = strdup("IPTV");
- s = config_get_str_sub(head, "network", NULL);
- if(s != NULL)
- t->tht_network = strdup(s);
- else
- t->tht_network = strdup(inet_ntoa(t->tht_iptv_group_addr));
-
snprintf(buf, sizeof(buf), "iptv_%s_%d",
inet_ntoa(t->tht_iptv_group_addr), t->tht_iptv_port);
t->tht_identifier = strdup(buf);
diff --git a/transports.c b/transports.c
index e24ab09e..f3dc3f85 100644
--- a/transports.c
+++ b/transports.c
@@ -402,6 +402,37 @@ transport_monitor(void *aux, int64_t now)
#endif
+/**
+ * Destroy a transport
+ */
+void
+transport_destroy(th_transport_t *t)
+{
+ th_stream_t *st;
+
+ free((void *)t->tht_name);
+
+ if(t->tht_channel != NULL) {
+ t->tht_channel = NULL;
+ LIST_REMOVE(t, tht_channel_link);
+ }
+
+ LIST_REMOVE(t, tht_mux_link);
+
+ transport_flush_subscribers(t);
+
+ free(t->tht_identifier);
+ free(t->tht_servicename);
+ free(t->tht_channelname);
+ free(t->tht_provider);
+
+ while((st = LIST_FIRST(&t->tht_streams)) != NULL) {
+ LIST_REMOVE(st, st_link);
+ free(st);
+ }
+}
+
+
/**
* Create and initialize a new transport struct
*/
diff --git a/transports.h b/transports.h
index 29d61495..754dc7fc 100644
--- a/transports.h
+++ b/transports.h
@@ -49,4 +49,6 @@ int transport_is_tv(th_transport_t *t);
int transport_is_available(th_transport_t *t);
+void transport_destroy(th_transport_t *t);
+
#endif /* TRANSPORTS_H */
diff --git a/tvhead.h b/tvhead.h
index a0f15a34..40dcaa45 100644
--- a/tvhead.h
+++ b/tvhead.h
@@ -146,6 +146,8 @@ typedef enum {
* DVB Mux instance
*/
typedef struct th_dvb_mux_instance {
+ int tdmi_refcnt;
+
LIST_ENTRY(th_dvb_mux_instance) tdmi_global_link;
LIST_ENTRY(th_dvb_mux_instance) tdmi_adapter_link;
@@ -179,8 +181,7 @@ typedef struct th_dvb_mux_instance {
uint16_t tdmi_transport_stream_id;
char *tdmi_identifier;
-
- const char *tdmi_network; /* Name of network, from NIT table */
+ char *tdmi_network; /* Name of network, from NIT table */
struct th_transport_list tdmi_transports; /* via tht_mux_link */
@@ -430,8 +431,6 @@ typedef struct th_transport {
struct th_muxer_list tht_muxers; /* muxers */
- struct pluginaux_list tht_plugin_aux;
-
/*
* Per source type structs
*/
@@ -469,11 +468,11 @@ typedef struct th_transport {
} file_input;
} u;
- const char *tht_identifier;
- const char *tht_servicename;
- const char *tht_channelname;
- const char *tht_provider;
- const char *tht_network;
+ char *tht_identifier;
+ char *tht_servicename;
+ char *tht_channelname;
+ char *tht_provider;
+
enum {
/* Service types defined in EN 300 468 */
diff --git a/v4l.c b/v4l.c
index 0650df92..09b83980 100644
--- a/v4l.c
+++ b/v4l.c
@@ -93,7 +93,6 @@ v4l_configure_transport(th_transport_t *t, const char *muxname,
(float)t->tht_v4l_frequency / 1000000.0f);
t->tht_name = strdup(buf);
- t->tht_network = strdup("Analog TV");
t->tht_provider = strdup("Analog TV");
snprintf(buf, sizeof(buf), "analog_%u", t->tht_v4l_frequency);
t->tht_identifier = strdup(buf);