From d1495e2e1864d7445fe580ab01028cf3e8e32a57 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sat, 9 Oct 2010 10:11:21 +0200 Subject: [PATCH] add signal status in HTSP --- src/dvb/dvb.h | 6 ++++++ src/dvb/dvb_adapter.c | 13 +++++++++++++ src/dvb/dvb_fe.c | 26 +++++++++++++++++++++++++- src/dvb/dvb_transport.c | 28 ++++++++++++++++++++++++++++ src/htsp.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/transports.c | 25 +++++++++++++++++++++++++ src/transports.h | 3 +++ src/tvhead.h | 14 ++++++++++++++ 8 files changed, 154 insertions(+), 2 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 9f155fe..240722d 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -200,6 +200,10 @@ typedef struct th_dvb_adapter { int tda_allpids_dmx_fd; int tda_dump_fd; + + pthread_mutex_t sig_status_update_mutex; + signal_status_t *sig_status; /* current signal status */ + } th_dvb_adapter_t; @@ -307,6 +311,8 @@ void dvb_transport_notify_by_adapter(th_dvb_adapter_t *tda); htsmsg_t *dvb_transport_build_msg(th_transport_t *t); +void dvb_transport_get_signal_status(th_transport_t *current_transport, + signal_status_t *status); /** * DVB Frontend diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 6f909bf..5f9605a 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -64,6 +64,19 @@ tda_alloc(void) tda->tda_allpids_dmx_fd = -1; tda->tda_dump_fd = -1; + /* current signal status */ + tda->sig_status = malloc(sizeof(signal_status_t)); + + tda->sig_status->snr = -2; + tda->sig_status->signal = -2; + tda->sig_status->ber = -2; + tda->sig_status->unc = -2; + tda->sig_status->status = -2; + tda->sig_status->status_text = NULL; + tda->sig_status->name = NULL; + + pthread_mutex_init(&tda->sig_status_update_mutex, NULL); + return tda; } diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index c68876e..eeda9cb 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -51,7 +51,7 @@ dvb_fe_monitor(void *aux) { th_dvb_adapter_t *tda = aux; fe_status_t fe_status; - int status, v, update = 0, vv, i, fec, q; + int status, v, update = 0, vv, i, fec, q, ber, signal, snr; th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; char buf[50]; @@ -112,6 +112,18 @@ dvb_fe_monitor(void *aux) } else { status = TDMI_FE_CONSTANT_FEC; } + + /* bit error rate */ + if (ioctl(tda->tda_fe_fd, FE_READ_BER, &ber) == -1) + ber = -2; + + /* signal strength */ + if (ioctl(tda->tda_fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1) + signal = -2; + + /* signal/noise ratio */ + if (ioctl(tda->tda_fe_fd, FE_READ_SNR, &snr) == -1) + snr = -2; } if(status != tdmi->tdmi_fe_status) { @@ -137,6 +149,18 @@ dvb_fe_monitor(void *aux) } } + /* update transport status */ + pthread_mutex_lock(&tda->sig_status_update_mutex); + + tda->sig_status->ber = ber; + tda->sig_status->signal = signal; + tda->sig_status->snr = snr; + tda->sig_status->status = fe_status; + tda->sig_status->unc = fec; + tvh_str_update(&tda->sig_status->status_text, dvb_mux_status(tdmi)); + + pthread_mutex_unlock(&tda->sig_status_update_mutex); + if(update) { htsmsg_t *m = htsmsg_create_map(); diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index 48650d8..e6d7e4d 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -460,3 +460,31 @@ dvb_transport_notify(th_transport_t *t) htsmsg_add_str(m, "adapterId", tdmi->tdmi_adapter->tda_identifier); notify_by_msg("dvbService", m); } + + +/** + * Get the signal status from a DVB transport + */ +void +dvb_transport_get_signal_status(th_transport_t *current_transport, + signal_status_t *status) +{ + if (current_transport && current_transport->tht_dvb_mux_instance && + current_transport->tht_dvb_mux_instance->tdmi_adapter) + { + th_dvb_adapter_t *tda = + current_transport->tht_dvb_mux_instance->tdmi_adapter; + + pthread_mutex_lock(&tda->sig_status_update_mutex); + + status->ber = tda->sig_status->ber; + status->signal = tda->sig_status->signal; + status->snr = tda->sig_status->snr; + status->status = tda->sig_status->status; + status->unc = tda->sig_status->unc; + status->status_text = strdup(tda->sig_status->status_text); + status->name = strdup(tda->tda_displayname); + + pthread_mutex_unlock(&tda->sig_status_update_mutex); + } +} diff --git a/src/htsp.c b/src/htsp.c index 55a94e0..55af13d 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -166,6 +166,8 @@ typedef struct htsp_subscription { } htsp_subscription_t; +static void htsp_get_signal_status(htsp_subscription_t *hs, signal_status_t *status); + /** * @@ -1387,6 +1389,7 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_connection_t *htsp = hs->hs_htsp; int64_t ts; int qlen = hs->hs_q.hmq_payload; + signal_status_t *status = malloc(sizeof(signal_status_t)); if((qlen > 500000 && pkt->pkt_frametype == PKT_B_FRAME) || (qlen > 750000 && pkt->pkt_frametype == PKT_P_FRAME) || @@ -1431,7 +1434,9 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_send(htsp, m, pkt->pkt_payload, &hs->hs_q, pktbuf_len(pkt->pkt_payload)); if(hs->hs_last_report != dispatch_clock) { - /* Send a queue status report every second */ + /* Send a queue and signal status report every second */ + + htsp_get_signal_status(hs, status); hs->hs_last_report = dispatch_clock; @@ -1460,6 +1465,18 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsmsg_add_u32(m, "Pdrops", hs->hs_dropstats[PKT_P_FRAME]); htsmsg_add_u32(m, "Idrops", hs->hs_dropstats[PKT_I_FRAME]); + /* add the signal status */ + if (status->status_text != NULL) + htsmsg_add_str(m, "feStatus", status->status_text); + htsmsg_add_u32(m, "feSNR", status->snr); + htsmsg_add_u32(m, "feSignal", status->signal); + htsmsg_add_u32(m, "feBER", status->ber); + htsmsg_add_u32(m, "feUNC", status->unc); + + /* add the tuner name */ + if (status->name != NULL) + htsmsg_add_str(m, "feName", status->name); + /* We use a special queue for queue status message so they're not blocked by anything else */ @@ -1611,3 +1628,25 @@ htsp_streaming_input(void *opaque, streaming_message_t *sm) } streaming_msg_free(sm); } + + +/** + * Adds the signal status of the adapter used by a subscription + */ +static void +htsp_get_signal_status(htsp_subscription_t *hs, signal_status_t *status) +{ + status->status_text = NULL; + status->name = NULL; + status->status = 0; + status->snr = -2; + status->signal = -2; + status->ber = -2; + status->unc = -2; + + // get signal status from the current transport + if (hs->hs_s && hs->hs_s->ths_transport) + { + return get_signal_status_from_transport(hs->hs_s->ths_transport, status); + } +} diff --git a/src/transports.c b/src/transports.c index 801e30a..7cfd6dd 100644 --- a/src/transports.c +++ b/src/transports.c @@ -1050,3 +1050,28 @@ get_encryption_from_transport(th_transport_t *t) return 0; } + + +/** + * Get the signal status from a transport + */ +void +get_signal_status_from_transport(th_transport_t *current_transport, + signal_status_t *status) +{ + if (current_transport) + { + // get signal status from the transport + switch (current_transport->tht_type) + { + case TRANSPORT_DVB: + dvb_transport_get_signal_status(current_transport, status); + case TRANSPORT_V4L: + //TODO add signal status from a V4L adapter + break; + case TRANSPORT_IPTV: + //TODO add signal status from an IPTV adapter + break; + } + } +} diff --git a/src/transports.h b/src/transports.h index 21caa61..acbdfe9 100644 --- a/src/transports.h +++ b/src/transports.h @@ -100,4 +100,7 @@ int tss2errcode(int tss); uint16_t get_encryption_from_transport(th_transport_t *t); +void get_signal_status_from_transport(th_transport_t *current_transport, + signal_status_t *status); + #endif /* TRANSPORTS_H */ diff --git a/src/tvhead.h b/src/tvhead.h index 3b4737e..660ca28 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -166,6 +166,20 @@ typedef enum { #define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264) #define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \ (t) == SCT_AAC) + +/** + * The signal status of a tuner + */ +typedef struct signal_status { + char *name; /* adapter name */ + char *status_text; /* adapter status text */ + int status; /* adapter status code */ + uint16_t snr; /* signal/noise ratio */ + uint16_t signal; /* signal strength */ + uint32_t ber; /* bit error rate */ + uint32_t unc; /* uncorrected blocks */ +} signal_status_t; + /** * A streaming pad generates data. * It has one or more streaming targets attached to it. -- 1.7.0.4