dvb: Add table parsing when in raw mode
This commit is contained in:
parent
43509ecf02
commit
f4fc438031
9 changed files with 232 additions and 75 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/dvb/frontend.h>
|
#include <linux/dvb/frontend.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "htsmsg.h"
|
#include "htsmsg.h"
|
||||||
|
#include "psi.h"
|
||||||
|
|
||||||
struct service;
|
struct service;
|
||||||
struct th_dvb_table;
|
struct th_dvb_table;
|
||||||
|
@ -107,6 +108,8 @@ typedef struct th_dvb_mux_instance {
|
||||||
|
|
||||||
|
|
||||||
LIST_HEAD(, th_dvb_table) tdmi_tables;
|
LIST_HEAD(, th_dvb_table) tdmi_tables;
|
||||||
|
int tdmi_num_tables;
|
||||||
|
|
||||||
TAILQ_HEAD(, th_dvb_table) tdmi_table_queue;
|
TAILQ_HEAD(, th_dvb_table) tdmi_table_queue;
|
||||||
int tdmi_table_initial;
|
int tdmi_table_initial;
|
||||||
|
|
||||||
|
@ -150,6 +153,22 @@ typedef struct th_dvb_mux_instance {
|
||||||
} th_dvb_mux_instance_t;
|
} th_dvb_mux_instance_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When in raw mode we need to enqueue raw TS packet
|
||||||
|
* to a different thread because we need to hold
|
||||||
|
* global_lock when doing delivery of the tables
|
||||||
|
*/
|
||||||
|
TAILQ_HEAD(dvb_table_feed_queue, dvb_table_feed);
|
||||||
|
|
||||||
|
typedef struct dvb_table_feed {
|
||||||
|
TAILQ_ENTRY(dvb_table_feed) dtf_link;
|
||||||
|
uint8_t dtf_tsb[188];
|
||||||
|
} dvb_table_feed_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DVB Adapter (one of these per physical adapter)
|
* DVB Adapter (one of these per physical adapter)
|
||||||
*/
|
*/
|
||||||
|
@ -236,6 +255,14 @@ typedef struct th_dvb_adapter {
|
||||||
|
|
||||||
int tda_rawmode;
|
int tda_rawmode;
|
||||||
|
|
||||||
|
|
||||||
|
struct dvb_table_feed_queue tda_table_feed;
|
||||||
|
pthread_cond_t tda_table_feed_cond; // Bound to tda_delivery_mutex
|
||||||
|
|
||||||
|
// PIDs that needs to be requeued and processed as tables
|
||||||
|
uint8_t tda_table_filter[8192];
|
||||||
|
|
||||||
|
|
||||||
} th_dvb_adapter_t;
|
} th_dvb_adapter_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -262,6 +289,7 @@ typedef struct th_dvb_table {
|
||||||
int tdt_fd;
|
int tdt_fd;
|
||||||
|
|
||||||
LIST_ENTRY(th_dvb_table) tdt_link;
|
LIST_ENTRY(th_dvb_table) tdt_link;
|
||||||
|
th_dvb_mux_instance_t *tdt_tdmi;
|
||||||
|
|
||||||
char *tdt_name;
|
char *tdt_name;
|
||||||
|
|
||||||
|
@ -278,6 +306,10 @@ typedef struct th_dvb_table {
|
||||||
int tdt_table;
|
int tdt_table;
|
||||||
int tdt_mask;
|
int tdt_mask;
|
||||||
|
|
||||||
|
int tdt_destroyed;
|
||||||
|
int tdt_refcount;
|
||||||
|
|
||||||
|
psi_section_t tdt_sect; // Manual reassembly
|
||||||
|
|
||||||
} th_dvb_table_t;
|
} th_dvb_table_t;
|
||||||
|
|
||||||
|
@ -459,12 +491,10 @@ void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
|
||||||
|
|
||||||
void dvb_table_rem_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
|
void dvb_table_rem_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
|
||||||
|
|
||||||
void dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi);
|
|
||||||
|
|
||||||
void tdt_add(th_dvb_mux_instance_t *tdmi, int table, int mask,
|
void tdt_add(th_dvb_mux_instance_t *tdmi, int table, int mask,
|
||||||
int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
|
int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
|
||||||
uint8_t tableid, void *opaque), void *opaque,
|
uint8_t tableid, void *opaque), void *opaque,
|
||||||
const char *name, int flags, int pid, th_dvb_table_t *tdt);
|
const char *name, int flags, int pid);
|
||||||
|
|
||||||
int dvb_pidx11_callback
|
int dvb_pidx11_callback
|
||||||
(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||||
|
@ -475,6 +505,10 @@ int dvb_pidx11_callback
|
||||||
#define TDT_CA 0x4
|
#define TDT_CA 0x4
|
||||||
#define TDT_TDT 0x8
|
#define TDT_TDT 0x8
|
||||||
|
|
||||||
|
void dvb_table_dispatch(uint8_t *sec, int r, th_dvb_table_t *tdt);
|
||||||
|
|
||||||
|
void dvb_table_release(th_dvb_table_t *tdt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Satellite configuration
|
* Satellite configuration
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -451,7 +451,7 @@ tda_add(int adapter_num)
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link);
|
TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link);
|
||||||
|
|
||||||
dvb_input_filtered_setup(tda);
|
dvb_input_raw_setup(tda);
|
||||||
|
|
||||||
if(tda->tda_sat)
|
if(tda->tda_sat)
|
||||||
dvb_satconf_init(tda);
|
dvb_satconf_init(tda);
|
||||||
|
@ -796,12 +796,25 @@ dvb_adapter_input_dvr(void *aux)
|
||||||
/* not enough data */
|
/* not enough data */
|
||||||
if (r < 188) continue;
|
if (r < 188) continue;
|
||||||
|
|
||||||
|
int wakeup_table_feed = 0; // Just wanna wakeup once
|
||||||
|
|
||||||
pthread_mutex_lock(&tda->tda_delivery_mutex);
|
pthread_mutex_lock(&tda->tda_delivery_mutex);
|
||||||
/* Process */
|
/* Process */
|
||||||
while (r >= 188) {
|
while (r >= 188) {
|
||||||
|
|
||||||
/* sync */
|
/* sync */
|
||||||
if (tsb[i] == 0x47) {
|
if (tsb[i] == 0x47) {
|
||||||
|
|
||||||
|
if(!(tsb[i+1] & 0x80)) { // Only dispatch to table parser if not error
|
||||||
|
int pid = (tsb[i+1] & 0x1f) << 8 | tsb[i+2];
|
||||||
|
if(tda->tda_table_filter[pid]) {
|
||||||
|
dvb_table_feed_t *dtf = malloc(sizeof(dvb_table_feed_t));
|
||||||
|
memcpy(dtf->dtf_tsb, tsb + i, 188);
|
||||||
|
TAILQ_INSERT_TAIL(&tda->tda_table_feed, dtf, dtf_link);
|
||||||
|
wakeup_table_feed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
|
LIST_FOREACH(t, &tda->tda_transports, s_active_link)
|
||||||
if(t->s_dvb_mux_instance == tda->tda_mux_current)
|
if(t->s_dvb_mux_instance == tda->tda_mux_current)
|
||||||
ts_recv_packet1(t, tsb + i, NULL);
|
ts_recv_packet1(t, tsb + i, NULL);
|
||||||
|
@ -816,6 +829,9 @@ dvb_adapter_input_dvr(void *aux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(wakeup_table_feed)
|
||||||
|
pthread_cond_signal(&tda->tda_table_feed_cond);
|
||||||
|
|
||||||
pthread_mutex_unlock(&tda->tda_delivery_mutex);
|
pthread_mutex_unlock(&tda->tda_delivery_mutex);
|
||||||
|
|
||||||
/* reset buffer */
|
/* reset buffer */
|
||||||
|
|
|
@ -226,6 +226,8 @@ dvb_fe_stop(th_dvb_mux_instance_t *tdmi, int retune)
|
||||||
{
|
{
|
||||||
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||||
|
|
||||||
|
lock_assert(&global_lock);
|
||||||
|
|
||||||
assert(tdmi == tda->tda_mux_current);
|
assert(tdmi == tda->tda_mux_current);
|
||||||
tda->tda_mux_current = NULL;
|
tda->tda_mux_current = NULL;
|
||||||
|
|
||||||
|
|
|
@ -116,9 +116,6 @@ open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
||||||
struct epoll_event e;
|
struct epoll_event e;
|
||||||
static int tdt_id_tally;
|
static int tdt_id_tally;
|
||||||
|
|
||||||
assert(tdt->tdt_fd == -1);
|
|
||||||
TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
|
|
||||||
|
|
||||||
tdt->tdt_fd = tvh_open(tda->tda_demux_path, O_RDWR, 0);
|
tdt->tdt_fd = tvh_open(tda->tda_demux_path, O_RDWR, 0);
|
||||||
|
|
||||||
if(tdt->tdt_fd != -1) {
|
if(tdt->tdt_fd != -1) {
|
||||||
|
@ -173,47 +170,6 @@ tdt_close_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec,
|
|
||||||
int r)
|
|
||||||
{
|
|
||||||
int chkcrc = tdt->tdt_flags & TDT_CRC;
|
|
||||||
int tableid, len;
|
|
||||||
uint8_t *ptr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* It seems some hardware (or is it the dvb API?) does not
|
|
||||||
honour the DMX_CHECK_CRC flag, so we check it again */
|
|
||||||
if(chkcrc && tvh_crc32(sec, r, 0xffffffff))
|
|
||||||
return;
|
|
||||||
|
|
||||||
r -= 3;
|
|
||||||
tableid = sec[0];
|
|
||||||
len = ((sec[1] & 0x0f) << 8) | sec[2];
|
|
||||||
|
|
||||||
if(len < r)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ptr = &sec[3];
|
|
||||||
if(chkcrc) len -= 4; /* Strip trailing CRC */
|
|
||||||
|
|
||||||
if(tdt->tdt_flags & TDT_CA)
|
|
||||||
ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
|
|
||||||
sec, len + 3, tableid, tdt->tdt_opaque);
|
|
||||||
else if(tdt->tdt_flags & TDT_TDT)
|
|
||||||
ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt);
|
|
||||||
else
|
|
||||||
ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque);
|
|
||||||
|
|
||||||
if(ret == 0)
|
|
||||||
tdt->tdt_count++;
|
|
||||||
|
|
||||||
if(tdt->tdt_flags & TDT_QUICKREQ)
|
|
||||||
dvb_table_fastswitch(tdmi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -250,7 +206,7 @@ dvb_table_input(void *aux)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(tdt != NULL) {
|
if(tdt != NULL) {
|
||||||
dvb_proc_table(tdmi, tdt, sec, r);
|
dvb_table_dispatch(sec, r, tdt);
|
||||||
|
|
||||||
/* Any tables pending (that wants a filter/fd), close this one */
|
/* Any tables pending (that wants a filter/fd), close this one */
|
||||||
if(TAILQ_FIRST(&tdmi->tdmi_table_queue) != NULL &&
|
if(TAILQ_FIRST(&tdmi->tdmi_table_queue) != NULL &&
|
||||||
|
@ -259,6 +215,7 @@ dvb_table_input(void *aux)
|
||||||
cycle_barrier = getmonoclock() + 100000;
|
cycle_barrier = getmonoclock() + 100000;
|
||||||
tdt = TAILQ_FIRST(&tdmi->tdmi_table_queue);
|
tdt = TAILQ_FIRST(&tdmi->tdmi_table_queue);
|
||||||
assert(tdt != NULL);
|
assert(tdt != NULL);
|
||||||
|
TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
|
||||||
|
|
||||||
open_table(tdmi, tdt);
|
open_table(tdmi, tdt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
static void
|
static void
|
||||||
open_service(th_dvb_adapter_t *tda, service_t *s)
|
open_service(th_dvb_adapter_t *tda, service_t *s)
|
||||||
{
|
{
|
||||||
|
// NOP -- We receive all PIDs anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ open_service(th_dvb_adapter_t *tda, service_t *s)
|
||||||
static void
|
static void
|
||||||
close_service(th_dvb_adapter_t *tda, service_t *s)
|
close_service(th_dvb_adapter_t *tda, service_t *s)
|
||||||
{
|
{
|
||||||
|
// NOP -- open_service() is a NOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +64,9 @@ close_service(th_dvb_adapter_t *tda, service_t *s)
|
||||||
static void
|
static void
|
||||||
open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
||||||
{
|
{
|
||||||
|
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||||
|
assert(tdt->tdt_pid < 0x2000);
|
||||||
|
tda->tda_table_filter[tdt->tdt_pid] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,8 +76,84 @@ open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
||||||
static void
|
static void
|
||||||
close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
|
||||||
{
|
{
|
||||||
|
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
|
||||||
|
assert(tdt->tdt_pid < 0x2000);
|
||||||
|
tda->tda_table_filter[tdt->tdt_pid] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
got_section(const uint8_t *data, size_t len, void *opaque)
|
||||||
|
{
|
||||||
|
th_dvb_table_t *tdt = opaque;
|
||||||
|
dvb_table_dispatch((uint8_t *)data, len, tdt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All the tables can be destroyed from any of the callbacks
|
||||||
|
* so we need to be a bit careful here
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dvb_table_raw_dispatch(th_dvb_mux_instance_t *tdmi,
|
||||||
|
const dvb_table_feed_t *dtf)
|
||||||
|
{
|
||||||
|
int pid = (dtf->dtf_tsb[1] & 0x1f) << 8 | dtf->dtf_tsb[2];
|
||||||
|
th_dvb_table_t *vec[tdmi->tdmi_num_tables], *tdt;
|
||||||
|
int i = 0;
|
||||||
|
LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) {
|
||||||
|
vec[i++] = tdt;
|
||||||
|
tdt->tdt_refcount++;
|
||||||
|
}
|
||||||
|
assert(i == tdmi->tdmi_num_tables);
|
||||||
|
int len = tdmi->tdmi_num_tables; // can change during callbacks
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
tdt = vec[i];
|
||||||
|
if(!tdt->tdt_destroyed) {
|
||||||
|
if(tdt->tdt_pid == pid)
|
||||||
|
psi_section_reassemble(&tdt->tdt_sect, dtf->dtf_tsb,
|
||||||
|
0, got_section, tdt);
|
||||||
|
}
|
||||||
|
dvb_table_release(tdt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
dvb_table_input(void *aux)
|
||||||
|
{
|
||||||
|
th_dvb_adapter_t *tda = aux;
|
||||||
|
th_dvb_mux_instance_t *tdmi;
|
||||||
|
dvb_table_feed_t *dtf;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&tda->tda_delivery_mutex);
|
||||||
|
|
||||||
|
while((dtf = TAILQ_FIRST(&tda->tda_table_feed)) == NULL)
|
||||||
|
pthread_cond_wait(&tda->tda_table_feed_cond, &tda->tda_delivery_mutex);
|
||||||
|
TAILQ_REMOVE(&tda->tda_table_feed, dtf, dtf_link);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&tda->tda_delivery_mutex);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&global_lock);
|
||||||
|
|
||||||
|
if((tdmi = tda->tda_mux_current) != NULL)
|
||||||
|
dvb_table_raw_dispatch(tdmi, dtf);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&global_lock);
|
||||||
|
free(dtf);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -84,5 +165,12 @@ dvb_input_raw_setup(th_dvb_adapter_t *tda)
|
||||||
tda->tda_close_service = close_service;
|
tda->tda_close_service = close_service;
|
||||||
tda->tda_open_table = open_table;
|
tda->tda_open_table = open_table;
|
||||||
tda->tda_close_table = close_table;
|
tda->tda_close_table = close_table;
|
||||||
|
|
||||||
|
TAILQ_INIT(&tda->tda_table_feed);
|
||||||
|
pthread_cond_init(&tda->tda_table_feed_cond, NULL);
|
||||||
|
|
||||||
|
pthread_t ptid;
|
||||||
|
pthread_create(&ptid, NULL, dvb_table_input, tda);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
|
dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
|
||||||
{
|
{
|
||||||
th_dvb_table_t *tdt;
|
th_dvb_table_t *tdt;
|
||||||
|
@ -72,6 +72,66 @@ dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dvb_table_dispatch(uint8_t *sec, int r, th_dvb_table_t *tdt)
|
||||||
|
{
|
||||||
|
if(tdt->tdt_destroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int chkcrc = tdt->tdt_flags & TDT_CRC;
|
||||||
|
int tableid, len;
|
||||||
|
uint8_t *ptr;
|
||||||
|
int ret;
|
||||||
|
th_dvb_mux_instance_t *tdmi = tdt->tdt_tdmi;
|
||||||
|
|
||||||
|
/* It seems some hardware (or is it the dvb API?) does not
|
||||||
|
honour the DMX_CHECK_CRC flag, so we check it again */
|
||||||
|
if(chkcrc && tvh_crc32(sec, r, 0xffffffff))
|
||||||
|
return;
|
||||||
|
|
||||||
|
r -= 3;
|
||||||
|
tableid = sec[0];
|
||||||
|
len = ((sec[1] & 0x0f) << 8) | sec[2];
|
||||||
|
|
||||||
|
if(len < r)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if((tableid & tdt->tdt_mask) != tdt->tdt_table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ptr = &sec[3];
|
||||||
|
if(chkcrc) len -= 4; /* Strip trailing CRC */
|
||||||
|
|
||||||
|
if(tdt->tdt_flags & TDT_CA)
|
||||||
|
ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
|
||||||
|
sec, len + 3, tableid, tdt->tdt_opaque);
|
||||||
|
else if(tdt->tdt_flags & TDT_TDT)
|
||||||
|
ret = tdt->tdt_callback(tdt->tdt_tdmi, ptr, len, tableid, tdt);
|
||||||
|
else
|
||||||
|
ret = tdt->tdt_callback(tdt->tdt_tdmi, ptr, len, tableid, tdt->tdt_opaque);
|
||||||
|
|
||||||
|
if(ret == 0)
|
||||||
|
tdt->tdt_count++;
|
||||||
|
|
||||||
|
if(tdt->tdt_flags & TDT_QUICKREQ)
|
||||||
|
dvb_table_fastswitch(tdmi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dvb_table_release(th_dvb_table_t *tdt)
|
||||||
|
{
|
||||||
|
if(--tdt->tdt_refcount == 0)
|
||||||
|
free(tdt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -79,15 +139,17 @@ static void
|
||||||
dvb_tdt_destroy(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi,
|
dvb_tdt_destroy(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi,
|
||||||
th_dvb_table_t *tdt)
|
th_dvb_table_t *tdt)
|
||||||
{
|
{
|
||||||
|
lock_assert(&global_lock);
|
||||||
|
assert(tdt->tdt_tdmi == tdmi);
|
||||||
LIST_REMOVE(tdt, tdt_link);
|
LIST_REMOVE(tdt, tdt_link);
|
||||||
|
tdmi->tdmi_num_tables--;
|
||||||
tda->tda_close_table(tdmi, tdt);
|
tda->tda_close_table(tdmi, tdt);
|
||||||
free(tdt->tdt_name);
|
free(tdt->tdt_name);
|
||||||
free(tdt);
|
tdt->tdt_destroyed = 1;
|
||||||
|
dvb_table_release(tdt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new DVB table
|
* Add a new DVB table
|
||||||
*/
|
*/
|
||||||
|
@ -95,7 +157,7 @@ void
|
||||||
tdt_add(th_dvb_mux_instance_t *tdmi, int tableid, int mask,
|
tdt_add(th_dvb_mux_instance_t *tdmi, int tableid, int mask,
|
||||||
int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
|
int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
|
||||||
uint8_t tableid, void *opaque), void *opaque,
|
uint8_t tableid, void *opaque), void *opaque,
|
||||||
const char *name, int flags, int pid, th_dvb_table_t *tdt)
|
const char *name, int flags, int pid)
|
||||||
{
|
{
|
||||||
th_dvb_table_t *t;
|
th_dvb_table_t *t;
|
||||||
|
|
||||||
|
@ -106,15 +168,12 @@ tdt_add(th_dvb_mux_instance_t *tdmi, int tableid, int mask,
|
||||||
LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) {
|
LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) {
|
||||||
if(pid == t->tdt_pid &&
|
if(pid == t->tdt_pid &&
|
||||||
t->tdt_callback == callback && t->tdt_opaque == opaque) {
|
t->tdt_callback == callback && t->tdt_opaque == opaque) {
|
||||||
if (tdt) free(tdt);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th_dvb_table_t *tdt = calloc(1, sizeof(th_dvb_table_t));
|
||||||
if(tdt == NULL)
|
tdt->tdt_refcount = 1;
|
||||||
tdt = calloc(1, sizeof(th_dvb_table_t));
|
|
||||||
|
|
||||||
tdt->tdt_name = strdup(name);
|
tdt->tdt_name = strdup(name);
|
||||||
tdt->tdt_callback = callback;
|
tdt->tdt_callback = callback;
|
||||||
tdt->tdt_opaque = opaque;
|
tdt->tdt_opaque = opaque;
|
||||||
|
@ -122,9 +181,10 @@ tdt_add(th_dvb_mux_instance_t *tdmi, int tableid, int mask,
|
||||||
tdt->tdt_flags = flags;
|
tdt->tdt_flags = flags;
|
||||||
tdt->tdt_table = tableid;
|
tdt->tdt_table = tableid;
|
||||||
tdt->tdt_mask = mask;
|
tdt->tdt_mask = mask;
|
||||||
|
tdt->tdt_tdmi = tdmi;
|
||||||
LIST_INSERT_HEAD(&tdmi->tdmi_tables, tdt, tdt_link);
|
LIST_INSERT_HEAD(&tdmi->tdmi_tables, tdt, tdt_link);
|
||||||
|
tdmi->tdmi_num_tables++;
|
||||||
tdt->tdt_fd = -1;
|
tdt->tdt_fd = -1;
|
||||||
TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
|
|
||||||
|
|
||||||
tdmi->tdmi_adapter->tda_open_table(tdmi, tdt);
|
tdmi->tdmi_adapter->tda_open_table(tdmi, tdt);
|
||||||
}
|
}
|
||||||
|
@ -510,7 +570,7 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tdt_add(tdmi, 0, 0, dvb_ca_callback, (void *)caid, "CA",
|
tdt_add(tdmi, 0, 0, dvb_ca_callback, (void *)caid, "CA",
|
||||||
TDT_CA, pid, NULL);
|
TDT_CA, pid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -959,12 +1019,12 @@ dvb_table_add_default_dvb(th_dvb_mux_instance_t *tdmi)
|
||||||
table = 0x40;
|
table = 0x40;
|
||||||
}
|
}
|
||||||
tdt_add(tdmi, table, 0xff, dvb_nit_callback, NULL, "nit",
|
tdt_add(tdmi, table, 0xff, dvb_nit_callback, NULL, "nit",
|
||||||
TDT_QUICKREQ | TDT_CRC, 0x10, NULL);
|
TDT_QUICKREQ | TDT_CRC, 0x10);
|
||||||
|
|
||||||
/* Service Descriptor Table and Bouqeut Allocation Table */
|
/* Service Descriptor Table and Bouqeut Allocation Table */
|
||||||
|
|
||||||
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, NULL, "pidx11",
|
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, NULL, "pidx11",
|
||||||
TDT_QUICKREQ | TDT_CRC, 0x11, NULL);
|
TDT_QUICKREQ | TDT_CRC, 0x11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -983,7 +1043,7 @@ dvb_table_add_default_atsc(th_dvb_mux_instance_t *tdmi)
|
||||||
}
|
}
|
||||||
|
|
||||||
tdt_add(tdmi, tableid, 0xff, atsc_vct_callback, NULL, "vct",
|
tdt_add(tdmi, tableid, 0xff, atsc_vct_callback, NULL, "vct",
|
||||||
TDT_QUICKREQ | TDT_CRC, 0x1ffb, NULL);
|
TDT_QUICKREQ | TDT_CRC, 0x1ffb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -997,11 +1057,11 @@ dvb_table_add_default(th_dvb_mux_instance_t *tdmi)
|
||||||
{
|
{
|
||||||
/* Program Allocation Table */
|
/* Program Allocation Table */
|
||||||
tdt_add(tdmi, 0x00, 0xff, dvb_pat_callback, NULL, "pat",
|
tdt_add(tdmi, 0x00, 0xff, dvb_pat_callback, NULL, "pat",
|
||||||
TDT_QUICKREQ | TDT_CRC, 0, NULL);
|
TDT_QUICKREQ | TDT_CRC, 0);
|
||||||
|
|
||||||
/* Conditional Access Table */
|
/* Conditional Access Table */
|
||||||
tdt_add(tdmi, 0x1, 0xff, dvb_cat_callback, NULL, "cat",
|
tdt_add(tdmi, 0x1, 0xff, dvb_cat_callback, NULL, "cat",
|
||||||
TDT_CRC, 1, NULL);
|
TDT_CRC, 1);
|
||||||
|
|
||||||
|
|
||||||
switch(tdmi->tdmi_adapter->tda_type) {
|
switch(tdmi->tdmi_adapter->tda_type) {
|
||||||
|
@ -1028,7 +1088,7 @@ dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid)
|
||||||
|
|
||||||
snprintf(pmtname, sizeof(pmtname), "PMT(%d)", pmt_pid);
|
snprintf(pmtname, sizeof(pmtname), "PMT(%d)", pmt_pid);
|
||||||
tdt_add(tdmi, 0x2, 0xff, dvb_pmt_callback, NULL, pmtname,
|
tdt_add(tdmi, 0x2, 0xff, dvb_pmt_callback, NULL, pmtname,
|
||||||
TDT_CRC | TDT_QUICKREQ | TDT_TDT, pmt_pid, NULL);
|
TDT_CRC | TDT_QUICKREQ | TDT_TDT, pmt_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -842,16 +842,16 @@ static void _eit_start
|
||||||
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, m, m->id, TDT_CRC, 3840, NULL);
|
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, m, m->id, TDT_CRC, 3840, NULL);
|
||||||
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 3841, NULL);
|
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 3841, NULL);
|
||||||
#endif
|
#endif
|
||||||
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, m, m->id, TDT_CRC, 3002, NULL);
|
tdt_add(tdmi, 0, 0, dvb_pidx11_callback, m, m->id, TDT_CRC, 3002);
|
||||||
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 3003, NULL);
|
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 3003);
|
||||||
|
|
||||||
/* Viasat Baltic (0x39) */
|
/* Viasat Baltic (0x39) */
|
||||||
} else if (!strcmp("viasat_baltic", m->id)) {
|
} else if (!strcmp("viasat_baltic", m->id)) {
|
||||||
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 0x39, NULL);
|
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 0x39);
|
||||||
|
|
||||||
/* Standard (0x12) */
|
/* Standard (0x12) */
|
||||||
} else {
|
} else {
|
||||||
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 0x12, NULL);
|
tdt_add(tdmi, 0, 0, _eit_callback, m, m->id, TDT_CRC, 0x12);
|
||||||
}
|
}
|
||||||
tvhlog(LOG_DEBUG, m->id, "install table handlers");
|
tvhlog(LOG_DEBUG, m->id, "install table handlers");
|
||||||
}
|
}
|
||||||
|
|
|
@ -669,7 +669,7 @@ static void _opentv_start
|
||||||
while (*t) {
|
while (*t) {
|
||||||
// TODO: what about 0x46 (service description)
|
// TODO: what about 0x46 (service description)
|
||||||
tdt_add(tdmi, 0x4a, 0xff, _opentv_channel_callback, m,
|
tdt_add(tdmi, 0x4a, 0xff, _opentv_channel_callback, m,
|
||||||
m->id, TDT_CRC, *t++, NULL);
|
m->id, TDT_CRC, *t++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Titles */
|
/* Titles */
|
||||||
|
@ -677,7 +677,7 @@ static void _opentv_start
|
||||||
while (*t) {
|
while (*t) {
|
||||||
_opentv_status_get_pid(sta, *t);
|
_opentv_status_get_pid(sta, *t);
|
||||||
tdt_add(tdmi, 0xa0, 0xfc, _opentv_title_callback, m,
|
tdt_add(tdmi, 0xa0, 0xfc, _opentv_title_callback, m,
|
||||||
m->id, TDT_CRC | TDT_TDT, *t++, NULL);
|
m->id, TDT_CRC | TDT_TDT, *t++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Summaries */
|
/* Summaries */
|
||||||
|
@ -685,7 +685,7 @@ static void _opentv_start
|
||||||
while (*t) {
|
while (*t) {
|
||||||
_opentv_status_get_pid(sta, *t);
|
_opentv_status_get_pid(sta, *t);
|
||||||
tdt_add(tdmi, 0xa8, 0xfc, _opentv_summary_callback, m,
|
tdt_add(tdmi, 0xa8, 0xfc, _opentv_summary_callback, m,
|
||||||
m->id, TDT_CRC | TDT_TDT, *t++, NULL);
|
m->id, TDT_CRC | TDT_TDT, *t++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,8 @@ psi_section_reassemble0(psi_section_t *ps, const uint8_t *data,
|
||||||
if(crc && tvh_crc32(ps->ps_data, tsize, 0xffffffff))
|
if(crc && tvh_crc32(ps->ps_data, tsize, 0xffffffff))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cb(ps->ps_data, tsize - (crc ? 4 : 0), opaque);
|
|
||||||
ps->ps_offset = 0;
|
ps->ps_offset = 0;
|
||||||
|
cb(ps->ps_data, tsize - (crc ? 4 : 0), opaque);
|
||||||
return len - excess;
|
return len - excess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue