Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
dvb psi: LCN updates
  • Loading branch information
perexg committed Nov 20, 2014
1 parent 898f88a commit d0a6684
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 34 deletions.
1 change: 1 addition & 0 deletions src/input/mpegts.h
Expand Up @@ -434,6 +434,7 @@ struct mpegts_service

uint32_t s_dvb_channel_num;
uint16_t s_dvb_channel_minor;
uint8_t s_dvb_channel_dtag;
uint16_t s_dvb_service_id;
char *s_dvb_svcname;
char *s_dvb_provider;
Expand Down
3 changes: 0 additions & 3 deletions src/input/mpegts/dvb.h
Expand Up @@ -130,9 +130,6 @@ struct mpegts_mux;
#define DVB_DESC_EAC3 0x7A
#define DVB_DESC_AAC 0x7C

#define DVB_DESC_LOCAL_CHAN1 0x81 /* UPC - 1W */
#define DVB_DESC_LOCAL_CHAN2 0x83

#define DVB_DESC_BSKYB_LCN 0xB1

#define DVB_DESC_BSKYB_NVOD 0xC0
Expand Down
80 changes: 49 additions & 31 deletions src/input/mpegts/dvb_psi.c
Expand Up @@ -33,6 +33,8 @@
#include <stdlib.h>
#include <string.h>

#define PRIV_FSAT (('F' << 24) | ('S' << 16) | ('A' << 8) | 'T')

