Added support for processing default authority (CRID) and modded table code to have a full PID x11 callback. Hooked into existing usage in EIT code.
This commit is contained in:
parent
d7eaac92dc
commit
692349682d
7 changed files with 234 additions and 78 deletions
|
@ -134,6 +134,8 @@ typedef struct th_dvb_mux_instance {
|
|||
char *tdmi_identifier;
|
||||
char *tdmi_network; /* Name of network, from NIT table */
|
||||
|
||||
char *tdmi_default_authority;
|
||||
|
||||
struct service_list tdmi_transports; /* via s_mux_link */
|
||||
|
||||
TAILQ_ENTRY(th_dvb_mux_instance) tdmi_scan_link;
|
||||
|
@ -436,6 +438,10 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams,
|
|||
uint8_t tableid, void *opaque), void *opaque,
|
||||
const char *name, int flags, int pid, th_dvb_table_t *tdt);
|
||||
|
||||
int dvb_pidx11_callback
|
||||
(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque);
|
||||
|
||||
#define TDT_CRC 0x1
|
||||
#define TDT_QUICKREQ 0x2
|
||||
#define TDT_CA 0x4
|
||||
|
|
|
@ -560,6 +560,9 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi)
|
|||
|
||||
htsmsg_add_u32(m, "initialscan", tdmi->tdmi_table_initial);
|
||||
|
||||
if(tdmi->tdmi_default_authority)
|
||||
htsmsg_add_str(m, "default_authority", tdmi->tdmi_default_authority);
|
||||
|
||||
switch(tdmi->tdmi_adapter->tda_type) {
|
||||
case FE_OFDM:
|
||||
htsmsg_add_str(m, "bandwidth",
|
||||
|
@ -779,6 +782,9 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
|||
|
||||
if(tda->tda_qmon && !htsmsg_get_u32(m, "quality", &u32))
|
||||
tdmi->tdmi_quality = u32;
|
||||
|
||||
if((s = htsmsg_get_str(m, "default_authority")))
|
||||
tdmi->tdmi_default_authority = strdup(s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define DVB_DESC_TELETEXT 0x56
|
||||
#define DVB_DESC_SUBTITLE 0x59
|
||||
#define DVB_DESC_AC3 0x6a
|
||||
#define DVB_DESC_DEF_AUTHORITY 0x73
|
||||
#define DVB_DESC_CRID 0x76
|
||||
#define DVB_DESC_EAC3 0x7a
|
||||
#define DVB_DESC_AAC 0x7c
|
||||
|
|
|
@ -348,12 +348,96 @@ dvb_desc_service(uint8_t *ptr, int len, uint8_t *typep,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DVB Descriptor: Default authority
|
||||
*/
|
||||
static int
|
||||
dvb_desc_def_authority(uint8_t *ptr, int len, char *defauth, size_t dalen)
|
||||
{
|
||||
int r;
|
||||
if ((r = dvb_get_string(defauth, dalen, ptr, len, NULL, NULL)) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvb_bat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
int i, j, bdlen, tslen, tdlen;
|
||||
uint8_t dtag, dlen;
|
||||
uint16_t tsid;
|
||||
char crid[257];
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
|
||||
if (tableid != 0x4a) return -1;
|
||||
bdlen = ((buf[5] & 0xf) << 8) | buf[6];
|
||||
if (bdlen+7 > len) return -1;
|
||||
buf += 7;
|
||||
len -= 7;
|
||||
|
||||
/* Bouquet Desc */
|
||||
i = 0;
|
||||
// TODO: parse top level descriptors?
|
||||
buf += bdlen;
|
||||
len -= bdlen;
|
||||
|
||||
tslen = ((buf[0] & 0xf) << 8) | buf[1];
|
||||
if (tslen+2 > len) return -1;
|
||||
buf += 2;
|
||||
len -= 2;
|
||||
|
||||
/* Transport Loop */
|
||||
i = 0;
|
||||
while (i+6 < tslen) {
|
||||
tsid = buf[i] << 8 | buf[i+1];
|
||||
tdlen = ((buf[i+4] & 0xf) << 8) | buf[i+5];
|
||||
if (tdlen+i+6 > tslen) break;
|
||||
i += 6;
|
||||
j = 0;
|
||||
|
||||
/* Find TDMI */
|
||||
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
|
||||
if(tdmi->tdmi_transport_stream_id == tsid)
|
||||
break;
|
||||
|
||||
/* Descriptors */
|
||||
if (tdmi) {
|
||||
int save = 0;
|
||||
*crid = 0;
|
||||
while (j+2 < tdlen) {
|
||||
dtag = buf[i+j];
|
||||
dlen = buf[i+j+1];
|
||||
if (dlen+j+2 > tdlen) break;
|
||||
j += 2;
|
||||
switch (dtag) {
|
||||
case DVB_DESC_DEF_AUTHORITY:
|
||||
dvb_desc_def_authority(buf+i+j, dlen, crid, sizeof(crid));
|
||||
break;
|
||||
}
|
||||
j += dlen;
|
||||
}
|
||||
if (*crid && strcmp(tdmi->tdmi_default_authority ?: "", crid)) {
|
||||
free(tdmi->tdmi_default_authority);
|
||||
tdmi->tdmi_default_authority = strdup(crid);
|
||||
save = 1;
|
||||
}
|
||||
if (save)
|
||||
dvb_mux_save(tdmi);
|
||||
}
|
||||
|
||||
i += tdlen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DVB SDT (Service Description Table)
|
||||
*/
|
||||
static int
|
||||
dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
service_t *t;
|
||||
uint16_t service_id;
|
||||
|
@ -362,18 +446,28 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
int dllen;
|
||||
uint8_t dtag, dlen;
|
||||
|
||||
char crid[257];
|
||||
char provider[256];
|
||||
char chname0[256], *chname;
|
||||
uint8_t stype;
|
||||
int l;
|
||||
|
||||
if(len < 8)
|
||||
return -1;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
|
||||
if (tableid != 0x42 || tableid != 0x46) return -1;
|
||||
|
||||
if(len < 8) return -1;
|
||||
|
||||
transport_stream_id = ptr[0] << 8 | ptr[1];
|
||||
|
||||
if(tdmi->tdmi_transport_stream_id != transport_stream_id)
|
||||
return -1;
|
||||
if (tableid == 0x42) {
|
||||
if(tdmi->tdmi_transport_stream_id != transport_stream_id)
|
||||
return -1;
|
||||
} else {
|
||||
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
|
||||
if(tdmi->tdmi_transport_stream_id == transport_stream_id)
|
||||
break;
|
||||
if (!tdmi) return 0;
|
||||
}
|
||||
|
||||
// version = ptr[2] >> 1 & 0x1f;
|
||||
// section_number = ptr[3];
|
||||
|
@ -391,6 +485,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
|
||||
|
||||
while(len >= 5) {
|
||||
int save = 0;
|
||||
service_id = ptr[0] << 8 | ptr[1];
|
||||
// reserved = ptr[2];
|
||||
// running_status = (ptr[3] >> 5) & 0x7;
|
||||
|
@ -403,9 +498,15 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
if(dllen > len)
|
||||
break;
|
||||
|
||||
stype = 0;
|
||||
if (!(t = dvb_transport_find(tdmi, service_id, 0, NULL))) {
|
||||
len -= dllen;
|
||||
ptr += dllen;
|
||||
continue;
|
||||
}
|
||||
|
||||
stype = 0;
|
||||
chname = NULL;
|
||||
*crid = 0;
|
||||
|
||||
while(dllen > 2) {
|
||||
dtag = ptr[0];
|
||||
|
@ -413,66 +514,87 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
|
||||
len -= 2; ptr += 2; dllen -= 2;
|
||||
|
||||
if(dlen > len)
|
||||
break;
|
||||
if(dlen > len) break;
|
||||
|
||||
switch(dtag) {
|
||||
case DVB_DESC_SERVICE:
|
||||
if(dvb_desc_service(ptr, dlen, &stype,
|
||||
provider, sizeof(provider),
|
||||
chname0, sizeof(chname0)) == 0) {
|
||||
chname = chname0;
|
||||
/* Some providers insert spaces.
|
||||
Clean up that (both heading and trailing) */
|
||||
while(*chname <= 32 && *chname != 0)
|
||||
chname++;
|
||||
case DVB_DESC_SERVICE:
|
||||
if(dvb_desc_service(ptr, dlen, &stype,
|
||||
provider, sizeof(provider),
|
||||
chname0, sizeof(chname0)) == 0) {
|
||||
chname = chname0;
|
||||
/* Some providers insert spaces.
|
||||
Clean up that (both heading and trailing) */
|
||||
while(*chname <= 32 && *chname != 0)
|
||||
chname++;
|
||||
|
||||
l = strlen(chname);
|
||||
while(l > 1 && chname[l - 1] <= 32) {
|
||||
chname[l - 1] = 0;
|
||||
l--;
|
||||
}
|
||||
l = strlen(chname);
|
||||
while(l > 1 && chname[l - 1] <= 32) {
|
||||
chname[l - 1] = 0;
|
||||
l--;
|
||||
}
|
||||
|
||||
if(l == 0) {
|
||||
chname = chname0;
|
||||
snprintf(chname0, sizeof(chname0), "noname-sid-0x%x", service_id);
|
||||
}
|
||||
|
||||
t = dvb_transport_find(tdmi, service_id, 0, NULL);
|
||||
if(t == NULL)
|
||||
break;
|
||||
|
||||
if(t->s_servicetype != stype ||
|
||||
t->s_scrambled != free_ca_mode ||
|
||||
strcmp(t->s_provider ?: "", provider) ||
|
||||
strcmp(t->s_svcname ?: "", chname)) {
|
||||
|
||||
t->s_servicetype = stype;
|
||||
t->s_scrambled = free_ca_mode;
|
||||
|
||||
free(t->s_provider);
|
||||
t->s_provider = strdup(provider);
|
||||
|
||||
free(t->s_svcname);
|
||||
t->s_svcname = strdup(chname);
|
||||
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
service_make_nicename(t);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
t->s_config_save(t);
|
||||
service_refresh_channel(t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(l == 0) {
|
||||
chname = chname0;
|
||||
snprintf(chname0, sizeof(chname0), "noname-sid-0x%x", service_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DVB_DESC_DEF_AUTHORITY:
|
||||
dvb_desc_def_authority(ptr, dlen, crid, sizeof(crid));
|
||||
break;
|
||||
}
|
||||
|
||||
len -= dlen; ptr += dlen; dllen -= dlen;
|
||||
}
|
||||
|
||||
if(t->s_servicetype != stype ||
|
||||
t->s_scrambled != free_ca_mode) {
|
||||
t->s_servicetype = stype;
|
||||
t->s_scrambled = free_ca_mode;
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (chname && (strcmp(t->s_provider ?: "", provider) ||
|
||||
strcmp(t->s_svcname ?: "", chname))) {
|
||||
free(t->s_provider);
|
||||
t->s_provider = strdup(provider);
|
||||
|
||||
free(t->s_svcname);
|
||||
t->s_svcname = strdup(chname);
|
||||
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
service_make_nicename(t);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (*crid && strcmp(t->s_default_authority ?: "", crid)) {
|
||||
free(t->s_default_authority);
|
||||
t->s_default_authority = strdup(crid);
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
t->s_config_save(t);
|
||||
service_refresh_channel(t);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Combined PID 0x11 callback, for stuff commonly found on that PID
|
||||
*/
|
||||
int dvb_pidx11_callback
|
||||
(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
if (tableid == 0x42 || tableid == 0x46)
|
||||
return dvb_sdt_callback(tdmi, ptr, len, tableid, opaque);
|
||||
else if (tableid == 0x4a)
|
||||
return dvb_bat_callback(tdmi, ptr, len, tableid, opaque);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* PAT - Program Allocation table
|
||||
|
@ -1025,18 +1147,9 @@ dvb_table_add_default_dvb(th_dvb_mux_instance_t *tdmi)
|
|||
tdt_add(tdmi, fp, dvb_nit_callback, NULL, "nit",
|
||||
TDT_QUICKREQ | TDT_CRC, 0x10, NULL);
|
||||
|
||||
/* Service Descriptor Table */
|
||||
/* Service Descriptor Table and Bouqeut Allocation Table */
|
||||
|
||||
fp = dvb_fparams_alloc();
|
||||
fp->filter.filter[0] = 0x42;
|
||||
// Note: DishNet (EchoStar) send SDT on 0x46 rather than 0x42
|
||||
if (tdmi->tdmi_network != NULL) {
|
||||
if(strstr(tdmi->tdmi_network,"EchoStar")!=NULL) {
|
||||
fp->filter.filter[0] = 0x46;
|
||||
}
|
||||
}
|
||||
fp->filter.mask[0] = 0xff;
|
||||
tdt_add(tdmi, fp, dvb_sdt_callback, NULL, "sdt",
|
||||
tdt_add(tdmi, NULL, dvb_pidx11_callback, NULL, "pidx11",
|
||||
TDT_QUICKREQ | TDT_CRC, 0x11, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -240,6 +240,9 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi)
|
|||
s = htsmsg_get_str(c, "dvb_default_charset");
|
||||
t->s_dvb_default_charset = s ? strdup(s) : NULL;
|
||||
|
||||
s = htsmsg_get_str(c, "default_authority");
|
||||
t->s_default_authority = s ? strdup(s) : NULL;
|
||||
|
||||
if(htsmsg_get_u32(c, "dvb_eit_enable", &u32))
|
||||
u32 = 1;
|
||||
t->s_dvb_eit_enable = u32;
|
||||
|
@ -286,6 +289,9 @@ dvb_transport_save(service_t *t)
|
|||
|
||||
htsmsg_add_u32(m, "dvb_eit_enable", t->s_dvb_eit_enable);
|
||||
|
||||
if(t->s_default_authority)
|
||||
htsmsg_add_str(m, "default_authority", t->s_default_authority);
|
||||
|
||||
pthread_mutex_lock(&t->s_stream_mutex);
|
||||
psi_save_service_settings(m, t);
|
||||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
|
|
|
@ -357,34 +357,51 @@ static int _eit_desc_content
|
|||
* Content ID
|
||||
*/
|
||||
static int _eit_desc_crid
|
||||
( epggrab_module_t *mod, uint8_t *ptr, int len, eit_event_t *ev )
|
||||
( epggrab_module_t *mod, uint8_t *ptr, int len, eit_event_t *ev, service_t *svc )
|
||||
{
|
||||
int r;
|
||||
uint8_t type;
|
||||
char buf[257], *crid;
|
||||
int clen;
|
||||
|
||||
while (len > 3) {
|
||||
|
||||
/* Explicit only */
|
||||
if ( (*ptr & 0x3) == 0 ) {
|
||||
crid = NULL;
|
||||
type = *ptr >> 2;
|
||||
|
||||
r = _eit_get_string_with_len(mod, buf, sizeof(buf),
|
||||
ptr+1, len-1,
|
||||
ev->default_charset);
|
||||
if (r < 0) return -1;
|
||||
|
||||
/* Episode */
|
||||
if (type == 0x1 || type == 0x31) {
|
||||
r = _eit_get_string_with_len(mod, ev->uri, sizeof(ev->uri),
|
||||
ptr+1, len-1, ev->default_charset);
|
||||
crid = ev->uri;
|
||||
clen = sizeof(ev->uri);
|
||||
|
||||
/* Season */
|
||||
} else if (type == 0x2 || type == 0x32) {
|
||||
r = _eit_get_string_with_len(mod, ev->suri, sizeof(ev->suri),
|
||||
ptr+1, len-1, ev->default_charset);
|
||||
|
||||
/* Unknown */
|
||||
} else {
|
||||
r = ptr[1] + 1;
|
||||
crid = ev->suri;
|
||||
clen = sizeof(ev->suri);
|
||||
}
|
||||
|
||||
if (crid) {
|
||||
if (strstr(buf, "crid://") == buf) {
|
||||
strncpy(crid, buf, clen);
|
||||
} else if ( *buf != '/' ) {
|
||||
snprintf(crid, clen, "crid://%s", buf);
|
||||
} else {
|
||||
char *defauth = svc->s_default_authority;
|
||||
if (!defauth)
|
||||
defauth = svc->s_dvb_mux_instance->tdmi_default_authority;
|
||||
if (defauth)
|
||||
snprintf(crid, clen, "crid://%s%s", defauth, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Next */
|
||||
if (r < 0) return -1;
|
||||
len -= 1 + r;
|
||||
ptr += 1 + r;
|
||||
}
|
||||
|
@ -471,7 +488,7 @@ static int _eit_process_event
|
|||
break;
|
||||
#endif
|
||||
case DVB_DESC_CRID:
|
||||
r = _eit_desc_crid(mod, ptr, dlen, &ev);
|
||||
r = _eit_desc_crid(mod, ptr, dlen, &ev, svc);
|
||||
break;
|
||||
default:
|
||||
r = 0;
|
||||
|
@ -684,8 +701,10 @@ static void _eit_start
|
|||
/* Add PIDs (freesat uses non-standard) */
|
||||
if (!strcmp("uk_freesat", m->id)) {
|
||||
#ifdef IGNORE_TOO_SLOW
|
||||
tdt_add(tdmi, NULL, dvb_pidx11_callback, m, m->id, TDT_CRC, 3840, NULL);
|
||||
tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 3841, NULL);
|
||||
#endif
|
||||
tdt_add(tdmi, NULL, dvb_pidx11_callback, m, m->id, TDT_CRC, 3002, NULL);
|
||||
tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 3003, NULL);
|
||||
} else {
|
||||
tdt_add(tdmi, NULL, _eit_callback, m, m->id, TDT_CRC, 0x12, NULL);
|
||||
|
|
|
@ -310,6 +310,11 @@ typedef struct service {
|
|||
*/
|
||||
char *s_provider;
|
||||
|
||||
/**
|
||||
* Default authority
|
||||
*/
|
||||
char *s_default_authority;
|
||||
|
||||
enum {
|
||||
/* Service types defined in EN 300 468 */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue