Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
dvb: Add support for grabbing entire mux directly via HTTP
  • Loading branch information
andoma committed Oct 25, 2012
1 parent f4fc438 commit 9f0de04
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/dvb/dvb.c
Expand Up @@ -23,8 +23,8 @@
#include "dvb_charset.h"

void
dvb_init(uint32_t adapter_mask)
dvb_init(uint32_t adapter_mask, const char *rawfile)
{
dvb_charset_init();
dvb_adapter_init(adapter_mask);
dvb_adapter_init(adapter_mask, rawfile);
}
20 changes: 18 additions & 2 deletions src/dvb/dvb.h
Expand Up @@ -150,6 +150,8 @@ typedef struct th_dvb_mux_instance {

TAILQ_HEAD(, epggrab_ota_mux) tdmi_epg_grab;

struct th_subscription_list tdmi_subscriptions;

} th_dvb_mux_instance_t;


Expand Down Expand Up @@ -255,6 +257,10 @@ typedef struct th_dvb_adapter {

int tda_rawmode;

// Full mux streaming, protected via the delivery mutex

streaming_pad_t tda_streaming_pad;


struct dvb_table_feed_queue tda_table_feed;
pthread_cond_t tda_table_feed_cond; // Bound to tda_delivery_mutex
Expand Down Expand Up @@ -317,12 +323,12 @@ typedef struct th_dvb_table {
extern struct th_dvb_adapter_queue dvb_adapters;
extern struct th_dvb_mux_instance_tree dvb_muxes;

void dvb_init(uint32_t adapter_mask);
void dvb_init(uint32_t adapter_mask, const char *rawfile);

/**
* DVB Adapter
*/
void dvb_adapter_init(uint32_t adapter_mask);
void dvb_adapter_init(uint32_t adapter_mask, const char *rawfile);

void dvb_adapter_mux_scanner(void *aux);

Expand Down Expand Up @@ -524,4 +530,14 @@ dvb_satconf_t *dvb_satconf_entry_find(th_dvb_adapter_t *tda,
void dvb_lnb_get_frequencies(const char *id,
int *f_low, int *f_hi, int *f_switch);


/**
* Raw demux
*/
struct th_subscription;
struct th_subscription *dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
const char *name,
streaming_target_t *st);

#endif /* DVB_H_ */

71 changes: 69 additions & 2 deletions src/dvb/dvb_adapter.c
Expand Up @@ -64,6 +64,7 @@ tda_alloc(void)
TAILQ_INIT(&tda->tda_scan_queues[i]);
TAILQ_INIT(&tda->tda_initial_scan_queue);
TAILQ_INIT(&tda->tda_satconfs);
streaming_pad_init(&tda->tda_streaming_pad);
return tda;
}

Expand Down Expand Up @@ -459,6 +460,53 @@ tda_add(int adapter_num)
gtimer_arm(&tda->tda_mux_scanner_timer, dvb_adapter_mux_scanner, tda, 1);
}


/**
*
*/
static void
tda_add_from_file(const char *filename)
{
int i, r;
th_dvb_adapter_t *tda;
char buf[400];

tda = tda_alloc();

tda->tda_adapter_num = -1;
tda->tda_fe_fd = -1;
tda->tda_dvr_pipe[0] = -1;

tda->tda_type = -1;

snprintf(buf, sizeof(buf), "%s", filename);

r = strlen(buf);
for(i = 0; i < r; i++)
if(!isalnum((int)buf[i]))
buf[i] = '_';

tda->tda_identifier = strdup(buf);

tda->tda_autodiscovery = 0;
tda->tda_idlescan = 0;

tda->tda_sat = 0;

/* Come up with an initial displayname, user can change it and it will
be overridden by any stored settings later on */

tda->tda_displayname = strdup(filename);

TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link);

dvb_input_raw_setup(tda);
}


