status: added back in basic status info
It will now show subscriptions and streams (tuners/muxes combined).
This commit is contained in:
parent
f16c29559e
commit
8ac1b3d7ed
14 changed files with 314 additions and 84 deletions
2
Makefile
2
Makefile
|
@ -109,10 +109,12 @@ SRCS = src/version.c \
|
|||
src/tvhtime.c \
|
||||
src/descrambler/descrambler.c \
|
||||
src/service_mapper.c \
|
||||
src/input.c \
|
||||
|
||||
SRCS += \
|
||||
src/api.c \
|
||||
src/api/api_idnode.c \
|
||||
src/api/api_input.c \
|
||||
src/api/api_channel.c \
|
||||
src/api/api_service.c \
|
||||
src/api/api_mpegts.c \
|
||||
|
|
|
@ -116,6 +116,7 @@ void api_init ( void )
|
|||
|
||||
/* Subsystems */
|
||||
api_idnode_init();
|
||||
api_input_init();
|
||||
api_mpegts_init();
|
||||
api_service_init();
|
||||
api_channel_init();
|
||||
|
|
|
@ -57,9 +57,10 @@ int api_exec ( const char *subsystem, htsmsg_t *args, htsmsg_t **resp );
|
|||
*/
|
||||
void api_init ( void );
|
||||
void api_idnode_init ( void );
|
||||
void api_mpegts_init ( void );
|
||||
void api_input_init ( void );
|
||||
void api_service_init ( void );
|
||||
void api_channel_init ( void );
|
||||
void api_mpegts_init ( void );
|
||||
|
||||
/*
|
||||
* IDnode
|
||||
|
|
71
src/api/api_input.c
Normal file
71
src/api/api_input.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* API - channel related calls
|
||||
*
|
||||
* Copyright (C) 2013 Adam Sutton
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __TVH_API_INPUT_H__
|
||||
#define __TVH_API_INPUT_H__
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "idnode.h"
|
||||
#include "input.h"
|
||||
#include "access.h"
|
||||
#include "api.h"
|
||||
|
||||
static int
|
||||
api_input_status
|
||||
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
|
||||
{
|
||||
int c = 0;
|
||||
htsmsg_t *l, *e;
|
||||
tvh_input_t *ti;
|
||||
tvh_input_stream_t *st;
|
||||
tvh_input_stream_list_t stl = { 0 };
|
||||
|
||||
TVH_INPUT_FOREACH(ti)
|
||||
ti->ti_get_streams(ti, &stl);
|
||||
|
||||
l = htsmsg_create_list();
|
||||
while ((st = LIST_FIRST(&stl))) {
|
||||
e = tvh_input_stream_create_msg(st);
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
tvh_input_stream_destroy(st);
|
||||
LIST_REMOVE(st, link);
|
||||
free(st);
|
||||
c++;
|
||||
}
|
||||
|
||||
*resp = htsmsg_create_map();
|
||||
htsmsg_add_msg(*resp, "entries", l);
|
||||
htsmsg_add_u32(*resp, "totalCount", c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void api_input_init ( void )
|
||||
{
|
||||
static api_hook_t ah[] = {
|
||||
{ "input/status", ACCESS_ANONYMOUS, api_input_status, NULL },
|
||||
// { "input/tree", ACCESS_ANONYMOUS, NULL, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
api_register_all(ah);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __TVH_API_INPUT_H__ */
|
|
@ -654,7 +654,7 @@ capmt_table_input(struct th_descrambler *td, struct service *s,
|
|||
return;
|
||||
if (!t->s_dvb_active_input) return;
|
||||
lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input;
|
||||
if (!idnode_is_instance(&lfe->mi_id, &linuxdvb_frontend_class))
|
||||
if (!idnode_is_instance(&lfe->ti_id, &linuxdvb_frontend_class))
|
||||
return;
|
||||
adapter_num = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_number;
|
||||
|
||||
|
@ -893,7 +893,7 @@ capmt_service_start(service_t *s)
|
|||
return;
|
||||
if (!t->s_dvb_active_input) return;
|
||||
lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input;
|
||||
if (!idnode_is_instance(&lfe->mi_id, &linuxdvb_frontend_class))
|
||||
if (!idnode_is_instance(&lfe->ti_id, &linuxdvb_frontend_class))
|
||||
return;
|
||||
tuner = ((linuxdvb_adapter_t*)lfe->lh_parent)->la_number;
|
||||
|
||||
|
|
57
src/input.h
57
src/input.h
|
@ -19,6 +19,61 @@
|
|||
#ifndef __TVH_INPUT_H__
|
||||
#define __TVH_INPUT_H__
|
||||
|
||||
#include "idnode.h"
|
||||
#include "queue.h"
|
||||
|
||||
/*
|
||||
* Input stream structure - used for getting statistics about active streams
|
||||
*/
|
||||
typedef struct tvh_input_stream_stats
|
||||
{
|
||||
int signal; ///< Signal level (0-100)
|
||||
int ber; ///< Bit error rate (0-100?)
|
||||
int unc; ///< Uncorrectable errors
|
||||
int snr; ///< Signal 2 Noise (dB)
|
||||
int bps; ///< Bandwidth (bps)
|
||||
} tvh_input_stream_stats_t;
|
||||
|
||||
typedef struct tvh_input_stream {
|
||||
|
||||
LIST_ENTRY(tvh_input_stream) link;
|
||||
|
||||
char *uuid; ///< Unique ID of the entry (used for updates)
|
||||
char *input_name; ///< Name of the parent input
|
||||
char *stream_name; ///< Name for this stream
|
||||
int subs_count; ///< Number of subcscriptions
|
||||
int max_weight; ///< Current max weight
|
||||
|
||||
tvh_input_stream_stats_t stats;
|
||||
|
||||
} tvh_input_stream_t;
|
||||
|
||||
typedef LIST_HEAD(,tvh_input_stream) tvh_input_stream_list_t;
|
||||
|
||||
/*
|
||||
* Generic input super-class
|
||||
*/
|
||||
typedef struct tvh_input {
|
||||
idnode_t ti_id;
|
||||
|
||||
LIST_ENTRY(tvh_input) ti_link;
|
||||
|
||||
void (*ti_get_streams) (struct tvh_input *, tvh_input_stream_list_t*);
|
||||
|
||||
} tvh_input_t;
|
||||
|
||||
typedef LIST_HEAD(,tvh_input) tvh_input_list_t;
|
||||
tvh_input_list_t tvh_inputs;
|
||||
|
||||
#define TVH_INPUT_FOREACH(x) LIST_FOREACH(x, &tvh_inputs, ti_link)
|
||||
|
||||
void input_init ( void );
|
||||
|
||||
htsmsg_t * tvh_input_stream_create_msg ( tvh_input_stream_t *st );
|
||||
|
||||
void tvh_input_stream_destroy ( tvh_input_stream_t *st );
|
||||
|
||||
|
||||
#if ENABLE_MPEGPS
|
||||
#include "input/mpegps.h"
|
||||
#endif
|
||||
|
@ -36,6 +91,4 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
void input_init ( void );
|
||||
|
||||
#endif /* __TVH_INPUT_H__ */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef __TVH_MPEGTS_H__
|
||||
#define __TVH_MPEGTS_H__
|
||||
|
||||
#include "input.h"
|
||||
#include "service.h"
|
||||
#include "mpegts/dvb.h"
|
||||
|
||||
|
@ -374,8 +375,9 @@ struct mpegts_mux_instance
|
|||
|
||||
LIST_HEAD(,th_subscription) mmi_subs;
|
||||
|
||||
// TODO: remove this
|
||||
int mmi_tune_failed; // this is really DVB
|
||||
tvh_input_stream_stats_t mmi_stats;
|
||||
|
||||
int mmi_tune_failed;
|
||||
|
||||
void (*mmi_delete) (mpegts_mux_instance_t *mmi);
|
||||
};
|
||||
|
@ -390,7 +392,7 @@ struct mpegts_mux_sub
|
|||
/* Input source */
|
||||
struct mpegts_input
|
||||
{
|
||||
idnode_t mi_id;
|
||||
tvh_input_t;
|
||||
|
||||
int mi_enabled;
|
||||
|
||||
|
@ -407,6 +409,11 @@ struct mpegts_input
|
|||
|
||||
LIST_HEAD(,mpegts_mux_instance) mi_mux_instances;
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
gtimer_t mi_status_timer;
|
||||
|
||||
/*
|
||||
* Input processing
|
||||
*/
|
||||
|
@ -416,8 +423,6 @@ struct mpegts_input
|
|||
LIST_HEAD(,service) mi_transports;
|
||||
|
||||
|
||||
int mi_bytes;
|
||||
|
||||
struct mpegts_table_feed_queue mi_table_feed;
|
||||
pthread_cond_t mi_table_feed_cond; // Bound to mi_delivery_mutex
|
||||
|
||||
|
@ -484,6 +489,8 @@ void mpegts_input_set_network ( mpegts_input_t *mi, mpegts_network_t *mn );
|
|||
void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init );
|
||||
void mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s );
|
||||
|
||||
void mpegts_input_status_timer ( void *p );
|
||||
|
||||
void mpegts_network_register_builder
|
||||
( const idclass_t *idc,
|
||||
mpegts_network_t *(*build)(const idclass_t *idc, htsmsg_t *conf) );
|
||||
|
|
|
@ -71,7 +71,7 @@ linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m )
|
|||
htsmsg_t *l;
|
||||
linuxdvb_hardware_t *lh;
|
||||
|
||||
idnode_save(&la->mi_id, m);
|
||||
idnode_save(&la->ti_id, m);
|
||||
htsmsg_add_u32(m, "number", la->la_number);
|
||||
if (la->la_rootpath)
|
||||
htsmsg_add_str(m, "rootpath", la->la_rootpath);
|
||||
|
@ -81,7 +81,7 @@ linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m )
|
|||
LIST_FOREACH(lh, &la->lh_children, lh_parent_link) {
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
linuxdvb_frontend_save((linuxdvb_frontend_t*)lh, e);
|
||||
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->mi_id), e);
|
||||
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->ti_id), e);
|
||||
}
|
||||
htsmsg_add_msg(m, "frontends", l);
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ linuxdvb_adapter_create0
|
|||
linuxdvb_adapter_t *la;
|
||||
|
||||
la = calloc(1, sizeof(linuxdvb_adapter_t));
|
||||
if (idnode_insert(&la->mi_id, uuid, &linuxdvb_adapter_class)) {
|
||||
if (idnode_insert(&la->ti_id, uuid, &linuxdvb_adapter_class)) {
|
||||
free(la);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ linuxdvb_adapter_create0
|
|||
if (!conf)
|
||||
return la;
|
||||
|
||||
idnode_load(&la->mi_id, conf);
|
||||
idnode_load(&la->ti_id, conf);
|
||||
if (!htsmsg_get_u32(conf, "number", &u32))
|
||||
la->la_number = u32;
|
||||
if ((str = htsmsg_get_str(conf, "rootpath")))
|
||||
|
|
|
@ -175,20 +175,20 @@ void linuxdvb_device_save ( linuxdvb_device_t *ld )
|
|||
|
||||
m = htsmsg_create_map();
|
||||
|
||||
idnode_save(&ld->mi_id, m);
|
||||
idnode_save(&ld->ti_id, m);
|
||||
|
||||
/* Adapters */
|
||||
l = htsmsg_create_map();
|
||||
LIST_FOREACH(lh, &ld->lh_children, lh_parent_link) {
|
||||
e = htsmsg_create_map();
|
||||
linuxdvb_adapter_save((linuxdvb_adapter_t*)lh, e);
|
||||
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->mi_id), e);
|
||||
htsmsg_add_msg(l, idnode_uuid_as_str(&lh->ti_id), e);
|
||||
}
|
||||
htsmsg_add_msg(m, "adapters", l);
|
||||
|
||||
/* Save */
|
||||
hts_settings_save(m, "input/linuxdvb/devices/%s",
|
||||
idnode_uuid_as_str(&ld->mi_id));
|
||||
idnode_uuid_as_str(&ld->ti_id));
|
||||
}
|
||||
|
||||
const idclass_t linuxdvb_device_class =
|
||||
|
@ -226,7 +226,7 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
|
|||
|
||||
/* Create */
|
||||
ld = calloc(1, sizeof(linuxdvb_device_t));
|
||||
if (idnode_insert(&ld->mi_id, uuid, &linuxdvb_device_class)) {
|
||||
if (idnode_insert(&ld->ti_id, uuid, &linuxdvb_device_class)) {
|
||||
free(ld);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ linuxdvb_device_create0 ( const char *uuid, htsmsg_t *conf )
|
|||
return ld;
|
||||
|
||||
/* Load config */
|
||||
idnode_load(&ld->mi_id, conf);
|
||||
idnode_load(&ld->ti_id, conf);
|
||||
get_min_dvb_adapter(&ld->ld_devid);
|
||||
|
||||
/* Adapters */
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
rk_class
|
||||
* Tvheadend - Linux DVB frontend
|
||||
*
|
||||
* Copyright (C) 2013 Adam Sutton
|
||||
|
@ -461,42 +460,11 @@ linuxdvb_frontend_open_all
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
linuxdvb_frontend_monitor_stats ( linuxdvb_frontend_t *lfe, const char *name )
|
||||
{
|
||||
int bw;
|
||||
htsmsg_t *m, *l, *e;
|
||||
mpegts_mux_instance_t *mmi;
|
||||
|
||||
/* Send message */
|
||||
m = htsmsg_create_map();
|
||||
htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&lfe->mi_id));
|
||||
htsmsg_add_str(m, "name", name);
|
||||
htsmsg_add_str(m, "type", "linuxdvb");
|
||||
|
||||
/* Mux list */
|
||||
if ((mmi = LIST_FIRST(&lfe->mi_mux_active))) {
|
||||
char buf[256];
|
||||
l = htsmsg_create_list();
|
||||
e = htsmsg_create_map();
|
||||
mmi->mmi_mux->mm_display_name(mmi->mmi_mux, buf, sizeof(buf));
|
||||
htsmsg_add_str(e, "name", buf);
|
||||
htsmsg_add_u32(e, "bytes", 0); // TODO
|
||||
// TODO: signal info
|
||||
htsmsg_add_msg(l, NULL, e);
|
||||
htsmsg_add_msg(m, "muxes", l);
|
||||
}
|
||||
|
||||
/* Total data */
|
||||
bw = atomic_exchange(&lfe->mi_bytes, 0);
|
||||
htsmsg_add_u32(m, "bytes", bw);
|
||||
|
||||
notify_by_msg("input", m);
|
||||
}
|
||||
|
||||
static void
|
||||
linuxdvb_frontend_monitor ( void *aux )
|
||||
{
|
||||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
char buf[256];
|
||||
linuxdvb_frontend_t *lfe = aux;
|
||||
mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active);
|
||||
|
@ -573,8 +541,15 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
}
|
||||
}
|
||||
|
||||
/* Monitor stats */
|
||||
linuxdvb_frontend_monitor_stats(lfe, buf);
|
||||
/* Statistics */
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16))
|
||||
mmi->mmi_stats.signal = u16;
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
|
||||
mmi->mmi_stats.ber = u32;
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16))
|
||||
mmi->mmi_stats.snr = u16;
|
||||
if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32))
|
||||
mmi->mmi_stats.unc = u32;
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
|
@ -35,7 +35,7 @@ linuxdvb_hardware_enumerate ( linuxdvb_hardware_list_t *list )
|
|||
linuxdvb_hardware_t *lh;
|
||||
idnode_set_t *set = idnode_set_create();
|
||||
LIST_FOREACH(lh, list, lh_parent_link)
|
||||
idnode_set_add(set, &lh->mi_id, NULL);
|
||||
idnode_set_add(set, &lh->ti_id, NULL);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ linuxdvb_satconf_class_frontend_get ( void *o )
|
|||
static const char *s;
|
||||
linuxdvb_satconf_t *ls = o;
|
||||
if (ls->ls_frontend)
|
||||
s = idnode_uuid_as_str(&ls->ls_frontend->mi_id);
|
||||
s = idnode_uuid_as_str(&ls->ls_frontend->ti_id);
|
||||
else
|
||||
s = NULL;
|
||||
return &s;
|
||||
|
@ -123,7 +123,7 @@ linuxdvb_satconf_class_frontend_enum (void *o)
|
|||
for (i = 0; i < is->is_count; i++) {
|
||||
mpegts_input_t *mi = (mpegts_input_t*)is->is_array[i];
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "key", idnode_uuid_as_str(&mi->mi_id));
|
||||
htsmsg_add_str(e, "key", idnode_uuid_as_str(&mi->ti_id));
|
||||
*buf = 0;
|
||||
mi->mi_display_name(mi, buf, sizeof(buf));
|
||||
htsmsg_add_str(e, "val", buf);
|
||||
|
@ -585,7 +585,7 @@ linuxdvb_diseqc_class_save ( idnode_t *o )
|
|||
{
|
||||
linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o;
|
||||
if (ld->ld_satconf)
|
||||
linuxdvb_satconf_class_save(&ld->ld_satconf->mi_id);
|
||||
linuxdvb_satconf_class_save(&ld->ld_satconf->ti_id);
|
||||
}
|
||||
|
||||
const idclass_t linuxdvb_diseqc_class =
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "streaming.h"
|
||||
#include "subscriptions.h"
|
||||
#include "atomic.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
@ -164,8 +165,15 @@ static void
|
|||
mpegts_input_started_mux
|
||||
( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
|
||||
{
|
||||
/* Arm timer */
|
||||
if (LIST_FIRST(&mi->mi_mux_active) == NULL)
|
||||
gtimer_arm(&mi->mi_status_timer, mpegts_input_status_timer,
|
||||
mi, 1);
|
||||
|
||||
/* Update */
|
||||
mmi->mmi_mux->mm_active = mmi;
|
||||
LIST_INSERT_HEAD(&mi->mi_mux_active, mmi, mmi_active_link);
|
||||
notify_reload("input_status");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -177,6 +185,10 @@ mpegts_input_stopped_mux
|
|||
mmi->mmi_mux->mm_active = NULL;
|
||||
LIST_REMOVE(mmi, mmi_active_link);
|
||||
|
||||
/* Disarm timer */
|
||||
if (LIST_FIRST(&mi->mi_mux_active) == NULL)
|
||||
gtimer_disarm(&mi->mi_status_timer);
|
||||
|
||||
mi->mi_display_name(mi, buf, sizeof(buf));
|
||||
tvhtrace("mpegts", "%s - flush subscribers", buf);
|
||||
s = LIST_FIRST(&mi->mi_transports);
|
||||
|
@ -185,6 +197,7 @@ mpegts_input_stopped_mux
|
|||
service_remove_subscriber(s, NULL, SM_CODE_SUBSCRIPTION_OVERRIDDEN);
|
||||
s = LIST_NEXT(s, s_active_link);
|
||||
}
|
||||
notify_reload("input_status");
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -290,7 +303,7 @@ mpegts_input_recv_packets
|
|||
pthread_mutex_unlock(&mi->mi_delivery_mutex);
|
||||
|
||||
/* Bandwidth monitoring */
|
||||
atomic_add(&mi->mi_bytes, i);
|
||||
atomic_add(&mmi->mmi_stats.bps, i);
|
||||
|
||||
/* Reset buffer */
|
||||
if (len) memmove(tsb, tsb+i, len);
|
||||
|
@ -371,6 +384,59 @@ mpegts_input_flush_mux
|
|||
pthread_mutex_unlock(&mi->mi_delivery_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_input_stream_status
|
||||
( mpegts_mux_instance_t *mmi, tvh_input_stream_t *st )
|
||||
{
|
||||
int s = 0, w = 0;
|
||||
char buf[512];
|
||||
mmi->mmi_mux->mm_display_name(mmi->mmi_mux, buf, sizeof(buf));
|
||||
st->uuid = strdup(idnode_uuid_as_str(&mmi->mmi_id));
|
||||
st->input_name = strdup(mmi->mmi_input->mi_displayname?:"");
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_input_get_streams
|
||||
( tvh_input_t *i, tvh_input_stream_list_t *isl )
|
||||
{
|
||||
tvh_input_stream_t *st;
|
||||
mpegts_input_t *mi = (mpegts_input_t*)i;
|
||||
mpegts_mux_instance_t *mmi;
|
||||
|
||||
LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) {
|
||||
st = calloc(1, sizeof(tvh_input_stream_t));
|
||||
mpegts_input_stream_status(mmi, st);
|
||||
LIST_INSERT_HEAD(isl, st, link);
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
* Status monitoring
|
||||
* *************************************************************************/
|
||||
|
||||
void
|
||||
mpegts_input_status_timer ( void *p )
|
||||
{
|
||||
tvh_input_stream_t st;
|
||||
mpegts_input_t *mi = p;
|
||||
mpegts_mux_instance_t *mmi;
|
||||
htsmsg_t *e;
|
||||
LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) {
|
||||
memset(&st, 0, sizeof(st));
|
||||
mpegts_input_stream_status(mmi, &st);
|
||||
e = tvh_input_stream_create_msg(&st);
|
||||
htsmsg_add_u32(e, "update", 1);
|
||||
notify_by_msg("input_status", e);
|
||||
tvh_input_stream_destroy(&st);
|
||||
}
|
||||
gtimer_arm(&mi->mi_status_timer, mpegts_input_status_timer, mi, 1);
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
* Creation/Config
|
||||
* *************************************************************************/
|
||||
|
@ -383,7 +449,8 @@ mpegts_input_create0
|
|||
( mpegts_input_t *mi, const idclass_t *class, const char *uuid,
|
||||
htsmsg_t *c )
|
||||
{
|
||||
idnode_insert(&mi->mi_id, uuid, class);
|
||||
idnode_insert(&mi->ti_id, uuid, class);
|
||||
LIST_INSERT_HEAD(&tvh_inputs, (tvh_input_t*)mi, ti_link);
|
||||
|
||||
/* Defaults */
|
||||
mi->mi_is_enabled = mpegts_input_is_enabled;
|
||||
|
@ -398,6 +465,7 @@ mpegts_input_create0
|
|||
mi->mi_started_mux = mpegts_input_started_mux;
|
||||
mi->mi_stopped_mux = mpegts_input_stopped_mux;
|
||||
mi->mi_has_subscription = mpegts_input_has_subscription;
|
||||
mi->ti_get_streams = mpegts_input_get_streams;
|
||||
|
||||
/* Index */
|
||||
mi->mi_instance = ++mpegts_input_idx;
|
||||
|
@ -417,7 +485,7 @@ mpegts_input_create0
|
|||
|
||||
/* Load config */
|
||||
if (c)
|
||||
idnode_load(&mi->mi_id, c);
|
||||
idnode_load(&mi->ti_id, c);
|
||||
|
||||
return mi;
|
||||
}
|
||||
|
@ -425,7 +493,7 @@ mpegts_input_create0
|
|||
void
|
||||
mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *m )
|
||||
{
|
||||
idnode_save(&mi->mi_id, m);
|
||||
idnode_save(&mi->ti_id, m);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -136,9 +136,61 @@ tvheadend.status_subs = function() {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* Streams
|
||||
*/
|
||||
tvheadend.status_adapters = function() {
|
||||
tvheadend.status_streams = function() {
|
||||
|
||||
var stream_store = new Ext.data.JsonStore({
|
||||
root : 'entries',
|
||||
totalProperty : 'totalCount',
|
||||
fields : [ {
|
||||
name : 'uuid'
|
||||
}, {
|
||||
name : 'input'
|
||||
}, {
|
||||
name : 'username'
|
||||
}, {
|
||||
name : 'stream'
|
||||
}, {
|
||||
name : 'subs'
|
||||
}, {
|
||||
name : 'weight'
|
||||
}, {
|
||||
name : 'signal'
|
||||
}, {
|
||||
name : 'ber'
|
||||
}, {
|
||||
name : 'unc'
|
||||
}, {
|
||||
name : 'snr'
|
||||
}, {
|
||||
name : 'bps'
|
||||
},
|
||||
],
|
||||
url : 'api/input/status',
|
||||
autoLoad : true,
|
||||
id : 'uuid'
|
||||
});
|
||||
|
||||
tvheadend.comet.on('input_status', function(m){
|
||||
if (m.reload != null) stream_store.reload();
|
||||
if (m.update != null) {
|
||||
var r = stream_store.getById(m.uuid);
|
||||
if (r) {
|
||||
r.data.subs = m.subs;
|
||||
r.data.weight = m.weight;
|
||||
r.data.signal = m.signal;
|
||||
r.data.ber = m.ber;
|
||||
r.data.unc = m.unc;
|
||||
r.data.snr = m.snr;
|
||||
r.data.bps = m.bps;
|
||||
stream_store.afterEdit(r);
|
||||
stream_store.fireEvent('updated', stream_store, r, Ext.data.Record.COMMIT);
|
||||
} else {
|
||||
stream_store.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var signal = new Ext.ux.grid.ProgressColumn({
|
||||
header : "Signal Strength",
|
||||
|
@ -149,30 +201,30 @@ tvheadend.status_adapters = function() {
|
|||
});
|
||||
|
||||
function renderBw(value) {
|
||||
return parseInt(value / 125);
|
||||
return parseInt(value / 1024);
|
||||
}
|
||||
|
||||
var cm = new Ext.grid.ColumnModel([{
|
||||
width : 50,
|
||||
header : "Name",
|
||||
dataIndex : 'name'
|
||||
},{
|
||||
width : 50,
|
||||
header : "Hardware device",
|
||||
dataIndex : 'path'
|
||||
width : 100,
|
||||
header : "Input",
|
||||
dataIndex : 'input'
|
||||
},{
|
||||
width : 100,
|
||||
header : "Currently tuned to",
|
||||
dataIndex : 'currentMux'
|
||||
header : "Stream",
|
||||
dataIndex : 'stream'
|
||||
},{
|
||||
width : 50,
|
||||
header : "Subs #",
|
||||
dataIndex : 'subs'
|
||||
},{
|
||||
width : 50,
|
||||
header : "Weight",
|
||||
dataIndex : 'weight'
|
||||
},{
|
||||
width : 100,
|
||||
header : "Bandwidth (kb/s)",
|
||||
dataIndex : 'bw',
|
||||
dataIndex : 'bps',
|
||||
renderer: renderBw
|
||||
},{
|
||||
width : 50,
|
||||
header : "Used for",
|
||||
dataIndex : 'reason'
|
||||
},{
|
||||
width : 50,
|
||||
header : "Bit error rate",
|
||||
|
@ -180,7 +232,7 @@ tvheadend.status_adapters = function() {
|
|||
},{
|
||||
width : 50,
|
||||
header : "Uncorrected bit error rate",
|
||||
dataIndex : 'uncavg'
|
||||
dataIndex : 'unc'
|
||||
},{
|
||||
width : 50,
|
||||
header : "SNR",
|
||||
|
@ -199,9 +251,9 @@ tvheadend.status_adapters = function() {
|
|||
loadMask : true,
|
||||
stripeRows : true,
|
||||
disableSelection : true,
|
||||
title : 'Adapters',
|
||||
title : 'Stream',
|
||||
iconCls : 'hardware',
|
||||
store : tvheadend.tvAdapterStore,
|
||||
store : stream_store,
|
||||
cm : cm,
|
||||
flex: 1,
|
||||
viewConfig : {
|
||||
|
@ -218,7 +270,7 @@ tvheadend.status = function() {
|
|||
layout : 'vbox',
|
||||
title : 'Status',
|
||||
iconCls : 'eye',
|
||||
items : [ new tvheadend.status_subs, new tvheadend.status_adapters ]
|
||||
items : [ new tvheadend.status_subs, new tvheadend.status_streams ]
|
||||
});
|
||||
|
||||
return panel;
|
||||
|
|
Loading…
Add table
Reference in a new issue