channel number: add minor number handling for ATSC
This commit is contained in:
parent
7074bb61bb
commit
c073538e05
12 changed files with 108 additions and 30 deletions
|
@ -208,7 +208,7 @@ channel_class_get_name ( void *p )
|
|||
static const void *
|
||||
channel_class_get_number ( void *p )
|
||||
{
|
||||
static int i;
|
||||
static int64_t i;
|
||||
i = channel_get_number(p);
|
||||
return &i;
|
||||
}
|
||||
|
@ -296,7 +296,8 @@ const idclass_t channel_class = {
|
|||
.get = channel_class_get_name,
|
||||
},
|
||||
{
|
||||
.type = PT_INT,
|
||||
.type = PT_S64,
|
||||
.intsplit = CHANNEL_SPLIT,
|
||||
.id = "number",
|
||||
.name = "Number",
|
||||
.off = offsetof(channel_t, ch_number),
|
||||
|
@ -507,7 +508,7 @@ channel_get_name ( channel_t *ch )
|
|||
return blank;
|
||||
}
|
||||
|
||||
int
|
||||
int64_t
|
||||
channel_get_number ( channel_t *ch )
|
||||
{
|
||||
int n;
|
||||
|
|
|
@ -177,7 +177,12 @@ void channel_save(channel_t *ch);
|
|||
const char *channel_get_name ( channel_t *ch );
|
||||
int channel_set_name ( channel_t *ch, const char *s );
|
||||
|
||||
int channel_get_number ( channel_t *ch );
|
||||
#define CHANNEL_SPLIT 1000000
|
||||
|
||||
static inline uint32_t channel_get_major ( int64_t chnum ) { return chnum / CHANNEL_SPLIT; }
|
||||
static inline uint32_t channel_get_minor ( int64_t chnum ) { return chnum % CHANNEL_SPLIT; }
|
||||
|
||||
int64_t channel_get_number ( channel_t *ch );
|
||||
|
||||
const char *channel_get_icon ( channel_t *ch );
|
||||
int channel_set_icon ( channel_t *ch, const char *icon );
|
||||
|
|
|
@ -550,13 +550,16 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp)
|
|||
channel_tag_t *ct;
|
||||
service_t *t;
|
||||
epg_broadcast_t *now, *next = NULL;
|
||||
int64_t chnum = channel_get_number(ch);
|
||||
|
||||
htsmsg_t *out = htsmsg_create_map();
|
||||
htsmsg_t *tags = htsmsg_create_list();
|
||||
htsmsg_t *services = htsmsg_create_list();
|
||||
|
||||
htsmsg_add_u32(out, "channelId", channel_get_id(ch));
|
||||
htsmsg_add_u32(out, "channelNumber", channel_get_number(ch));
|
||||
htsmsg_add_u32(out, "channelNumber", channel_get_major(chnum));
|
||||
if (channel_get_minor(chnum))
|
||||
htsmsg_add_u32(out, "channelNumberMinor", channel_get_minor(chnum));
|
||||
|
||||
htsmsg_add_str(out, "channelName", channel_get_name(ch));
|
||||
if(ch->ch_icon != NULL) {
|
||||
|
|
|
@ -425,6 +425,7 @@ struct mpegts_service
|
|||
|
||||
uint16_t s_dvb_service_id;
|
||||
uint16_t s_dvb_channel_num;
|
||||
uint16_t s_dvb_channel_minor;
|
||||
char *s_dvb_svcname;
|
||||
char *s_dvb_provider;
|
||||
char *s_dvb_cridauth;
|
||||
|
@ -438,7 +439,7 @@ struct mpegts_service
|
|||
*/
|
||||
|
||||
int s_dvb_eit_enable;
|
||||
uint16_t s_dvb_opentv_chnum;
|
||||
uint64_t s_dvb_opentv_chnum;
|
||||
|
||||
/*
|
||||
* Link to carrying multiplex and active adapter
|
||||
|
|
|
@ -1070,11 +1070,9 @@ atsc_vct_callback
|
|||
tvh_str_set(&s->s_dvb_svcname, chname);
|
||||
save = 1;
|
||||
}
|
||||
if (s->s_dvb_channel_num != maj) {
|
||||
// TODO: ATSC channel numbering is plain weird!
|
||||
// could shift the major (*100 or something) and append
|
||||
// minor, but that'll probably confuse people, as will this!
|
||||
if (s->s_dvb_channel_num != maj || s->s_dvb_channel_minor != min) {
|
||||
s->s_dvb_channel_num = maj;
|
||||
s->s_dvb_channel_minor = min;
|
||||
save = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "service.h"
|
||||
#include "channels.h"
|
||||
#include "input.h"
|
||||
#include "settings.h"
|
||||
#include "dvb_charset.h"
|
||||
|
@ -101,6 +102,13 @@ const idclass_t mpegts_service_class =
|
|||
.opts = PO_RDONLY,
|
||||
.off = offsetof(mpegts_service_t, s_dvb_channel_num),
|
||||
},
|
||||
{
|
||||
.type = PT_U16,
|
||||
.id = "lcn_minor",
|
||||
.name = "Local Channel Minor",
|
||||
.opts = PO_RDONLY,
|
||||
.off = offsetof(mpegts_service_t, s_dvb_channel_minor),
|
||||
},
|
||||
{
|
||||
.type = PT_U16,
|
||||
.id = "lcn2",
|
||||
|
@ -364,12 +372,13 @@ mpegts_service_grace_period(service_t *t)
|
|||
/*
|
||||
* Channel number
|
||||
*/
|
||||
static int
|
||||
static int64_t
|
||||
mpegts_service_channel_number ( service_t *s )
|
||||
{
|
||||
int r = ((mpegts_service_t*)s)->s_dvb_channel_num;
|
||||
int r = ((mpegts_service_t*)s)->s_dvb_channel_num * CHANNEL_SPLIT +
|
||||
((mpegts_service_t*)s)->s_dvb_channel_minor;
|
||||
if (r <= 0)
|
||||
r = ((mpegts_service_t*)s)->s_dvb_opentv_chnum;
|
||||
r = ((mpegts_service_t*)s)->s_dvb_opentv_chnum * CHANNEL_SPLIT;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
57
src/prop.c
57
src/prop.c
|
@ -133,16 +133,33 @@ prop_write_values
|
|||
break;
|
||||
}
|
||||
case PT_U32: {
|
||||
if (htsmsg_field_get_u32(f, &u32))
|
||||
continue;
|
||||
if (p->intsplit) {
|
||||
char *s;
|
||||
if (!(new = htsmsg_field_get_str(f)))
|
||||
continue;
|
||||
u32 = atol(new) * p->intsplit;
|
||||
if ((s = strchr(new, '.')) != NULL)
|
||||
u32 += (atol(s + 1) % p->intsplit);
|
||||
} else {
|
||||
if (htsmsg_field_get_u32(f, &u32))
|
||||
continue;
|
||||
}
|
||||
PROP_UPDATE(u32, uint32_t);
|
||||
break;
|
||||
}
|
||||
case PT_S64: {
|
||||
if (htsmsg_field_get_s64(f, &s64))
|
||||
continue;
|
||||
i = s64;
|
||||
PROP_UPDATE(i, int64_t);
|
||||
if (p->intsplit) {
|
||||
char *s;
|
||||
if (!(new = htsmsg_field_get_str(f)))
|
||||
continue;
|
||||
s64 = atol(new) * p->intsplit;
|
||||
if ((s = strchr(new, '.')) != NULL)
|
||||
s64 += (atol(s + 1) % p->intsplit);
|
||||
} else {
|
||||
if (htsmsg_field_get_s64(f, &s64))
|
||||
continue;
|
||||
}
|
||||
PROP_UPDATE(s64, int64_t);
|
||||
break;
|
||||
}
|
||||
case PT_DBL: {
|
||||
|
@ -230,7 +247,7 @@ prop_read_value
|
|||
const char *s;
|
||||
const void *val = obj + p->off;
|
||||
uint32_t u32;
|
||||
char buf[16];
|
||||
char buf[24];
|
||||
|
||||
/* Ignore */
|
||||
u32 = p->get_opts ? p->get_opts(obj) : p->opts;
|
||||
|
@ -262,10 +279,28 @@ prop_read_value
|
|||
htsmsg_add_u32(m, name, *(uint16_t *)val);
|
||||
break;
|
||||
case PT_U32:
|
||||
htsmsg_add_u32(m, name, *(uint32_t *)val);
|
||||
if (p->intsplit) {
|
||||
uint32_t maj = *(int64_t *)val / p->intsplit;
|
||||
uint32_t min = *(int64_t *)val % p->intsplit;
|
||||
if (min) {
|
||||
snprintf(buf, sizeof(buf), "%u.%u", (unsigned int)maj, (unsigned int)min);
|
||||
htsmsg_add_str(m, name, buf);
|
||||
} else
|
||||
htsmsg_add_s64(m, name, maj);
|
||||
} else
|
||||
htsmsg_add_u32(m, name, *(uint32_t *)val);
|
||||
break;
|
||||
case PT_S64:
|
||||
htsmsg_add_s64(m, name, *(int64_t *)val);
|
||||
if (p->intsplit) {
|
||||
int64_t maj = *(int64_t *)val / p->intsplit;
|
||||
int64_t min = *(int64_t *)val % p->intsplit;
|
||||
if (min) {
|
||||
snprintf(buf, sizeof(buf), "%lu.%lu", (unsigned long)maj, (unsigned long)min);
|
||||
htsmsg_add_str(m, name, buf);
|
||||
} else
|
||||
htsmsg_add_s64(m, name, maj);
|
||||
} else
|
||||
htsmsg_add_s64(m, name, *(int64_t *)val);
|
||||
break;
|
||||
case PT_STR:
|
||||
if ((s = *(const char **)val))
|
||||
|
@ -421,6 +456,10 @@ prop_serialize_value
|
|||
if (pl->group)
|
||||
htsmsg_add_u32(m, "group", pl->group);
|
||||
|
||||
/* Split integer value */
|
||||
if (pl->intsplit)
|
||||
htsmsg_add_u32(m, "intsplit", pl->intsplit);
|
||||
|
||||
/* Data */
|
||||
if (obj)
|
||||
prop_read_value(obj, pl, m, "value", optmask);
|
||||
|
|
|
@ -62,10 +62,11 @@ typedef struct property {
|
|||
const char *id; ///< Property Key
|
||||
const char *name; ///< Textual description
|
||||
prop_type_t type; ///< Type
|
||||
int islist; ///< Is a list
|
||||
uint8_t islist; ///< Is a list
|
||||
uint8_t group; ///< Visual group ID (like ExtJS FieldSet)
|
||||
size_t off; ///< Offset into object
|
||||
uint32_t opts; ///< Options
|
||||
uint32_t group; ///< Visual group ID (like ExtJS FieldSet)
|
||||
uint32_t intsplit; ///< integer/remainder boundary
|
||||
|
||||
/* String based processing */
|
||||
const void *(*get) (void *ptr);
|
||||
|
|
|
@ -803,7 +803,7 @@ service_destroy(service_t *t, int delconf)
|
|||
service_unref(t);
|
||||
}
|
||||
|
||||
static int
|
||||
static int64_t
|
||||
service_channel_number ( service_t *s )
|
||||
{
|
||||
return 0;
|
||||
|
@ -1567,7 +1567,7 @@ service_get_full_channel_name ( service_t *s )
|
|||
/*
|
||||
* Get number for service
|
||||
*/
|
||||
int
|
||||
int64_t
|
||||
service_get_channel_number ( service_t *s )
|
||||
{
|
||||
if (s->s_channel_number) return s->s_channel_number(s);
|
||||
|
|
|
@ -292,7 +292,7 @@ typedef struct service {
|
|||
/**
|
||||
* Channel info
|
||||
*/
|
||||
int (*s_channel_number) (struct service *);
|
||||
int64_t (*s_channel_number) (struct service *);
|
||||
const char *(*s_channel_name) (struct service *);
|
||||
const char *(*s_provider_name) (struct service *);
|
||||
|
||||
|
@ -554,6 +554,6 @@ void sort_elementary_streams(service_t *t);
|
|||
|
||||
const char *service_get_channel_name (service_t *s);
|
||||
const char *service_get_full_channel_name (service_t *s);
|
||||
int service_get_channel_number (service_t *s);
|
||||
int64_t service_get_channel_number (service_t *s);
|
||||
|
||||
#endif // SERVICE_H__
|
||||
|
|
|
@ -54,18 +54,27 @@ dumpchannels(htsbuf_queue_t *hq)
|
|||
{
|
||||
channel_t *ch;
|
||||
outputtitle(hq, 0, "Channels");
|
||||
int64_t chnum;
|
||||
char chbuf[32];
|
||||
|
||||
CHANNEL_FOREACH(ch) {
|
||||
|
||||
htsbuf_qprintf(hq, "%s (%d)\n", channel_get_name(ch), channel_get_id(ch));
|
||||
chnum = channel_get_number(ch);
|
||||
if (channel_get_minor(chnum))
|
||||
snprintf(chbuf, sizeof(chbuf), "%u.%u",
|
||||
channel_get_major(chnum),
|
||||
channel_get_minor(chnum));
|
||||
else
|
||||
snprintf(chbuf, sizeof(chbuf), "%u", channel_get_major(chnum));
|
||||
htsbuf_qprintf(hq,
|
||||
" refcount = %d\n"
|
||||
" zombie = %d\n"
|
||||
" number = %d\n"
|
||||
" number = %s\n"
|
||||
" icon = %s\n\n",
|
||||
ch->ch_refcount,
|
||||
ch->ch_zombie,
|
||||
channel_get_number(ch),
|
||||
chbuf,
|
||||
ch->ch_icon ?: "<none set>");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,6 +122,7 @@ tvheadend.IdNodeField = function(conf)
|
|||
this.hidden = conf.hidden || conf.advanced;
|
||||
this.password = conf.password;
|
||||
this.duration = conf.duration;
|
||||
this.intsplit = conf.intsplit;
|
||||
this.group = conf.group;
|
||||
this.enum = conf.enum;
|
||||
this.store = null;
|
||||
|
@ -490,6 +491,17 @@ tvheadend.idnode_editor_field = function(f, create)
|
|||
case 'u16':
|
||||
case 's64':
|
||||
case 'dbl':
|
||||
if (f.intsplit) {
|
||||
/* this should be improved */
|
||||
return new Ext.form.TextField({
|
||||
fieldLabel: f.caption,
|
||||
name: f.id,
|
||||
value: value,
|
||||
disabled: d,
|
||||
width: 300,
|
||||
maskRe: /[0-9\.]/,
|
||||
});
|
||||
}
|
||||
return new Ext.form.NumberField({
|
||||
fieldLabel: f.caption,
|
||||
name: f.id,
|
||||
|
|
Loading…
Add table
Reference in a new issue