stream status: add possibility to clear statistics, introduce tvh_input_instance_t
This commit is contained in:
parent
abb14095cb
commit
bda5d8ce25
11 changed files with 232 additions and 117 deletions
|
@ -37,8 +37,10 @@ api_status_inputs
|
|||
tvh_input_stream_t *st;
|
||||
tvh_input_stream_list_t stl = { 0 };
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
TVH_INPUT_FOREACH(ti)
|
||||
ti->ti_get_streams(ti, &stl);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
l = htsmsg_create_list();
|
||||
while ((st = LIST_FIRST(&stl))) {
|
||||
|
@ -67,11 +69,13 @@ api_status_subscriptions
|
|||
|
||||
l = htsmsg_create_list();
|
||||
c = 0;
|
||||
pthread_mutex_lock(&global_lock);
|
||||
LIST_FOREACH(ths, &subscriptions, ths_global_link) {
|
||||
e = subscription_create_msg(ths);
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
c++;
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
*resp = htsmsg_create_map();
|
||||
htsmsg_add_msg(*resp, "entries", l);
|
||||
|
@ -120,12 +124,48 @@ api_connections_cancel
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
input_clear_stats(const char *uuid)
|
||||
{
|
||||
tvh_input_instance_t *tii;
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
if ((tii = tvh_input_instance_find_by_uuid(uuid)) != NULL)
|
||||
if (tii->tii_clear_stats)
|
||||
tii->tii_clear_stats(tii);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
api_status_input_clear_stats
|
||||
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
|
||||
{
|
||||
htsmsg_field_t *f;
|
||||
htsmsg_t *ids;
|
||||
const char *uuid;
|
||||
|
||||
if (!(f = htsmsg_field_find(args, "uuid")))
|
||||
return EINVAL;
|
||||
if (!(ids = htsmsg_field_get_list(f))) {
|
||||
if ((uuid = htsmsg_field_get_str(f)) == NULL)
|
||||
return EINVAL;
|
||||
input_clear_stats(uuid);
|
||||
} else {
|
||||
HTSMSG_FOREACH(f, ids) {
|
||||
if ((uuid = htsmsg_field_get_str(f)) == NULL) continue;
|
||||
input_clear_stats(uuid);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void api_status_init ( void )
|
||||
{
|
||||
static api_hook_t ah[] = {
|
||||
{ "status/connections", ACCESS_ADMIN, api_status_connections, NULL },
|
||||
{ "status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL },
|
||||
{ "status/inputs", ACCESS_ADMIN, api_status_inputs, NULL },
|
||||
{ "status/inputclrstats", ACCESS_ADMIN, api_status_input_clear_stats, NULL },
|
||||
{ "connections/cancel", ACCESS_ADMIN, api_connections_cancel, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
|
25
src/input.c
25
src/input.c
|
@ -18,10 +18,18 @@
|
|||
|
||||
#include "input.h"
|
||||
#include "notify.h"
|
||||
#include "access.h"
|
||||
|
||||
tvh_input_list_t tvh_inputs;
|
||||
tvh_hardware_list_t tvh_hardware;
|
||||
|
||||
const idclass_t tvh_input_instance_class =
|
||||
{
|
||||
.ic_class = "tvh_input_instance",
|
||||
.ic_caption = "Input Instance",
|
||||
.ic_perm_def = ACCESS_ADMIN
|
||||
};
|
||||
|
||||
/*
|
||||
* Create entry
|
||||
*/
|
||||
|
@ -59,6 +67,23 @@ tvh_hardware_delete ( tvh_hardware_t *th )
|
|||
idnode_unlink(&th->th_id);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
tvh_input_instance_clear_stats ( tvh_input_instance_t *tii )
|
||||
{
|
||||
tvh_input_stream_stats_t *s = &tii->tii_stats;
|
||||
|
||||
atomic_exchange(&s->ber, 0);
|
||||
atomic_exchange(&s->unc, 0);
|
||||
atomic_exchange(&s->cc, 0);
|
||||
atomic_exchange(&s->te, 0);
|
||||
atomic_exchange(&s->ec_block, 0);
|
||||
atomic_exchange(&s->tc_block, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Input status handling
|
||||
*/
|
||||
|
|
22
src/input.h
22
src/input.h
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
typedef struct tvh_hardware tvh_hardware_t;
|
||||
typedef struct tvh_input tvh_input_t;
|
||||
typedef struct tvh_input_instance tvh_input_instance_t;
|
||||
typedef struct tvh_input_stream tvh_input_stream_t;
|
||||
typedef struct tvh_input_stream_stats tvh_input_stream_stats_t;
|
||||
|
||||
|
@ -87,6 +88,20 @@ struct tvh_input {
|
|||
void (*ti_get_streams) (struct tvh_input *, tvh_input_stream_list_t*);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic input instance super-class
|
||||
*/
|
||||
struct tvh_input_instance {
|
||||
idnode_t tii_id;
|
||||
|
||||
LIST_ENTRY(tvh_input_instance) tii_input_link;
|
||||
|
||||
tvh_input_stream_stats_t tii_stats;
|
||||
|
||||
void (*tii_delete) (tvh_input_instance_t *tii);
|
||||
void (*tii_clear_stats) (tvh_input_instance_t *tii);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic hardware super-class
|
||||
*/
|
||||
|
@ -103,6 +118,7 @@ void tvh_hardware_delete ( tvh_hardware_t *th );
|
|||
* Class and Global list defs
|
||||
*/
|
||||
extern const idclass_t tvh_input_class;
|
||||
extern const idclass_t tvh_input_instance_class;
|
||||
|
||||
tvh_input_list_t tvh_inputs;
|
||||
tvh_hardware_list_t tvh_hardware;
|
||||
|
@ -120,6 +136,12 @@ htsmsg_t * tvh_input_stream_create_msg ( tvh_input_stream_t *st );
|
|||
|
||||
void tvh_input_stream_destroy ( tvh_input_stream_t *st );
|
||||
|
||||
static inline tvh_input_instance_t *
|
||||
tvh_input_instance_find_by_uuid(const char *uuid)
|
||||
{ return (tvh_input_instance_t*)idnode_find(uuid, &tvh_input_instance_class, NULL); }
|
||||
|
||||
void tvh_input_instance_clear_stats ( tvh_input_instance_t *tii );
|
||||
|
||||
/*
|
||||
* Input subsystem includes
|
||||
*/
|
||||
|
|
|
@ -548,10 +548,9 @@ struct mpegts_service
|
|||
/* Physical mux instance */
|
||||
struct mpegts_mux_instance
|
||||
{
|
||||
idnode_t mmi_id;
|
||||
tvh_input_instance_t;
|
||||
|
||||
LIST_ENTRY(mpegts_mux_instance) mmi_mux_link;
|
||||
LIST_ENTRY(mpegts_mux_instance) mmi_input_link;
|
||||
LIST_ENTRY(mpegts_mux_instance) mmi_active_link;
|
||||
|
||||
streaming_pad_t mmi_streaming_pad;
|
||||
|
@ -559,11 +558,7 @@ struct mpegts_mux_instance
|
|||
mpegts_mux_t *mmi_mux;
|
||||
mpegts_input_t *mmi_input;
|
||||
|
||||
tvh_input_stream_stats_t mmi_stats;
|
||||
|
||||
int mmi_tune_failed;
|
||||
|
||||
void (*mmi_delete) (mpegts_mux_instance_t *mmi);
|
||||
};
|
||||
|
||||
struct mpegts_mux_sub
|
||||
|
@ -598,7 +593,7 @@ struct mpegts_input
|
|||
|
||||
mpegts_network_link_list_t mi_networks;
|
||||
|
||||
LIST_HEAD(,mpegts_mux_instance) mi_mux_instances;
|
||||
LIST_HEAD(,tvh_input_instance) mi_mux_instances;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -795,7 +790,7 @@ mpegts_service_t *mpegts_mux_find_service(mpegts_mux_t *ms, uint16_t sid);
|
|||
&type##_class, uuid,\
|
||||
mi, mm);
|
||||
|
||||
void mpegts_mux_instance_delete ( mpegts_mux_instance_t *mmi );
|
||||
void mpegts_mux_instance_delete ( tvh_input_instance_t *tii );
|
||||
|
||||
int mpegts_mux_instance_start
|
||||
( mpegts_mux_instance_t **mmiptr );
|
||||
|
|
|
@ -662,18 +662,18 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 1) && fe_properties[0].u.st.len > 0) {
|
||||
if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.signal = fe_properties[0].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.signal = fe_properties[0].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_DECIBEL;
|
||||
mmi->mmi_stats.signal = fe_properties[0].u.st.stat[0].svalue;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_DECIBEL;
|
||||
mmi->tii_stats.signal = fe_properties[0].u.st.stat[0].svalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 1);
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unhandled signal scale: %d",
|
||||
fe_properties[0].u.st.stat[0].scale);
|
||||
|
@ -682,12 +682,12 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(!gotprop && ioctl_check(lfe, 2)) {
|
||||
/* try old API */
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) {
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.signal = u16;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.signal = u16;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 2);
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide signal strength value.");
|
||||
}
|
||||
|
@ -697,7 +697,7 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 3) && fe_properties[1].u.st.len > 0) {
|
||||
if(fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||
mmi->mmi_stats.ec_bit = fe_properties[1].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.ec_bit = fe_properties[1].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -711,12 +711,12 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(gotprop && (fe_properties[2].u.st.len > 0)) {
|
||||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 4) && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||
mmi->mmi_stats.tc_bit = fe_properties[2].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.tc_bit = fe_properties[2].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 4);
|
||||
mmi->mmi_stats.ec_bit = 0; /* both values or none */
|
||||
mmi->tii_stats.ec_bit = 0; /* both values or none */
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unhandled TOTAL_BIT_COUNT scale: %d",
|
||||
fe_properties[2].u.st.stat[0].scale);
|
||||
|
@ -725,7 +725,7 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(!gotprop && ioctl_check(lfe, 5)) {
|
||||
/* try old API */
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
|
||||
mmi->mmi_stats.ber = u32;
|
||||
mmi->tii_stats.ber = u32;
|
||||
else {
|
||||
ioctl_bad(lfe, 5);
|
||||
if (logit)
|
||||
|
@ -737,18 +737,18 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 6) && fe_properties[3].u.st.len > 0) {
|
||||
if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.snr = fe_properties[3].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.snr = fe_properties[3].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_DECIBEL;
|
||||
mmi->mmi_stats.snr = fe_properties[3].u.st.stat[0].svalue;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_DECIBEL;
|
||||
mmi->tii_stats.snr = fe_properties[3].u.st.stat[0].svalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 6);
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unhandled SNR scale: %d",
|
||||
fe_properties[3].u.st.stat[0].scale);
|
||||
|
@ -757,12 +757,12 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(!gotprop && ioctl_check(lfe, 7)) {
|
||||
/* try old API */
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) {
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.snr = u16;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.snr = u16;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 7);
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide SNR value.");
|
||||
}
|
||||
|
@ -772,7 +772,7 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) {
|
||||
if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||
mmi->mmi_stats.unc = mmi->mmi_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.unc = mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -787,12 +787,12 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(gotprop && (fe_properties[5].u.st.len > 0)) {
|
||||
gotprop = 0;
|
||||
if(ioctl_check(lfe, 9) && fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||
mmi->mmi_stats.tc_block = fe_properties[5].u.st.stat[0].uvalue;
|
||||
mmi->tii_stats.tc_block = fe_properties[5].u.st.stat[0].uvalue;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 9);
|
||||
mmi->mmi_stats.ec_block = mmi->mmi_stats.unc = 0; /* both values or none */
|
||||
mmi->tii_stats.ec_block = mmi->tii_stats.unc = 0; /* both values or none */
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unhandled TOTAL_BLOCK_COUNT scale: %d",
|
||||
fe_properties[5].u.st.stat[0].scale);
|
||||
|
@ -801,7 +801,7 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
if(!gotprop && ioctl_check(lfe, 10)) {
|
||||
/* try old API */
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) {
|
||||
mmi->mmi_stats.unc = u32;
|
||||
mmi->tii_stats.unc = u32;
|
||||
gotprop = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -816,34 +816,34 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
{
|
||||
ioctl_bad(lfe, 0);
|
||||
if (ioctl_check(lfe, 1) && !ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) {
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.signal = u16;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.signal = u16;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 1);
|
||||
mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide signal strength value.");
|
||||
}
|
||||
if (ioctl_check(lfe, 2) && !ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
|
||||
mmi->mmi_stats.ber = u32;
|
||||
mmi->tii_stats.ber = u32;
|
||||
else {
|
||||
ioctl_bad(lfe, 2);
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide BER value.");
|
||||
}
|
||||
if (ioctl_check(lfe, 3) && !ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) {
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->mmi_stats.snr = u16;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
mmi->tii_stats.snr = u16;
|
||||
}
|
||||
else {
|
||||
ioctl_bad(lfe, 3);
|
||||
mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
|
||||
if (logit)
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "Unable to provide SNR value.");
|
||||
}
|
||||
if (ioctl_check(lfe, 4) && !ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32))
|
||||
mmi->mmi_stats.unc = u32;
|
||||
mmi->tii_stats.unc = u32;
|
||||
else {
|
||||
ioctl_bad(lfe, 4);
|
||||
if (logit)
|
||||
|
@ -853,16 +853,16 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
|
||||
/* Send message */
|
||||
sigstat.status_text = signal2str(status);
|
||||
sigstat.snr = mmi->mmi_stats.snr;
|
||||
sigstat.signal = mmi->mmi_stats.signal;
|
||||
sigstat.ber = mmi->mmi_stats.ber;
|
||||
sigstat.unc = mmi->mmi_stats.unc;
|
||||
sigstat.signal_scale = mmi->mmi_stats.signal_scale;
|
||||
sigstat.snr_scale = mmi->mmi_stats.snr_scale;
|
||||
sigstat.ec_bit = mmi->mmi_stats.ec_bit;
|
||||
sigstat.tc_bit = mmi->mmi_stats.tc_bit;
|
||||
sigstat.ec_block = mmi->mmi_stats.ec_block;
|
||||
sigstat.tc_block = mmi->mmi_stats.tc_block;
|
||||
sigstat.snr = mmi->tii_stats.snr;
|
||||
sigstat.signal = mmi->tii_stats.signal;
|
||||
sigstat.ber = mmi->tii_stats.ber;
|
||||
sigstat.unc = mmi->tii_stats.unc;
|
||||
sigstat.signal_scale = mmi->tii_stats.signal_scale;
|
||||
sigstat.snr_scale = mmi->tii_stats.snr_scale;
|
||||
sigstat.ec_bit = mmi->tii_stats.ec_bit;
|
||||
sigstat.tc_bit = mmi->tii_stats.tc_bit;
|
||||
sigstat.ec_block = mmi->tii_stats.ec_block;
|
||||
sigstat.tc_block = mmi->tii_stats.tc_block;
|
||||
sm.sm_type = SMT_SIGNAL_STATUS;
|
||||
sm.sm_data = &sigstat;
|
||||
LIST_FOREACH(s, &lfe->mi_transports, s_active_link) {
|
||||
|
|
|
@ -673,10 +673,10 @@ mpegts_input_create_mux_instance
|
|||
( mpegts_input_t *mi, mpegts_mux_t *mm )
|
||||
{
|
||||
extern const idclass_t mpegts_mux_instance_class;
|
||||
mpegts_mux_instance_t *mmi;
|
||||
LIST_FOREACH(mmi, &mi->mi_mux_instances, mmi_input_link)
|
||||
if (mmi->mmi_mux == mm) break;
|
||||
if (!mmi)
|
||||
tvh_input_instance_t *tii;
|
||||
LIST_FOREACH(tii, &mi->mi_mux_instances, tii_input_link)
|
||||
if (((mpegts_mux_instance_t *)tii)->mmi_mux == mm) break;
|
||||
if (!tii)
|
||||
(void)mpegts_mux_instance_create(mpegts_mux_instance, NULL, mi, mm);
|
||||
}
|
||||
|
||||
|
@ -871,7 +871,7 @@ mpegts_input_recv_packets
|
|||
/* Check for sync */
|
||||
while ( (len >= MIN_TS_SYN) &&
|
||||
((len2 = ts_sync_count(tsb, len)) < MIN_TS_SYN) ) {
|
||||
mmi->mmi_stats.unc++;
|
||||
mmi->tii_stats.unc++;
|
||||
--len;
|
||||
++tsb;
|
||||
++off;
|
||||
|
@ -1079,7 +1079,7 @@ mpegts_input_process
|
|||
/* Transport error */
|
||||
if (pid & 0x8000) {
|
||||
if ((pid & 0x1FFF) != 0x1FFF)
|
||||
++mmi->mmi_stats.te;
|
||||
++mmi->tii_stats.te;
|
||||
}
|
||||
|
||||
pid &= 0x1FFF;
|
||||
|
@ -1102,7 +1102,7 @@ mpegts_input_process
|
|||
cc = tsb2[3] & 0x0f;
|
||||
if (cc2 != 0xff && cc2 != cc) {
|
||||
tvhtrace("mpegts", "pid %04X cc err %2d != %2d", pid, cc, cc2);
|
||||
++mmi->mmi_stats.cc;
|
||||
++mmi->tii_stats.cc;
|
||||
}
|
||||
cc2 = (cc + 1) & 0xF;
|
||||
}
|
||||
|
@ -1214,7 +1214,7 @@ done:
|
|||
pthread_cond_signal(&mi->mi_table_cond);
|
||||
|
||||
/* Bandwidth monitoring */
|
||||
atomic_add(&mmi->mmi_stats.bps, tsb - mpkt->mp_data);
|
||||
atomic_add(&mmi->tii_stats.bps, tsb - mpkt->mp_data);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -1352,15 +1352,15 @@ mpegts_input_stream_status
|
|||
w = MAX(w, ths->ths_weight);
|
||||
}
|
||||
|
||||
st->uuid = strdup(idnode_uuid_as_str(&mmi->mmi_id));
|
||||
st->uuid = strdup(idnode_uuid_as_str(&mmi->tii_id));
|
||||
mi->mi_display_name(mi, buf, sizeof(buf));
|
||||
st->input_name = strdup(buf);
|
||||
mpegts_mux_nice_name(mm, buf, sizeof(buf));
|
||||
st->stream_name = strdup(buf);
|
||||
st->subs_count = s;
|
||||
st->max_weight = w;
|
||||
st->stats = mmi->mmi_stats;
|
||||
st->stats.bps = atomic_exchange(&mmi->mmi_stats.bps, 0) * 8;
|
||||
st->stats = mmi->tii_stats;
|
||||
st->stats.bps = atomic_exchange(&mmi->tii_stats.bps, 0) * 8;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1524,19 +1524,19 @@ void
|
|||
mpegts_input_delete ( mpegts_input_t *mi, int delconf )
|
||||
{
|
||||
mpegts_network_link_t *mnl;
|
||||
mpegts_mux_instance_t *mmi, *mmi_next;
|
||||
tvh_input_instance_t *tii, *tii_next;
|
||||
|
||||
/* Remove networks */
|
||||
while ((mnl = LIST_FIRST(&mi->mi_networks)))
|
||||
mpegts_input_del_network(mnl);
|
||||
|
||||
/* Remove mux instances assigned to this input */
|
||||
mmi = LIST_FIRST(&mi->mi_mux_instances);
|
||||
while (mmi) {
|
||||
mmi_next = LIST_NEXT(mmi, mmi_input_link);
|
||||
if (mmi->mmi_input == mi)
|
||||
mmi->mmi_delete(mmi);
|
||||
mmi = mmi_next;
|
||||
tii = LIST_FIRST(&mi->mi_mux_instances);
|
||||
while (tii) {
|
||||
tii_next = LIST_NEXT(tii, tii_input_link);
|
||||
if (((mpegts_mux_instance_t *)tii)->mmi_input == mi)
|
||||
tii->tii_delete(tii);
|
||||
tii = tii_next;
|
||||
}
|
||||
|
||||
/* Remove global refs */
|
||||
|
|
|
@ -37,6 +37,7 @@ static void mpegts_mux_scan_timeout ( void *p );
|
|||
|
||||
const idclass_t mpegts_mux_instance_class =
|
||||
{
|
||||
.ic_super = &tvh_input_instance_class,
|
||||
.ic_class = "mpegts_mux_instance",
|
||||
.ic_caption = "MPEGTS Multiplex Phy",
|
||||
.ic_perm_def = ACCESS_ADMIN
|
||||
|
@ -44,11 +45,13 @@ const idclass_t mpegts_mux_instance_class =
|
|||
|
||||
void
|
||||
mpegts_mux_instance_delete
|
||||
( mpegts_mux_instance_t *mmi )
|
||||
( tvh_input_instance_t *tii )
|
||||
{
|
||||
idnode_unlink(&mmi->mmi_id);
|
||||
mpegts_mux_instance_t *mmi = (mpegts_mux_instance_t *)tii;
|
||||
|
||||
idnode_unlink(&tii->tii_id);
|
||||
LIST_REMOVE(mmi, mmi_mux_link);
|
||||
LIST_REMOVE(mmi, mmi_input_link);
|
||||
LIST_REMOVE(tii, tii_input_link);
|
||||
free(mmi);
|
||||
}
|
||||
|
||||
|
@ -58,7 +61,7 @@ mpegts_mux_instance_create0
|
|||
mpegts_input_t *mi, mpegts_mux_t *mm )
|
||||
{
|
||||
// TODO: does this need to be an idnode?
|
||||
if (idnode_insert(&mmi->mmi_id, uuid, class, 0)) {
|
||||
if (idnode_insert(&mmi->tii_id, uuid, class, 0)) {
|
||||
free(mmi);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -68,10 +71,11 @@ mpegts_mux_instance_create0
|
|||
mmi->mmi_input = mi;
|
||||
|
||||
/* Callbacks */
|
||||
mmi->mmi_delete = mpegts_mux_instance_delete;
|
||||
mmi->tii_delete = mpegts_mux_instance_delete;
|
||||
mmi->tii_clear_stats = tvh_input_instance_clear_stats;
|
||||
|
||||
LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link);
|
||||
LIST_INSERT_HEAD(&mi->mi_mux_instances, mmi, mmi_input_link);
|
||||
LIST_INSERT_HEAD(&mi->mi_mux_instances, (tvh_input_instance_t *)mmi, tii_input_link);
|
||||
|
||||
|
||||
return mmi;
|
||||
|
@ -621,7 +625,7 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf )
|
|||
|
||||
/* Remove instances */
|
||||
while ((mmi = LIST_FIRST(&mm->mm_instances))) {
|
||||
mmi->mmi_delete(mmi);
|
||||
mmi->tii_delete((tvh_input_instance_t *)mmi);
|
||||
}
|
||||
|
||||
/* Remove raw subscribers */
|
||||
|
|
|
@ -76,16 +76,16 @@ satip_frontend_signal_cb( void *aux )
|
|||
lfe->sf_tables = 1;
|
||||
}
|
||||
sigstat.status_text = signal2str(lfe->sf_status);
|
||||
sigstat.snr = mmi->mmi_stats.snr;
|
||||
sigstat.signal = mmi->mmi_stats.signal;
|
||||
sigstat.ber = mmi->mmi_stats.ber;
|
||||
sigstat.unc = mmi->mmi_stats.unc;
|
||||
sigstat.signal_scale = mmi->mmi_stats.signal_scale;
|
||||
sigstat.snr_scale = mmi->mmi_stats.snr_scale;
|
||||
sigstat.ec_bit = mmi->mmi_stats.ec_bit;
|
||||
sigstat.tc_bit = mmi->mmi_stats.tc_bit;
|
||||
sigstat.ec_block = mmi->mmi_stats.ec_block;
|
||||
sigstat.tc_block = mmi->mmi_stats.tc_block;
|
||||
sigstat.snr = mmi->tii_stats.snr;
|
||||
sigstat.signal = mmi->tii_stats.signal;
|
||||
sigstat.ber = mmi->tii_stats.ber;
|
||||
sigstat.unc = mmi->tii_stats.unc;
|
||||
sigstat.signal_scale = mmi->tii_stats.signal_scale;
|
||||
sigstat.snr_scale = mmi->tii_stats.snr_scale;
|
||||
sigstat.ec_bit = mmi->tii_stats.ec_bit;
|
||||
sigstat.tc_bit = mmi->tii_stats.tc_bit;
|
||||
sigstat.ec_block = mmi->tii_stats.ec_block;
|
||||
sigstat.tc_block = mmi->tii_stats.tc_block;
|
||||
sm.sm_type = SMT_SIGNAL_STATUS;
|
||||
sm.sm_data = &sigstat;
|
||||
LIST_FOREACH(svc, &lfe->mi_transports, s_active_link) {
|
||||
|
@ -722,20 +722,20 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name,
|
|||
return;
|
||||
if (atoi(argv[0]) != lfe->sf_number)
|
||||
return;
|
||||
mmi->mmi_stats.signal =
|
||||
mmi->tii_stats.signal =
|
||||
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
|
||||
mmi->mmi_stats.signal_scale =
|
||||
mmi->tii_stats.signal_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
if (atoi(argv[2]) > 0)
|
||||
status = SIGNAL_GOOD;
|
||||
mmi->mmi_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->mmi_stats.snr_scale =
|
||||
mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->tii_stats.snr_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
if (status == SIGNAL_GOOD &&
|
||||
mmi->mmi_stats.signal == 0 && mmi->mmi_stats.snr == 0) {
|
||||
mmi->tii_stats.signal == 0 && mmi->tii_stats.snr == 0) {
|
||||
/* some values that we're tuned */
|
||||
mmi->mmi_stats.signal = 50 * 0xffff / 100;
|
||||
mmi->mmi_stats.snr = 12 * 0xffff / 15;
|
||||
mmi->tii_stats.signal = 50 * 0xffff / 100;
|
||||
mmi->tii_stats.snr = 12 * 0xffff / 15;
|
||||
}
|
||||
goto ok;
|
||||
} else if (strncmp(s, "ver=1.0;", 8) == 0) {
|
||||
|
@ -747,14 +747,14 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name,
|
|||
return;
|
||||
if (atoi(argv[0]) != lfe->sf_number)
|
||||
return;
|
||||
mmi->mmi_stats.signal =
|
||||
mmi->tii_stats.signal =
|
||||
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
|
||||
mmi->mmi_stats.signal_scale =
|
||||
mmi->tii_stats.signal_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
if (atoi(argv[2]) > 0)
|
||||
status = SIGNAL_GOOD;
|
||||
mmi->mmi_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->mmi_stats.snr_scale =
|
||||
mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->tii_stats.snr_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
goto ok;
|
||||
} else if (strncmp(s, "ver=1.1;tuner=", 14) == 0) {
|
||||
|
@ -763,14 +763,14 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name,
|
|||
return;
|
||||
if (atoi(argv[0]) != lfe->sf_number)
|
||||
return;
|
||||
mmi->mmi_stats.signal =
|
||||
mmi->tii_stats.signal =
|
||||
atoi(argv[1]) * 0xffff / lfe->sf_device->sd_sig_scale;
|
||||
mmi->mmi_stats.signal_scale =
|
||||
mmi->tii_stats.signal_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
if (atoi(argv[2]) > 0)
|
||||
status = SIGNAL_GOOD;
|
||||
mmi->mmi_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->mmi_stats.snr_scale =
|
||||
mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15;
|
||||
mmi->tii_stats.snr_scale =
|
||||
SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
goto ok;
|
||||
}
|
||||
|
@ -782,9 +782,9 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name,
|
|||
return;
|
||||
|
||||
ok:
|
||||
if (mmi->mmi_stats.snr < 2 && status == SIGNAL_GOOD)
|
||||
if (mmi->tii_stats.snr < 2 && status == SIGNAL_GOOD)
|
||||
status = SIGNAL_BAD;
|
||||
else if (mmi->mmi_stats.snr < 4 && status == SIGNAL_GOOD)
|
||||
else if (mmi->tii_stats.snr < 4 && status == SIGNAL_GOOD)
|
||||
status = SIGNAL_FAINT;
|
||||
lfe->sf_status = status;
|
||||
}
|
||||
|
@ -1503,7 +1503,7 @@ new_tune:
|
|||
}
|
||||
pthread_mutex_lock(&lfe->sf_dvr_lock);
|
||||
if (lfe->sf_req == lfe->sf_req_thread) {
|
||||
mmi->mmi_stats.unc += unc;
|
||||
mmi->tii_stats.unc += unc;
|
||||
mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi,
|
||||
&sb, NULL, NULL);
|
||||
} else
|
||||
|
|
|
@ -23,12 +23,12 @@ extern const idclass_t mpegts_mux_class;
|
|||
extern const idclass_t mpegts_mux_instance_class;
|
||||
|
||||
static void
|
||||
tsfile_mux_instance_delete( mpegts_mux_instance_t *_mmi )
|
||||
tsfile_mux_instance_delete( tvh_input_instance_t *tii )
|
||||
{
|
||||
tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t *)_mmi;
|
||||
tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t *)tii;
|
||||
|
||||
free(mmi->mmi_tsfile_path);
|
||||
mpegts_mux_instance_delete(_mmi);
|
||||
mpegts_mux_instance_delete(tii);
|
||||
}
|
||||
|
||||
tsfile_mux_instance_t *
|
||||
|
@ -41,7 +41,7 @@ tsfile_mux_instance_create
|
|||
#undef tsfile_mux_instance_class
|
||||
mmi->mmi_tsfile_path = strdup(path);
|
||||
mmi->mmi_tsfile_pcr_pid = MPEGTS_PID_NONE;
|
||||
mmi->mmi_delete = tsfile_mux_instance_delete;
|
||||
mmi->tii_delete = tsfile_mux_instance_delete;
|
||||
tvhtrace("tsfile", "mmi created %p path %s", mmi, mmi->mmi_tsfile_path);
|
||||
return mmi;
|
||||
}
|
||||
|
|
|
@ -300,19 +300,19 @@ tvhdhomerun_frontend_monitor_cb( void *aux )
|
|||
|
||||
if(tuner_status.signal_present) {
|
||||
/* TODO: totaly stupid conversion from 0-100 scale to 0-655.35 */
|
||||
mmi->mmi_stats.snr = tuner_status.signal_to_noise_quality * 655.35;
|
||||
mmi->mmi_stats.signal = tuner_status.signal_strength * 655.35;
|
||||
mmi->tii_stats.snr = tuner_status.signal_to_noise_quality * 655.35;
|
||||
mmi->tii_stats.signal = tuner_status.signal_strength * 655.35;
|
||||
} else {
|
||||
mmi->mmi_stats.snr = 0;
|
||||
mmi->tii_stats.snr = 0;
|
||||
}
|
||||
|
||||
sigstat.status_text = signal2str(hfe->hf_status);
|
||||
sigstat.snr = mmi->mmi_stats.snr;
|
||||
sigstat.snr_scale = mmi->mmi_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
sigstat.signal = mmi->mmi_stats.signal;
|
||||
sigstat.signal_scale = mmi->mmi_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
sigstat.ber = mmi->mmi_stats.ber;
|
||||
sigstat.unc = mmi->mmi_stats.unc;
|
||||
sigstat.snr = mmi->tii_stats.snr;
|
||||
sigstat.snr_scale = mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
sigstat.signal = mmi->tii_stats.signal;
|
||||
sigstat.signal_scale = mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
|
||||
sigstat.ber = mmi->tii_stats.ber;
|
||||
sigstat.unc = mmi->tii_stats.unc;
|
||||
sm.sm_type = SMT_SIGNAL_STATUS;
|
||||
sm.sm_data = &sigstat;
|
||||
|
||||
|
|
|
@ -231,6 +231,33 @@ tvheadend.status_streams = function(panel, index)
|
|||
if (grid)
|
||||
return;
|
||||
|
||||
var actions = new Ext.ux.grid.RowActions({
|
||||
header: '',
|
||||
width: 10,
|
||||
actions: [
|
||||
{
|
||||
iconCls: 'undo',
|
||||
qtip: 'Clear statistics',
|
||||
cb: function(grid, rec, act, row) {
|
||||
var uuid = grid.getStore().getAt(row).data.uuid;
|
||||
Ext.MessageBox.confirm('Clear statistics',
|
||||
'Clear statistics for selected input?',
|
||||
function(button) {
|
||||
if (button === 'no')
|
||||
return;
|
||||
Ext.Ajax.request({
|
||||
url: 'api/status/inputclrstats',
|
||||
params: { uuid: uuid }
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
],
|
||||
destroy: function() {
|
||||
}
|
||||
});
|
||||
|
||||
store = new Ext.data.JsonStore({
|
||||
root: 'entries',
|
||||
totalProperty: 'totalCount',
|
||||
|
@ -288,6 +315,7 @@ tvheadend.status_streams = function(panel, index)
|
|||
}
|
||||
|
||||
var cm = new Ext.grid.ColumnModel([
|
||||
actions,
|
||||
{
|
||||
width: 120,
|
||||
header: "Input",
|
||||
|
@ -402,7 +430,8 @@ tvheadend.status_streams = function(panel, index)
|
|||
flex: 1,
|
||||
viewConfig: {
|
||||
forceFit: true
|
||||
}
|
||||
},
|
||||
plugins: [actions]
|
||||
});
|
||||
|
||||
dpanel.add(grid);
|
||||
|
|
Loading…
Add table
Reference in a new issue