/**
*
*/
void
dvb_adapter_start ( th_dvb_adapter_t *tda )
{
Expand Down Expand Up @@ -515,7 +563,7 @@ dvb_adapter_stop ( th_dvb_adapter_t *tda )
*
*/
void
dvb_adapter_init(uint32_t adapter_mask)
dvb_adapter_init(uint32_t adapter_mask, const char *rawfile)
{
htsmsg_t *l, *c;
htsmsg_field_t *f;
Expand All @@ -529,6 +577,10 @@ dvb_adapter_init(uint32_t adapter_mask)
if ((1 << i) & adapter_mask)
tda_add(i);

if(rawfile)
tda_add_from_file(rawfile);


l = hts_settings_load("dvbadapters");
if(l != NULL) {
HTSMSG_FOREACH(f, l) {
Expand Down Expand Up @@ -605,6 +657,10 @@ dvb_adapter_mux_scanner(void *aux)
if(service_compute_weight(&tda->tda_transports) > 0)
return;

if(tda->tda_mux_current != NULL &&
LIST_FIRST(&tda->tda_mux_current->tdmi_subscriptions) != NULL)
return; // Someone is doing full mux dump

/* Check if we have muxes pending for quickscan, if so, choose them */
if((tdmi = TAILQ_FIRST(&tda->tda_initial_scan_queue)) != NULL) {
dvb_fe_tune(tdmi, "Initial autoscan");
Expand Down Expand Up @@ -804,7 +860,18 @@ dvb_adapter_input_dvr(void *aux)

/* sync */
if (tsb[i] == 0x47) {


if(LIST_FIRST(&tda->tda_streaming_pad.sp_targets) != NULL) {
streaming_message_t sm;
pktbuf_t *pb = pktbuf_alloc(tsb, 188);
memset(&sm, 0, sizeof(sm));
sm.sm_type = SMT_MPEGTS;
sm.sm_data = pb;
streaming_pad_deliver(&tda->tda_streaming_pad, &sm);
pktbuf_ref_dec(pb);
}


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]) {
Expand Down
29 changes: 29 additions & 0 deletions src/dvb/dvb_multiplex.c
Expand Up @@ -1285,3 +1285,32 @@ th_dvb_mux_instance_t *dvb_mux_find
}
return NULL;
}


/**
*
*/
th_subscription_t *
dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi,
const char *name,
streaming_target_t *st)
{
th_subscription_t *s;
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;

s = subscription_create(INT32_MAX, name, st, SUBSCRIPTION_RAW_MPEGTS,
NULL, NULL, NULL, NULL);


s->ths_tdmi = tdmi;
LIST_INSERT_HEAD(&tdmi->tdmi_subscriptions, s, ths_tdmi_link);

dvb_fe_tune(tdmi, "Full mux subscription");

pthread_mutex_lock(&tda->tda_delivery_mutex);
streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input);
pthread_mutex_unlock(&tda->tda_delivery_mutex);

notify_reload("subscriptions");
return s;
}
5 changes: 4 additions & 1 deletion src/dvb/dvb_service.c
Expand Up @@ -79,7 +79,10 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start)
if(w && w >= weight && !force_start)
/* We are outranked by weight, cant use it */
return SM_CODE_NOT_FREE;


if(LIST_FIRST(&tdmi->tdmi_subscriptions) != NULL)
return SM_CODE_NOT_FREE;

dvb_adapter_clean(tda);
}

Expand Down
8 changes: 6 additions & 2 deletions src/main.c
Expand Up @@ -262,6 +262,7 @@ main(int argc, char **argv)
sigset_t set;
const char *homedir;
const char *rawts_input = NULL;
const char *dvb_rawts_input = NULL;
const char *join_transport = NULL;
const char *confpath = NULL;
char *p, *endp;
Expand All @@ -279,7 +280,7 @@ main(int argc, char **argv)
// make sure the timezone is set
tzset();

while((c = getopt(argc, argv, "Aa:fp:u:g:c:Chdr:j:sw:e:E:")) != -1) {
while((c = getopt(argc, argv, "Aa:fp:u:g:c:Chdr:j:sw:e:E:R:")) != -1) {
switch(c) {
case 'a':
adapter_mask = 0x0;
Expand Down Expand Up @@ -340,6 +341,9 @@ main(int argc, char **argv)
case 'r':
rawts_input = optarg;
break;
case 'R':
dvb_rawts_input = optarg;
break;
case 'j':
join_transport = optarg;
break;
Expand Down Expand Up @@ -421,7 +425,7 @@ main(int argc, char **argv)

tcp_server_init();
#if ENABLE_LINUXDVB
dvb_init(adapter_mask);
dvb_init(adapter_mask, dvb_rawts_input);
#endif
iptv_input_init();
#if ENABLE_V4L
Expand Down
33 changes: 23 additions & 10 deletions src/subscriptions.c
Expand Up @@ -39,6 +39,7 @@
#include "htsmsg.h"
#include "notify.h"
#include "atomic.h"
#include "dvb/dvb.h"

struct th_subscription_list subscriptions;
static gtimer_t subscription_reschedule_timer;
Expand Down Expand Up @@ -215,6 +216,14 @@ subscription_unsubscribe(th_subscription_t *s)
if(t != NULL)
service_remove_subscriber(t, s, SM_CODE_OK);

if(s->ths_tdmi != NULL) {
LIST_REMOVE(s, ths_tdmi_link);
th_dvb_adapter_t *tda = s->ths_tdmi->tdmi_adapter;
pthread_mutex_lock(&tda->tda_delivery_mutex);
streaming_target_disconnect(&tda->tda_streaming_pad, &s->ths_input);
pthread_mutex_unlock(&tda->tda_delivery_mutex);
}

if(s->ths_start_message != NULL)
streaming_msg_free(s->ths_start_message);

Expand Down Expand Up @@ -302,9 +311,9 @@ subscription_input_direct(void *opauqe, streaming_message_t *sm)
/**
*
*/
static th_subscription_t *
th_subscription_t *
subscription_create(int weight, const char *name, streaming_target_t *st,
int flags, int direct, const char *hostname,
int flags, st_callback_t *cb, const char *hostname,
const char *username, const char *client)
{
th_subscription_t *s = calloc(1, sizeof(th_subscription_t));
Expand All @@ -316,9 +325,8 @@ subscription_create(int weight, const char *name, streaming_target_t *st,
else
reject |= SMT_TO_MASK(SMT_MPEGTS); // Reject raw mpegts


streaming_target_init(&s->ths_input, direct ? subscription_input_direct :
subscription_input, s, reject);
streaming_target_init(&s->ths_input,
cb ?: subscription_input_direct, s, reject);

s->ths_weight = weight;
s->ths_title = strdup(name);
Expand Down Expand Up @@ -348,8 +356,10 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight,
int flags, const char *hostname,
const char *username, const char *client)
{
th_subscription_t *s = subscription_create(weight, name, st, flags, 0,
hostname, username, client);
th_subscription_t *s;

s = subscription_create(weight, name, st, flags, subscription_input,
hostname, username, client);

s->ths_channel = ch;
LIST_INSERT_HEAD(&ch->ch_subscriptions, s, ths_channel_link);
Expand Down Expand Up @@ -391,13 +401,16 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight,
*/
th_subscription_t *
subscription_create_from_service(service_t *t, const char *name,
streaming_target_t *st, int flags)
streaming_target_t *st, int flags)
{
th_subscription_t *s = subscription_create(INT32_MAX, name, st, flags, 1,
NULL, NULL, NULL);
th_subscription_t *s;
source_info_t si;
int r;

s = subscription_create(INT32_MAX, name, st, flags,
subscription_input_direct,
NULL, NULL, NULL);

if(t->s_status != SERVICE_RUNNING) {
if((r = service_start(t, INT32_MAX, 1)) != 0) {
subscription_unsubscribe(s);
Expand Down
13 changes: 11 additions & 2 deletions src/subscriptions.h
Expand Up @@ -65,6 +65,10 @@ typedef struct th_subscription {
char *ths_username;
char *ths_client;

// Ugly ugly ugly to refer DVB code here

LIST_ENTRY(th_subscription) ths_tdmi_link;
struct th_dvb_mux_instance *ths_tdmi;

} th_subscription_t;

Expand Down Expand Up @@ -95,9 +99,14 @@ th_subscription_t *subscription_create_from_service(struct service *t,
streaming_target_t *st,
int flags);

void subscription_change_weight(th_subscription_t *s, int weight);
th_subscription_t *subscription_create(int weight, const char *name,
streaming_target_t *st,
int flags, st_callback_t *cb,
const char *hostname,
const char *username,
const char *client);

void subscription_stop(th_subscription_t *s);
void subscription_change_weight(th_subscription_t *s, int weight);

void subscription_unlink_service(th_subscription_t *s, int reason);

Expand Down

0 comments on commit 9f0de04

Please sign in to comment.