From ae95ede1654d71f70b3594ca14c5ed2a3a2dac98 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 7 Nov 2014 15:08:36 +0100 Subject: [PATCH] bouquet: improve the LCN handling for fastscan and dvb bouquets --- src/bouquet.h | 1 - src/input/mpegts/dvb.h | 4 +- src/input/mpegts/dvb_psi.c | 89 ++++++++++++++++++++------------------ 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/bouquet.h b/src/bouquet.h index bf37c192..5c1713b9 100644 --- a/src/bouquet.h +++ b/src/bouquet.h @@ -50,7 +50,6 @@ typedef struct bouquet { idnode_set_t *bq_active_services; htsmsg_t *bq_services_waiting; uint32_t bq_services_seen; - uint32_t bq_services_tmp; /* for fastscan tables */ uint32_t bq_lcn_offset; uint64_t bq_last_lcn; diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index fcc5c0f2..c994fae0 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -129,7 +129,9 @@ struct mpegts_mux; #define DVB_DESC_CRID 0x76 #define DVB_DESC_EAC3 0x7A #define DVB_DESC_AAC 0x7C -#define DVB_DESC_LOCAL_CHAN 0x83 + +#define DVB_DESC_LOCAL_CHAN1 0x81 /* UPC - 1W */ +#define DVB_DESC_LOCAL_CHAN2 0x83 #define DVB_DESC_BSKYB_LCN 0xB1 diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 27a694c7..07662cc9 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -53,6 +53,7 @@ typedef struct dvb_freesat_region { typedef struct dvb_bat_svc { TAILQ_ENTRY(dvb_bat_svc) link; mpegts_service_t *svc; + uint32_t lcn; dvb_freesat_svc_t *fallback; } dvb_bat_svc_t; @@ -376,15 +377,33 @@ dvb_desc_service return 0; } +static dvb_bat_svc_t * +dvb_bat_find_service( dvb_bat_id_t *bi, mpegts_service_t *s, uint32_t lcn ) +{ + dvb_bat_svc_t *bs; + + TAILQ_FOREACH(bs, &bi->services, link) + if (bs->svc == s) + break; + if (!bs) { + bs = calloc(1, sizeof(*bs)); + bs->svc = s; + TAILQ_INSERT_TAIL(&bi->services, bs, link); + } + if (lcn != UINT_MAX) + bs->lcn = lcn; + return bs; +} + static int dvb_desc_service_list ( const char *dstr, const uint8_t *ptr, int len, mpegts_mux_t *mm, - dvb_bat_id_t *bi, bouquet_t *bq ) + dvb_bat_id_t *bi ) { uint16_t stype, sid; - int i; - dvb_bat_svc_t *bs; mpegts_service_t *s; + int i; + for (i = 0; i < len; i += 3) { sid = (ptr[i] << 8) | ptr[i+1]; stype = ptr[i+2]; @@ -394,13 +413,8 @@ dvb_desc_service_list if (mm) { int save = 0; s = mpegts_service_find(mm, sid, 0, 1, &save); - if (bi) { - bs = calloc(1, sizeof(*bs)); - bs->svc = s; - TAILQ_INSERT_TAIL(&bi->services, bs, link); - } else if (bq) { - bouquet_add_service(bq, (service_t *)s, 0, 0); - } + if (bi) + dvb_bat_find_service(bi, s, UINT_MAX); if (save) s->s_config_save((service_t*)s); } @@ -410,19 +424,26 @@ dvb_desc_service_list static int dvb_desc_local_channel - ( const char *dstr, const uint8_t *ptr, int len, mpegts_mux_t *mm ) + ( const char *dstr, const uint8_t *ptr, int len, mpegts_mux_t *mm, + dvb_bat_id_t *bi ) { int save = 0; uint16_t sid, lcn; + mpegts_service_t *s; + + if ((len % 4) != 0) + return 0; while(len >= 4) { sid = (ptr[0] << 8) | ptr[1]; lcn = ((ptr[2] & 3) << 8) | ptr[3]; tvhdebug(dstr, " sid %d lcn %d", sid, lcn); if (lcn && mm) { - mpegts_service_t *s = mpegts_service_find(mm, sid, 0, 0, &save); + s = mpegts_service_find(mm, sid, 0, 0, &save); if (s) { - if (s->s_dvb_channel_num != lcn) { + if (bi) { + dvb_bat_find_service(bi, s, lcn); + } else if (s->s_dvb_channel_num != lcn) { s->s_dvb_channel_num = lcn; s->s_config_save((service_t*)s); service_refresh_channel((service_t*)s); @@ -1130,7 +1151,8 @@ dvb_bat_destroy( mpegts_table_t *mt ) static void dvb_bat_completed - ( dvb_bat_t *b, const char *dstr, int tableid, int tsid, int nbid, mpegts_mux_t *mux ) + ( dvb_bat_t *b, const char *dstr, int tableid, int tsid, int nbid, + mpegts_mux_t *mux, bouquet_t *bq_alt ) { dvb_bat_id_t *bi; dvb_bat_svc_t *bs; @@ -1170,6 +1192,8 @@ dvb_bat_completed } if (src[0]) bq = bouquet_find_by_source(bi->name, src, !TAILQ_EMPTY(&bi->services)); + } else if (tableid == DVB_FASTSCAN_NIT_BASE) { + bq = bq_alt; } #endif @@ -1178,7 +1202,7 @@ dvb_bat_completed dvb_bouquet_comment(bq, bi->mm); TAILQ_FOREACH(bs, &bi->services, link) - bouquet_add_service(bq, (service_t *)bs->svc, 0, 0); + bouquet_add_service(bq, (service_t *)bs->svc, bs->lcn, 0); bouquet_completed(bq, bi->services_count); @@ -1216,10 +1240,11 @@ dvb_nit_callback r = dvb_table_begin(mt, ptr, len, tableid, nbid, 7, &st, §, &last, &ver); if (r == 0) { - if (tableid == 0x4A) { + if (tableid == 0x4A || tableid == DVB_FASTSCAN_NIT_BASE) { if ((b = mt->mt_bat) != NULL) { if (!b->complete) { - dvb_bat_completed(b, mt->mt_name, tableid, mm->mm_tsid, nbid, mm); + dvb_bat_completed(b, mt->mt_name, tableid, mm->mm_tsid, nbid, + mm, mt->mt_opaque); mt->mt_working -= st->working; st->working = 0; } @@ -1246,7 +1271,7 @@ dvb_nit_callback } /* BAT ID lookup */ - if (tableid == 0x4A) { + if (tableid == 0x4A || tableid == DVB_FASTSCAN_NIT_BASE) { if ((b = mt->mt_bat) == NULL) { b = calloc(1, sizeof(*b)); mt->mt_bat = b; @@ -1385,12 +1410,13 @@ dvb_nit_callback if (mux && *dauth) mpegts_mux_set_crid_authority(mux, dauth); break; - case DVB_DESC_LOCAL_CHAN: - if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, mux)) + 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, bq)) + if (dvb_desc_service_list(mt->mt_name, dptr, dlen, mux, bi)) return -1; break; case DVB_DESC_PRIVATE_DATA: @@ -1415,9 +1441,6 @@ dvb_nit_callback } } - if (bq && bq->bq_saveflag) - bouquet_save(bq, 1); - /* End */ return dvb_table_end(mt, st, sect); } @@ -1693,7 +1716,6 @@ dvb_fs_sdt_callback mpegts_mux_t *mm = mt->mt_mux, *mux; mpegts_network_t *mn = mm->mm_network; mpegts_table_state_t *st = NULL; - bouquet_t *bq = mt->mt_opaque; /* Fastscan ID */ nbid = (ptr[0] << 8) | ptr[1]; @@ -1705,7 +1727,6 @@ dvb_fs_sdt_callback if (r == 0) { mt->mt_working -= st->working; st->working = 0; - bouquet_completed(bq, bq->bq_services_tmp); } if (r != 1) return r; if (len < 5) return -1; @@ -1746,26 +1767,16 @@ dvb_fs_sdt_callback /* Find service */ s = mpegts_service_find(mux, service_id, 0, 1, &save); charset = dvb_charset_find(mn, mux, s); - if (bq && s) { - bouquet_add_service(bq, (service_t *)s, 0, 0); - } else { - tvhtrace(mt->mt_name, " service not found (bq %p, svc %p)", bq, s); - } /* Descriptor loop */ DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) { tvhtrace(mt->mt_name, " dtag %02X dlen %d", dtag, dlen); switch (dtag) { case DVB_DESC_SERVICE: - bq->bq_services_tmp++; if (dvb_desc_service(dptr, dlen, &stype, sprov, sizeof(sprov), sname, sizeof(sname), charset)) return -1; break; - case DVB_DESC_LOCAL_CHAN: - if (dvb_desc_local_channel(mt->mt_name, dptr, dlen, mux)) - return -1; - break; case DVB_DESC_SAT_DEL: mux = dvb_desc_sat_del(mm, onid, tsid, dptr, dlen); if (mux) { @@ -1827,9 +1838,6 @@ dvb_fs_sdt_callback } } - if (bq && bq->bq_saveflag) - bouquet_save(bq, 1); - /* End */ return dvb_table_end(mt, st, sect); } @@ -2329,11 +2337,10 @@ static void psi_tables_dvb_fastscan( void *aux, bouquet_t *bq, const char *name, int pid ) { tvhtrace("fastscan", "adding table %04X (%i) for '%s'", pid, pid, name); - bq->bq_services_tmp = 0; mpegts_table_add(aux, DVB_FASTSCAN_NIT_BASE, DVB_FASTSCAN_MASK, dvb_nit_callback, bq, "fs_nit", MT_CRC, pid); mpegts_table_add(aux, DVB_FASTSCAN_SDT_BASE, DVB_FASTSCAN_MASK, - dvb_fs_sdt_callback, bq, "fs_sdt", MT_CRC, pid); + dvb_fs_sdt_callback, NULL, "fs_sdt", MT_CRC, pid); } #endif