Moved EIT handling code from dvb_tables into the eit grab module. Needs tidying up.
This commit is contained in:
parent
96668a6134
commit
3d5910bcf6
3 changed files with 234 additions and 237 deletions
|
@ -41,7 +41,6 @@
|
|||
#include "psi.h"
|
||||
#include "notify.h"
|
||||
#include "cwc.h"
|
||||
#include "epggrab/eit.h"
|
||||
|
||||
static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
|
||||
|
||||
|
@ -320,95 +319,6 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams,
|
|||
tdt_open_fd(tdmi, tdt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Short Event
|
||||
*/
|
||||
static int
|
||||
dvb_desc_short_event(uint8_t *ptr, int len,
|
||||
char *title, size_t titlelen,
|
||||
char *desc, size_t desclen,
|
||||
char *dvb_default_charset)
|
||||
{
|
||||
int r;
|
||||
|
||||
if(len < 4)
|
||||
return -1;
|
||||
ptr += 3; len -= 3;
|
||||
|
||||
if((r = dvb_get_string_with_len(title, titlelen, ptr, len, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
ptr += r; len -= r;
|
||||
|
||||
if((r = dvb_get_string_with_len(desc, desclen, ptr, len, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Extended Event
|
||||
*/
|
||||
static int
|
||||
dvb_desc_extended_event(uint8_t *ptr, int len,
|
||||
char *desc, size_t desclen,
|
||||
char *item, size_t itemlen,
|
||||
char *text, size_t textlen,
|
||||
char *dvb_default_charset)
|
||||
{
|
||||
int count = ptr[4], r;
|
||||
uint8_t *localptr = ptr + 5, *items = localptr;
|
||||
int locallen = len - 5;
|
||||
|
||||
/* terminate buffers */
|
||||
desc[0] = '\0'; item[0] = '\0'; text[0] = '\0';
|
||||
|
||||
while (items < (localptr + count))
|
||||
{
|
||||
/* this only makes sense if we have 2 or more character left in buffer */
|
||||
if ((desclen - strlen(desc)) > 2)
|
||||
{
|
||||
/* get description -> append to desc if space left */
|
||||
if (desc[0] != '\0')
|
||||
strncat(desc, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(desc + strlen(desc),
|
||||
desclen - strlen(desc),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
items += 1 + items[0];
|
||||
|
||||
/* this only makes sense if we have 2 or more character left in buffer */
|
||||
if ((itemlen - strlen(item)) > 2)
|
||||
{
|
||||
/* get item -> append to item if space left */
|
||||
if (item[0] != '\0')
|
||||
strncat(item, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(item + strlen(item),
|
||||
itemlen - strlen(item),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* go to next item */
|
||||
items += 1 + items[0];
|
||||
}
|
||||
|
||||
localptr += count;
|
||||
locallen -= count;
|
||||
count = localptr[0];
|
||||
|
||||
/* get text */
|
||||
if((r = dvb_get_string_with_len(text, textlen, localptr, locallen, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Service
|
||||
*/
|
||||
|
@ -437,139 +347,6 @@ dvb_desc_service(uint8_t *ptr, int len, uint8_t *typep,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB EIT (Event Information Table)
|
||||
*/
|
||||
static int
|
||||
dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
service_t *t;
|
||||
channel_t *ch;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
|
||||
uint16_t serviceid;
|
||||
uint16_t transport_stream_id;
|
||||
|
||||
uint16_t event_id;
|
||||
time_t start_time, stop_time;
|
||||
|
||||
int ok;
|
||||
int duration;
|
||||
int dllen;
|
||||
uint8_t dtag, dlen;
|
||||
|
||||
char title[256];
|
||||
char desc[5000];
|
||||
char extdesc[5000];
|
||||
char extitem[5000];
|
||||
char exttext[5000];
|
||||
uint8_t genre[10]; // max 10 genres
|
||||
int genre_idx = 0;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
// printf("EIT!, tid = %x\n", tableid);
|
||||
|
||||
if(tableid < 0x4e || tableid > 0x6f || len < 11)
|
||||
return -1;
|
||||
|
||||
serviceid = ptr[0] << 8 | ptr[1];
|
||||
// version = ptr[2] >> 1 & 0x1f;
|
||||
// section_number = ptr[3];
|
||||
// last_section_number = ptr[4];
|
||||
transport_stream_id = ptr[5] << 8 | ptr[6];
|
||||
// original_network_id = ptr[7] << 8 | ptr[8];
|
||||
// segment_last_section_number = ptr[9];
|
||||
// last_table_id = ptr[10];
|
||||
|
||||
if((ptr[2] & 1) == 0) {
|
||||
/* current_next_indicator == next, skip this */
|
||||
return -1;
|
||||
}
|
||||
|
||||
len -= 11;
|
||||
ptr += 11;
|
||||
|
||||
/* Search all muxes on adapter */
|
||||
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
|
||||
if(tdmi->tdmi_transport_stream_id == transport_stream_id)
|
||||
break;
|
||||
|
||||
if(tdmi == NULL)
|
||||
return -1;
|
||||
|
||||
t = dvb_transport_find(tdmi, serviceid, 0, NULL);
|
||||
if(t == NULL || !t->s_enabled || (ch = t->s_ch) == NULL)
|
||||
return 0;
|
||||
|
||||
if(!t->s_dvb_eit_enable)
|
||||
return 0;
|
||||
|
||||
while(len >= 12) {
|
||||
ok = 1;
|
||||
event_id = ptr[0] << 8 | ptr[1];
|
||||
start_time = dvb_convert_date(&ptr[2]);
|
||||
duration = bcdtoint(ptr[7] & 0xff) * 3600 +
|
||||
bcdtoint(ptr[8] & 0xff) * 60 +
|
||||
bcdtoint(ptr[9] & 0xff);
|
||||
dllen = ((ptr[10] & 0x0f) << 8) | ptr[11];
|
||||
|
||||
len -= 12;
|
||||
ptr += 12;
|
||||
|
||||
if(dllen > len) break;
|
||||
stop_time = start_time + duration;
|
||||
|
||||
*title = 0;
|
||||
*desc = 0;
|
||||
while(dllen > 0) {
|
||||
dtag = ptr[0];
|
||||
dlen = ptr[1];
|
||||
|
||||
len -= 2; ptr += 2; dllen -= 2;
|
||||
|
||||
if(dlen > len) break;
|
||||
|
||||
switch(dtag) {
|
||||
case DVB_DESC_SHORT_EVENT:
|
||||
if(dvb_desc_short_event(ptr, dlen,
|
||||
title, sizeof(title),
|
||||
desc, sizeof(desc),
|
||||
t->s_dvb_default_charset)) ok = 0;
|
||||
break;
|
||||
|
||||
case DVB_DESC_CONTENT:
|
||||
if(dlen >= 2) {
|
||||
if (genre_idx < 10)
|
||||
genre[genre_idx++] = (*ptr);
|
||||
}
|
||||
break;
|
||||
case DVB_DESC_EXT_EVENT:
|
||||
if(dvb_desc_extended_event(ptr, dlen,
|
||||
extdesc, sizeof(extdesc),
|
||||
extitem, sizeof(extitem),
|
||||
exttext, sizeof(exttext),
|
||||
t->s_dvb_default_charset)) ok = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
len -= dlen; ptr += dlen; dllen -= dlen;
|
||||
}
|
||||
|
||||
/* Pass to EIT handler */
|
||||
if (ok)
|
||||
eit_callback(ch, event_id, start_time, stop_time,
|
||||
title, desc, extitem, extdesc, exttext,
|
||||
genre, genre_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB SDT (Service Description Table)
|
||||
*/
|
||||
|
@ -1242,12 +1019,6 @@ dvb_table_add_default_dvb(th_dvb_mux_instance_t *tdmi)
|
|||
fp->filter.mask[0] = 0xff;
|
||||
tdt_add(tdmi, fp, dvb_sdt_callback, NULL, "sdt",
|
||||
TDT_QUICKREQ | TDT_CRC, 0x11, NULL);
|
||||
|
||||
/* Event Information table */
|
||||
|
||||
fp = dvb_fparams_alloc();
|
||||
tdt_add(tdmi, fp, dvb_eit_callback, NULL, "eit",
|
||||
TDT_CRC, 0x12, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include <string.h>
|
||||
#include "tvheadend.h"
|
||||
#include "channels.h"
|
||||
#include "dvb/dvb.h"
|
||||
#include "dvb/dvb_support.h"
|
||||
#include "service.h"
|
||||
#include "epg.h"
|
||||
#include "epggrab/eit.h"
|
||||
|
||||
|
@ -36,8 +39,7 @@ longest_string ( const char *a, const char *b )
|
|||
if (strlen(a) - strlen(b) >= 0) return a;
|
||||
}
|
||||
|
||||
// called from dvb_tables.c
|
||||
void eit_callback ( channel_t *ch, int id, time_t start, time_t stop,
|
||||
static void eit_callback ( channel_t *ch, int id, time_t start, time_t stop,
|
||||
const char *title, const char *desc,
|
||||
const char *extitem, const char *extdesc,
|
||||
const char *exttext,
|
||||
|
@ -95,14 +97,244 @@ void eit_callback ( channel_t *ch, int id, time_t start, time_t stop,
|
|||
free(uri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Short Event
|
||||
*/
|
||||
static int
|
||||
dvb_desc_short_event(uint8_t *ptr, int len,
|
||||
char *title, size_t titlelen,
|
||||
char *desc, size_t desclen,
|
||||
char *dvb_default_charset)
|
||||
{
|
||||
int r;
|
||||
|
||||
if(len < 4)
|
||||
return -1;
|
||||
ptr += 3; len -= 3;
|
||||
|
||||
if((r = dvb_get_string_with_len(title, titlelen, ptr, len, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
ptr += r; len -= r;
|
||||
|
||||
if((r = dvb_get_string_with_len(desc, desclen, ptr, len, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Extended Event
|
||||
*/
|
||||
static int
|
||||
dvb_desc_extended_event(uint8_t *ptr, int len,
|
||||
char *desc, size_t desclen,
|
||||
char *item, size_t itemlen,
|
||||
char *text, size_t textlen,
|
||||
char *dvb_default_charset)
|
||||
{
|
||||
int count = ptr[4], r;
|
||||
uint8_t *localptr = ptr + 5, *items = localptr;
|
||||
int locallen = len - 5;
|
||||
|
||||
/* terminate buffers */
|
||||
desc[0] = '\0'; item[0] = '\0'; text[0] = '\0';
|
||||
|
||||
while (items < (localptr + count))
|
||||
{
|
||||
/* this only makes sense if we have 2 or more character left in buffer */
|
||||
if ((desclen - strlen(desc)) > 2)
|
||||
{
|
||||
/* get description -> append to desc if space left */
|
||||
if (desc[0] != '\0')
|
||||
strncat(desc, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(desc + strlen(desc),
|
||||
desclen - strlen(desc),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
items += 1 + items[0];
|
||||
|
||||
/* this only makes sense if we have 2 or more character left in buffer */
|
||||
if ((itemlen - strlen(item)) > 2)
|
||||
{
|
||||
/* get item -> append to item if space left */
|
||||
if (item[0] != '\0')
|
||||
strncat(item, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(item + strlen(item),
|
||||
itemlen - strlen(item),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* go to next item */
|
||||
items += 1 + items[0];
|
||||
}
|
||||
|
||||
localptr += count;
|
||||
locallen -= count;
|
||||
count = localptr[0];
|
||||
|
||||
/* get text */
|
||||
if((r = dvb_get_string_with_len(text, textlen, localptr, locallen, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DVB EIT (Event Information Table)
|
||||
*/
|
||||
static int
|
||||
_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
service_t *t;
|
||||
channel_t *ch;
|
||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||
epggrab_module_t *mod = (epggrab_module_t*)opaque;
|
||||
|
||||
uint16_t serviceid;
|
||||
uint16_t transport_stream_id;
|
||||
|
||||
uint16_t event_id;
|
||||
time_t start_time, stop_time;
|
||||
|
||||
int ok;
|
||||
int duration;
|
||||
int dllen;
|
||||
uint8_t dtag, dlen;
|
||||
|
||||
char title[256];
|
||||
char desc[5000];
|
||||
char extdesc[5000];
|
||||
char extitem[5000];
|
||||
char exttext[5000];
|
||||
uint8_t genre[10]; // max 10 genres
|
||||
int genre_idx = 0;
|
||||
|
||||
/* Global disable */
|
||||
if (!mod->enabled) return 0;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
// printf("EIT!, tid = %x\n", tableid);
|
||||
|
||||
if(tableid < 0x4e || tableid > 0x6f || len < 11)
|
||||
return -1;
|
||||
|
||||
serviceid = ptr[0] << 8 | ptr[1];
|
||||
// version = ptr[2] >> 1 & 0x1f;
|
||||
// section_number = ptr[3];
|
||||
// last_section_number = ptr[4];
|
||||
transport_stream_id = ptr[5] << 8 | ptr[6];
|
||||
// original_network_id = ptr[7] << 8 | ptr[8];
|
||||
// segment_last_section_number = ptr[9];
|
||||
// last_table_id = ptr[10];
|
||||
|
||||
if((ptr[2] & 1) == 0) {
|
||||
/* current_next_indicator == next, skip this */
|
||||
return -1;
|
||||
}
|
||||
|
||||
len -= 11;
|
||||
ptr += 11;
|
||||
|
||||
/* Search all muxes on adapter */
|
||||
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
|
||||
if(tdmi->tdmi_transport_stream_id == transport_stream_id)
|
||||
break;
|
||||
|
||||
if(tdmi == NULL)
|
||||
return -1;
|
||||
|
||||
t = dvb_transport_find(tdmi, serviceid, 0, NULL);
|
||||
if(t == NULL || !t->s_enabled || (ch = t->s_ch) == NULL)
|
||||
return 0;
|
||||
|
||||
if(!t->s_dvb_eit_enable)
|
||||
return 0;
|
||||
|
||||
while(len >= 12) {
|
||||
ok = 1;
|
||||
event_id = ptr[0] << 8 | ptr[1];
|
||||
start_time = dvb_convert_date(&ptr[2]);
|
||||
duration = bcdtoint(ptr[7] & 0xff) * 3600 +
|
||||
bcdtoint(ptr[8] & 0xff) * 60 +
|
||||
bcdtoint(ptr[9] & 0xff);
|
||||
dllen = ((ptr[10] & 0x0f) << 8) | ptr[11];
|
||||
|
||||
len -= 12;
|
||||
ptr += 12;
|
||||
|
||||
if(dllen > len) break;
|
||||
stop_time = start_time + duration;
|
||||
|
||||
*title = 0;
|
||||
*desc = 0;
|
||||
while(dllen > 0) {
|
||||
dtag = ptr[0];
|
||||
dlen = ptr[1];
|
||||
|
||||
len -= 2; ptr += 2; dllen -= 2;
|
||||
|
||||
if(dlen > len) break;
|
||||
|
||||
switch(dtag) {
|
||||
case DVB_DESC_SHORT_EVENT:
|
||||
if(dvb_desc_short_event(ptr, dlen,
|
||||
title, sizeof(title),
|
||||
desc, sizeof(desc),
|
||||
t->s_dvb_default_charset)) ok = 0;
|
||||
break;
|
||||
|
||||
case DVB_DESC_CONTENT:
|
||||
if(dlen >= 2) {
|
||||
if (genre_idx < 10)
|
||||
genre[genre_idx++] = (*ptr);
|
||||
}
|
||||
break;
|
||||
case DVB_DESC_EXT_EVENT:
|
||||
if(dvb_desc_extended_event(ptr, dlen,
|
||||
extdesc, sizeof(extdesc),
|
||||
extitem, sizeof(extitem),
|
||||
exttext, sizeof(exttext),
|
||||
t->s_dvb_default_charset)) ok = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
len -= dlen; ptr += dlen; dllen -= dlen;
|
||||
}
|
||||
|
||||
/* Pass to EIT handler */
|
||||
if (ok)
|
||||
eit_callback(ch, event_id, start_time, stop_time,
|
||||
title, desc, extitem, extdesc, exttext,
|
||||
genre, genre_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
* Module Setup
|
||||
* ***********************************************************************/
|
||||
|
||||
static void _eit_tune ( epggrab_module_t *m, th_dvb_mux_instance_t *tdmi )
|
||||
{
|
||||
tdt_add(tdmi, NULL, _eit_callback, NULL, "eit", TDT_CRC, 0x12, NULL);
|
||||
}
|
||||
|
||||
void eit_init ( epggrab_module_list_t *list )
|
||||
{
|
||||
_eit_mod.id = strdup("eit");
|
||||
_eit_mod.name = strdup("EIT: On-Air Grabber");
|
||||
_eit_mod.tune = _eit_tune;
|
||||
*((uint8_t*)&_eit_mod.flags) = EPGGRAB_MODULE_OTA;
|
||||
LIST_INSERT_HEAD(list, &_eit_mod, link);
|
||||
// Note: this is mostly ignored anyway as EIT is treated as a special case!
|
||||
|
|
|
@ -24,10 +24,4 @@
|
|||
void eit_init ( epggrab_module_list_t *list );
|
||||
void eit_load ( void );
|
||||
|
||||
void eit_callback ( struct channel *ch, int id, time_t start, time_t stop,
|
||||
const char *title, const char *desc,
|
||||
const char *extitem, const char *extdesc,
|
||||
const char *exttext,
|
||||
const uint8_t *genres, int genre_cnt );
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue