mpegts: add ability to override the charset used with the PSI code

This is now possible at 4 levels:

1. The global defaults (for known bad muxes)
2. The network
3. The mux
4. The service

Such that 4 overrides 3, overrides 2, etc...
This commit is contained in:
Adam Sutton 2013-10-14 09:31:46 +01:00
parent febd529cf7
commit 06b042e0b3
10 changed files with 168 additions and 86 deletions

View file

@ -2,91 +2,91 @@
{
"tsid": 1,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 12070.50 H"
},
{
"tsid": 2,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11797.50 H"
},
{
"tsid": 3,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11719.50 H"
},
{
"tsid": 4,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 12031.50 H"
},
{
"tsid": 6,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11914.50 H"
},
{
"tsid": 10,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11332.25 H"
},
{
"tsid": 11,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 12382.50 H"
},
{
"tsid": 12,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 12304.50 H"
},
{
"tsid": 13,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11992.50 H"
},
{
"tsid": 14,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11875.50 H"
},
{
"tsid": 15,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 10920.75 H"
},
{
"tsid": 17,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 11758.50 H"
},
{
"tsid": 33,
"onid": 133,
"charset": "ISO8859-15",
"charset": "ISO-8859-15",
"sid": 0,
"description": "Astra 19.2E Sky Germany 12480.00 V"
},
@ -107,14 +107,14 @@
{
"tsid": 3218,
"onid": 3,
"charset": "ISO8859-5",
"charset": "ISO-8859-5",
"sid": 0,
"description": "Astra 23.5E Satellite BG 12051.00 V"
},
{
"tsid": 3226,
"onid": 3,
"charset": "ISO8859-5",
"charset": "ISO-8859-5",
"sid": 0,
"description": "Astra 23.5E Satellite BG 12207.00 V"
},
@ -135,7 +135,7 @@
{
"tsid": 200,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 13805,
"description": "Hotbird 13.0 Eutelsat Eurosport GR"
},
@ -149,7 +149,7 @@
{
"tsid": 200,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 13840,
"description": "Hotbird 13.0 Eutelsat Eurosport GR"
},
@ -310,28 +310,28 @@
{
"tsid": 5500,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 0,
"description": "Hotbird 13.0 Nova GR"
},
{
"tsid": 6100,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 0,
"description": "Hotbird 13.0 Nova GR"
},
{
"tsid": 7100,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 0,
"description": "Hotbird 13.0 Nova GR"
},
{
"tsid": 7300,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 0,
"description": "Hotbird 13.0 Nova GR"
},
@ -464,7 +464,7 @@
{
"tsid": 12100,
"onid": 318,
"charset": "ISO8859-7",
"charset": "ISO-8859-7",
"sid": 0,
"description": "Hotbird 13.0 Nova GR"
},
@ -611,224 +611,224 @@
{
"tsid": 1,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 2,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 3,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 4,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 5,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 6,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 7,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 8,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 9,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 10,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 11,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 12,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 13,
"onid": 1,
"charset": "ISO8859-2",
"charset": "ISO-8859-2",
"sid": 0,
"description": "Intelsat/Thor 1W RCS DigiTV"
},
{
"tsid": 20400,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10762.00 V"
},
{
"tsid": 20600,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10803.75 V"
},
{
"tsid": 20700,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10845.00 H"
},
{
"tsid": 20800,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10845.25 V"
},
{
"tsid": 20900,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 108877.00 H"
},
{
"tsid": 21000,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10928.00 H"
},
{
"tsid": 21100,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10887.00 V"
},
{
"tsid": 21200,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 10928.00 V"
},
{
"tsid": 41200,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11455.50 V"
},
{
"tsid": 50100,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11471.00 H"
},
{
"tsid": 50200,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11492.00 V"
},
{
"tsid": 50300,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11673.00 H"
},
{
"tsid": 50400,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11534.00 V"
},
{
"tsid": 50500,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11554.00 H"
},
{
"tsid": 50600,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11575.00 V"
},
{
"tsid": 50700,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11596.00 H"
},
{
"tsid": 50800,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11679.00 H"
},
{
"tsid": 50900,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11513.00 H"
},
{
"tsid": 51000,
"onid": 126,
"charset": "ISO8859-9",
"charset": "ISO-8859-9",
"sid": 0,
"description": "Turksat 7E Digitürk 11617.00 V"
}

View file

@ -434,15 +434,7 @@ static int _eit_process_event
/* Process tags */
memset(&ev, 0, sizeof(ev));
ev.default_charset = svc->s_dvb_charset;
/* Override */
if (!ev.default_charset) {
ev.default_charset
= dvb_charset_find(svc->s_dvb_mux->mm_onid,
svc->s_dvb_mux->mm_tsid,
svc->s_dvb_service_id);
}
ev.default_charset = dvb_charset_find(NULL, NULL, svc);
while (dllen > 2) {
int r;

View file

@ -236,6 +236,7 @@ struct mpegts_network
uint16_t mn_nid;
int mn_autodiscovery;
int mn_skipinitscan;
char *mn_charset;
};
/* Multiplex */
@ -307,6 +308,7 @@ struct mpegts_mux
*/
char *mm_crid_authority;
int mm_enabled;
char *mm_charset;
};
/* Service */

View file

@ -20,8 +20,10 @@
#include "tvheadend.h"
#include "settings.h"
#include "dvb_charset.h"
#include "../mpegts.h"
static LIST_HEAD(,dvb_charset) dvb_charset_list;
/*
* Process a file
*/
@ -80,18 +82,66 @@ void dvb_charset_init ( void )
* Find default charset
*/
const char *dvb_charset_find
( uint16_t onid, uint16_t tsid, uint16_t sid )
( mpegts_network_t *mn, mpegts_mux_t *mm, mpegts_service_t *s )
{
dvb_charset_t *ret = NULL, *enc;
LIST_FOREACH(enc, &dvb_charset_list, link) {
if (onid == enc->onid && tsid == enc->tsid) {
if (sid == enc->sid) {
ret = enc;
break;
} else if (!enc->sid) {
ret = enc;
if (!mm && s) mm = s->s_dvb_mux;
if (!mn && mm) mn = mm->mm_network;
/* User Overrides */
if (s && s->s_dvb_charset && *s->s_dvb_charset)
return s->s_dvb_charset;
if (mm && mm->mm_charset && *mm->mm_charset)
return mm->mm_charset;
if (mn && mn->mn_charset && *mn->mn_charset)
return mn->mn_charset;
/* Global overrides */
if (mm) {
LIST_FOREACH(enc, &dvb_charset_list, link) {
if (mm->mm_onid == enc->onid && mm->mm_tsid == enc->tsid) {
if (s && (s->s_dvb_service_id == enc->sid)) {
ret = enc;
break;
} else if (!enc->sid) {
ret = enc;
}
}
}
}
return ret ? ret->charset : NULL;
}
/*
* List of available charsets
*/
htsmsg_t *
dvb_charset_enum ( void *p )
{
int i;
static const char *charsets[] = {
"AUTO",
"ISO-6937",
"ISO-8859-1",
"ISO-8859-2",
"ISO-8859-3",
"ISO-8859-4",
"ISO-8859-5",
"ISO-8859-6",
"ISO-8859-7",
"ISO-8859-8",
"ISO-8859-9",
"ISO-8859-10",
"ISO-8859-11",
"ISO-8859-12",
"ISO-8859-13",
"ISO-8859-14",
"ISO-8859-15",
"UTF-8",
};
htsmsg_t *m = htsmsg_create_list();
for ( i = 0; i < ARRAY_SIZE(charsets); i++)
htsmsg_add_str(m, NULL, charsets[i]);
return m;
}

View file

@ -29,7 +29,13 @@ typedef struct dvb_charset {
void dvb_charset_init ( void );
struct mpegts_network;
struct mpegts_mux;
struct mpegts_service;
const char *dvb_charset_find
(uint16_t onid, uint16_t tsid, uint16_t sid);
(struct mpegts_network *mn, struct mpegts_mux *mm, struct mpegts_service *s);
htsmsg_t *dvb_charset_enum ( void* );
#endif /* __TVH_DVB_CHARSET_H__ */

View file

@ -23,6 +23,7 @@
#include "parsers.h"
#include "lang_codes.h"
#include "service.h"
#include "dvb_charset.h"
#include <assert.h>
#include <stdio.h>
@ -311,7 +312,7 @@ static int
dvb_desc_service
( const uint8_t *ptr, int len, int *stype,
char *sprov, size_t sprov_len,
char *sname, size_t sname_len )
char *sname, size_t sname_len, const char *charset )
{
int r;
size_t l;
@ -324,11 +325,11 @@ dvb_desc_service
*stype = *ptr++;
/* Provider */
if ((r = dvb_get_string_with_len(sprov, sprov_len, ptr, len, NULL, NULL)) < 0)
if ((r = dvb_get_string_with_len(sprov, sprov_len, ptr, len, charset, NULL)) < 0)
return -1;
/* Name */
if (dvb_get_string_with_len(sname, sname_len, ptr+r, len-r, NULL, NULL) < 0)
if (dvb_get_string_with_len(sname, sname_len, ptr+r, len-r, charset, NULL) < 0)
return -1;
/* Cleanup name */
@ -734,6 +735,7 @@ dvb_nit_callback
mpegts_network_t *mn = mm->mm_network;
char name[256], dauth[256];
mpegts_table_state_t *st = NULL;
const char *charset;
/* Net/Bat ID */
nbid = (ptr[0] << 8) | ptr[1];
@ -758,14 +760,15 @@ dvb_nit_callback
}
/* Network Descriptors */
*name = 0;
*name = 0;
charset = dvb_charset_find(mn, NULL, NULL);
DVB_DESC_FOREACH(ptr, len, 5, lptr, llen, dtag, dlen, dptr) {
tvhtrace(mt->mt_name, " dtag %02X dlen %d", dtag, dlen);
switch (dtag) {
case DVB_DESC_BOUQUET_NAME:
case DVB_DESC_NETWORK_NAME:
if (dvb_get_string(name, sizeof(name), dptr, dlen, NULL, NULL))
if (dvb_get_string(name, sizeof(name), dptr, dlen, charset, NULL))
return -1;
break;
case DVB_DESC_MULTI_NETWORK_NAME:
@ -796,6 +799,7 @@ dvb_nit_callback
LIST_FOREACH(mux, &mn->mn_muxes, mm_network_link)
if (mux->mm_onid == onid && mux->mm_tsid == tsid)
break;
charset = dvb_charset_find(mn, mux, NULL);
DVB_DESC_FOREACH(lptr, llen, 4, dlptr, dllen, dtag, dlen, dptr) {
tvhtrace(mt->mt_name, " dtag %02X dlen %d", dtag, dlen);
@ -834,7 +838,7 @@ dvb_nit_callback
/* Both */
case DVB_DESC_DEF_AUTHORITY:
if (dvb_get_string(dauth, sizeof(dauth), dptr, dlen, NULL, NULL))
if (dvb_get_string(dauth, sizeof(dauth), dptr, dlen, charset, NULL))
return -1;
tvhdebug(mt->mt_name, " default auth [%s]", dauth);
if (mux && *dauth)
@ -869,6 +873,7 @@ dvb_sdt_callback
uint8_t dtag, dlen;
const uint8_t *lptr, *dptr;
mpegts_mux_t *mm = mt->mt_mux;
mpegts_network_t *mn = mm->mm_network;
mpegts_table_state_t *st = NULL;
/* Begin */
@ -887,7 +892,6 @@ dvb_sdt_callback
mpegts_mux_set_onid(mm, onid);
mpegts_mux_set_tsid(mm, tsid);
} else {
mpegts_network_t *mn = mm->mm_network;
LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link)
if (mm->mm_onid == onid && mm->mm_tsid == tsid)
break;
@ -905,6 +909,7 @@ dvb_sdt_callback
int stype = 0;
char sprov[256], sname[256], sauth[256];
int running_status = (ptr[3] >> 5) & 0x7;
const char *charset;
*sprov = *sname = *sauth = 0;
tvhdebug("sdt", " sid %04X (%d) running %d free_ca %d",
service_id, service_id, running_status, free_ca_mode);
@ -913,7 +918,8 @@ dvb_sdt_callback
DVB_LOOP_INIT(ptr, len, 3, lptr, llen);
/* Find service */
s = mpegts_service_find(mm, service_id, 0, 1, &save);
s = mpegts_service_find(mm, service_id, 0, 1, &save);
charset = dvb_charset_find(mn, mm, s);
/* Descriptor loop */
DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) {
@ -921,11 +927,11 @@ dvb_sdt_callback
switch (dtag) {
case DVB_DESC_SERVICE:
if (dvb_desc_service(dptr, dlen, &stype, sprov,
sizeof(sprov), sname, sizeof(sname)))
sizeof(sprov), sname, sizeof(sname), charset))
return -1;
break;
case DVB_DESC_DEF_AUTHORITY:
if (dvb_get_string(sauth, sizeof(sauth), dptr, dlen, NULL, NULL))
if (dvb_get_string(sauth, sizeof(sauth), dptr, dlen, charset, NULL))
return -1;
break;
}

View file

@ -197,7 +197,7 @@ dvb_get_string
(char *dst, size_t dstlen, const uint8_t *src, size_t srclen,
const char *dvb_charset, dvb_string_conv_t *conv)
{
int ic;
int ic = -1;
size_t len, outlen;
int i, auto_pl_charset = 0;
@ -262,10 +262,14 @@ dvb_get_string
// manual charset override
if (dvb_charset != NULL && dvb_charset[0] != 0) {
if (sscanf(dvb_charset, "ISO8859-%d", &i) > 0 && i > 0 && i < 16) {
if (!strcmp(dvb_charset, "AUTO")) {
// ignore
} else if (sscanf(dvb_charset, "ISO-8859-%d", &i) > 0 && i > 0 && i < 16) {
ic = convert_iso_8859[i];
} else {
} else if (!strcmp(dvb_charset, "ISO-6937")) {
ic = convert_iso6937;
} else if (!strcmp(dvb_charset, "UTF-8")) {
ic = convert_utf8;
}
}

View file

@ -21,6 +21,7 @@
#include "queue.h"
#include "input/mpegts.h"
#include "subscriptions.h"
#include "dvb_charset.h"
#include <assert.h>
@ -220,6 +221,14 @@ const idclass_t mpegts_mux_class =
.opts = PO_RDONLY,
.off = offsetof(mpegts_mux_t, mm_initial_scan_done),
},
{
.type = PT_STR,
.id = "charset",
.name = "Character Set",
.off = offsetof(mpegts_mux_t, mm_charset),
.list = dvb_charset_enum,
.opts = PO_ADVANCED,
},
{
.type = PT_INT,
.id = "num_svc",
@ -273,6 +282,7 @@ mpegts_mux_delete ( mpegts_mux_t *mm )
/* Free memory */
idnode_unlink(&mm->mm_id);
free(mm->mm_crid_authority);
free(mm->mm_charset);
free(mm);
}

View file

@ -18,6 +18,7 @@
#include "input/mpegts.h"
#include "subscriptions.h"
#include "dvb_charset.h"
#include <assert.h>
@ -127,6 +128,14 @@ const idclass_t mpegts_network_class =
.off = offsetof(mpegts_network_t, mn_skipinitscan),
.def.i = 1
},
{
.type = PT_STR,
.id = "charset",
.name = "Character Set",
.off = offsetof(mpegts_network_t, mn_charset),
.list = dvb_charset_enum,
.opts = PO_ADVANCED,
},
{
.type = PT_INT,
.id = "num_mux",
@ -229,6 +238,7 @@ mpegts_network_delete
/* Free memory */
idnode_unlink(&mn->mn_id);
free(mn->mn_network_name);
free(mn->mn_charset);
free(mn);
}

View file

@ -22,6 +22,7 @@
#include "service.h"
#include "input/mpegts.h"
#include "settings.h"
#include "dvb_charset.h"
/* **************************************************************************
* Class definition
@ -121,7 +122,8 @@ const idclass_t mpegts_service_class =
.id = "charset",
.name = "Character Set",
.off = offsetof(mpegts_service_t, s_dvb_charset),
.opts = PO_ADVANCED,
.list = dvb_charset_enum,
.opts = PO_ADVANCED,
},
{},
}