channel number: add minor number handling for ATSC

This commit is contained in:
Jaroslav Kysela 2014-09-11 15:27:01 +02:00
parent 7074bb61bb
commit c073538e05
12 changed files with 108 additions and 30 deletions

View file

@ -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;

View file

@ -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 );

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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__

View file

@ -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>");
}
}

View file

@ -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,