typedef struct dvb_freesat_svc {
TAILQ_ENTRY(dvb_freesat_svc) link;
TAILQ_ENTRY(dvb_freesat_svc) region_link;
Expand All @@ -53,6 +55,7 @@ typedef struct dvb_freesat_region {
typedef struct dvb_bat_svc {
TAILQ_ENTRY(dvb_bat_svc) link;
mpegts_service_t *svc;
uint8_t lcn_dtag;
uint32_t lcn;
dvb_freesat_svc_t *fallback;
int used;
Expand All @@ -64,7 +67,6 @@ typedef struct dvb_bat_id {
uint32_t freesat:1;
uint32_t bskyb:1;
uint16_t nbid;
uint32_t services_count;
char name[32];
mpegts_mux_t *mm;
TAILQ_HEAD(,dvb_bat_svc) services;
Expand Down Expand Up @@ -379,7 +381,8 @@ dvb_desc_service
}

static dvb_bat_svc_t *
dvb_bat_find_service( dvb_bat_id_t *bi, mpegts_service_t *s, uint32_t lcn )
dvb_bat_find_service( dvb_bat_id_t *bi, mpegts_service_t *s,
uint8_t lcn_dtag, uint32_t lcn )
{
dvb_bat_svc_t *bs;

Expand All @@ -391,8 +394,10 @@ dvb_bat_find_service( dvb_bat_id_t *bi, mpegts_service_t *s, uint32_t lcn )
bs->svc = s;
TAILQ_INSERT_TAIL(&bi->services, bs, link);
}
if (lcn != UINT_MAX)
if (lcn != UINT_MAX && !bs->lcn_dtag) {
bs->lcn_dtag = lcn_dtag;
bs->lcn = lcn;
}
return bs;
}

Expand All @@ -409,13 +414,11 @@ dvb_desc_service_list
sid = (ptr[i] << 8) | ptr[i+1];
stype = ptr[i+2];
tvhdebug(dstr, " service %04X (%d) type %02X (%d)", sid, sid, stype, stype);
if (bi)
bi->services_count++;
if (mm) {
int save = 0;
s = mpegts_service_find(mm, sid, 0, 1, &save);
if (bi)
dvb_bat_find_service(bi, s, UINT_MAX);
dvb_bat_find_service(bi, s, 0, UINT_MAX);
if (save)
s->s_config_save((service_t*)s);
}
Expand All @@ -425,8 +428,8 @@ dvb_desc_service_list

static int
dvb_desc_local_channel
( const char *dstr, const uint8_t *ptr, int len, mpegts_mux_t *mm,
dvb_bat_id_t *bi )
( const char *dstr, const uint8_t *ptr, int len,
uint8_t dtag, mpegts_mux_t *mm, dvb_bat_id_t *bi )
{
int save = 0;
uint16_t sid, lcn;
Expand All @@ -439,12 +442,15 @@ dvb_desc_local_channel
sid = (ptr[0] << 8) | ptr[1];
lcn = ((ptr[2] & 3) << 8) | ptr[3];
tvhdebug(dstr, " sid %d lcn %d", sid, lcn);
if (lcn && mm) {
if (sid && lcn && mm) {
s = mpegts_service_find(mm, sid, 0, 0, &save);
if (s) {
if (bi) {
dvb_bat_find_service(bi, s, lcn);
} else if (s->s_dvb_channel_num != lcn) {
dvb_bat_find_service(bi, s, dtag, lcn);
} else if ((!s->s_dvb_channel_dtag ||
s->s_dvb_channel_dtag == dtag) &&
s->s_dvb_channel_num != lcn) {
s->s_dvb_channel_dtag = dtag;
s->s_dvb_channel_num = lcn;
s->s_config_save((service_t*)s);
service_refresh_channel((service_t*)s);
Expand Down Expand Up @@ -1189,6 +1195,7 @@ dvb_bat_completed
{
dvb_bat_id_t *bi;
dvb_bat_svc_t *bs;
uint32_t services_count;
bouquet_t *bq;

b->complete = 1;
Expand Down Expand Up @@ -1236,13 +1243,15 @@ dvb_bat_completed

dvb_bouquet_comment(bq, bi->mm);

if (bq->bq_enabled) {
TAILQ_FOREACH(bs, &bi->services, link)
services_count = 0;
TAILQ_FOREACH(bs, &bi->services, link) {
services_count++;
if (bq->bq_enabled)
bouquet_add_service(bq, (service_t *)bs->svc,
(int64_t)bs->lcn * CHANNEL_SPLIT, 0);
}

bouquet_completed(bq, bi->services_count);
bouquet_completed(bq, services_count);

complete:
bi->complete = 1;
Expand All @@ -1256,7 +1265,7 @@ dvb_nit_callback
int save = 0;
int r, sect, last, ver;
#if ENABLE_MPEGTS_DVB
int fsat = 0, p02 = 0;
uint32_t priv = 0;
#endif
uint8_t dtag;
int llen, dllen, dlen;
Expand Down Expand Up @@ -1353,16 +1362,14 @@ dvb_nit_callback
case DVB_DESC_PRIVATE_DATA:
#if ENABLE_MPEGTS_DVB
if (tableid == 0x4A && dlen == 4) {
if (!memcmp(dptr, "FSAT", 4))
fsat = 1;
else if (!memcmp(dptr, "\x00\x00\x00\x02", 4))
p02 = 1;
priv = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
tvhtrace(mt->mt_name, " private %08X", priv);
}
#endif
break;
case DVB_DESC_FREESAT_REGIONS:
#if ENABLE_MPEGTS_DVB
if (fsat)
if (priv == PRIV_FSAT)
dvb_freesat_regions(bi, mt->mt_name, dptr, dlen);
#endif
break;
Expand Down Expand Up @@ -1392,6 +1399,7 @@ dvb_nit_callback
}

/* Transport length */
priv = 0;
DVB_LOOP_FOREACH(ptr, len, 0, lptr, llen, 6) {
tsid = (lptr[0] << 8) | lptr[1];
onid = (lptr[2] << 8) | lptr[3];
Expand Down Expand Up @@ -1455,34 +1463,44 @@ dvb_nit_callback
if (mux && *dauth)
mpegts_mux_set_crid_authority(mux, dauth);
break;
case DVB_DESC_LOCAL_CHAN1:
case DVB_DESC_LOCAL_CHAN2:
if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, mux, bi))
return -1;
break;
case DVB_DESC_SERVICE_LIST:
if (dvb_desc_service_list(mt->mt_name, dptr, dlen, mux, bi))
return -1;
break;
case DVB_DESC_PRIVATE_DATA:
#if ENABLE_MPEGTS_DVB
if (dlen == 4 && !memcmp(dptr, "FSAT", 4))
fsat = 1;
else if (!memcmp(dptr, "\x00\x00\x00\x02", 4))
p02 = 1;
if (dlen == 4) {
priv = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
tvhtrace(mt->mt_name, " private %08X", priv);
}
#endif
break;
case 0x81:
if (priv == 0) goto lcn;
case 0x82:
if (priv == 0) goto lcn;
case 0x83:
if (priv == 0 || priv == 0x28 || priv == 0xa5) goto lcn;
case 0x86:
if (priv == 0) goto lcn;
case 0x93:
if (priv == 0 || priv == 0x362275)
/* fall thru */
lcn:
if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, dtag, mux, bi))
return -1;
break;
case DVB_DESC_FREESAT_LCN:
#if ENABLE_MPEGTS_DVB
if (tableid == 0x4A && fsat) {
if (tableid == 0x4A && priv == PRIV_FSAT) {
dvb_freesat_local_channels(bi, mt->mt_name, dptr, dlen);
bi->freesat = 1;
}
#endif
break;
case DVB_DESC_BSKYB_LCN:
#if ENABLE_MPEGTS_DVB
if (tableid == 0x4A && p02) {
if (tableid == 0x4A && priv == 2) {
dvb_bskyb_local_channels(bi, mt->mt_name, dptr, dlen, mux);
bi->bskyb = 1;
}
Expand Down

2 comments on commit d0a6684

@herrnst
Copy link
Contributor

Choose a reason for hiding this comment

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

This commit causes LCN's to be all zero on DVB-C UnitymediaKabelBW Germany cable provider when rescanning all services (e.g. after a clean install or when readding all muxes to get a clean channels list after some channel shuffling by the provider). Was about to upgrade my install from GIT rev 4bce3dc up to master, and readding all channels yielded in all channel numbers to be zero, instead of the providers numbering. A bisect resulted in this commit (which looks obvious by tampering with the LCN stuff) to break it, going back one revision to 898f88a brings LCNs back.

@herrnst
Copy link
Contributor

Choose a reason for hiding this comment

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

Please sign in to comment.