Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
channel number: add minor number handling for ATSC
  • Loading branch information
perexg committed Sep 11, 2014
1 parent 7074bb6 commit c073538
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 30 deletions.
7 changes: 4 additions & 3 deletions src/channels.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -507,7 +508,7 @@ channel_get_name ( channel_t *ch )
return blank;
}

int
int64_t
channel_get_number ( channel_t *ch )
{
int n;
Expand Down
7 changes: 6 additions & 1 deletion src/channels.h
Expand Up @@ -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 );
Expand Down
5 changes: 4 additions & 1 deletion src/htsp_server.c
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion src/input/mpegts.h
Expand Up @@ -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;
Expand All @@ -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
Expand Down
6 changes: 2 additions & 4 deletions src/input/mpegts/dvb_psi.c
Expand Up @@ -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;
}

Expand Down
15 changes: 12 additions & 3 deletions src/input/mpegts/mpegts_service.c
Expand Up @@ -20,6 +20,7 @@
#include <assert.h>

#include "service.h"
#include "channels.h"
#include "input.h"
#include "settings.h"
#include "dvb_charset.h"
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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;
}

Expand Down
57 changes: 48 additions & 9 deletions src/prop.c
Expand Up @@ -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: {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/prop.h
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/service.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/service.h
Expand Up @@ -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 *);

Expand Down Expand Up @@ -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__
13 changes: 11 additions & 2 deletions src/webui/statedump.c
Expand Up @@ -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>");
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/webui/static/app/idnode.js
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

4 comments on commit c073538

@stan86
Copy link

@stan86 stan86 commented on c073538 Sep 12, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit breaks channel numbers > 1000.

@ProfYaffle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it also explain this? DVB-T and DVB-S, mostly (but not exclusively) radio stations.

screenshot - 120914 - 13 30 50

@perexg
Copy link
Contributor Author

@perexg perexg commented on c073538 Sep 12, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ea9d782 .

@ProfYaffle : Really nice values :-)

@ProfYaffle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@perexg Don't blame me, it's your code that's (still) generating them! :)

Please sign in to comment.