Add function for automating probing of services and if successful, map to a channel
This commit is contained in:
parent
7c849df9c3
commit
5879cd4d14
10 changed files with 225 additions and 3 deletions
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@
|
|||
SRCS = main.c dispatch.c channels.c transports.c teletext.c psi.c \
|
||||
subscriptions.c mux.c tsdemux.c buffer.c tcp.c \
|
||||
resolver.c tsmux.c parsers.c bitstream.c parser_h264.c spawn.c \
|
||||
notify.c intercom.c access.c
|
||||
notify.c intercom.c access.c serviceprobe.c
|
||||
|
||||
SRCS += http.c
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "channels.h"
|
||||
#include "psi.h"
|
||||
#include "transports.h"
|
||||
#include "serviceprobe.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -227,6 +228,8 @@ ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq,
|
|||
ajax_a_jsfuncf(tq, "Map selected", "selected_do('map');");
|
||||
tcp_qprintf(tq, " / ");
|
||||
ajax_a_jsfuncf(tq, "Unmap selected", "selected_do('unmap');");
|
||||
tcp_qprintf(tq, " / ");
|
||||
ajax_a_jsfuncf(tq, "Test and map selected", "selected_do('probe');");
|
||||
|
||||
tcp_qprintf(tq, "</div></div>");
|
||||
|
||||
|
@ -337,6 +340,9 @@ ajax_transport_op(http_connection_t *hc, http_reply_t *hr,
|
|||
dvb_map_channel(t, tq);
|
||||
} else if(!strcmp(op, "unmap") && t->tht_channel != NULL) {
|
||||
dvb_unmap_channel(t, tq);
|
||||
} else if(!strcmp(op, "probe")) {
|
||||
serviceprobe_add(t);
|
||||
continue;
|
||||
}
|
||||
t->tht_config_change(t);
|
||||
}
|
||||
|
|
2
main.c
2
main.c
|
@ -62,6 +62,7 @@
|
|||
#include "ajaxui/ajaxui.h"
|
||||
#include "webui/webui.h"
|
||||
#include "access.h"
|
||||
#include "serviceprobe.h"
|
||||
|
||||
#include <libhts/htsparachute.h>
|
||||
|
||||
|
@ -237,6 +238,7 @@ main(int argc, char **argv)
|
|||
av_log_set_level(AV_LOG_INFO);
|
||||
tffm_init();
|
||||
pkt_init();
|
||||
serviceprobe_setup();
|
||||
|
||||
if(!disable_dvb)
|
||||
dvb_init();
|
||||
|
|
175
serviceprobe.c
Normal file
175
serviceprobe.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Output functions for fixed multicast streaming
|
||||
* Copyright (C) 2007 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "tvhead.h"
|
||||
#include "iptv_output.h"
|
||||
#include "dispatch.h"
|
||||
#include "channels.h"
|
||||
#include "subscriptions.h"
|
||||
#include "serviceprobe.h"
|
||||
#include "transports.h"
|
||||
#include "mux.h"
|
||||
|
||||
static void serviceprobe_engage(void);
|
||||
|
||||
struct th_transport_queue probequeue;
|
||||
|
||||
typedef struct sp {
|
||||
dtimer_t sp_timer;
|
||||
th_muxer_t *sp_muxer;
|
||||
th_subscription_t *sp_s;
|
||||
int sp_ok;
|
||||
} sp_t;
|
||||
|
||||
|
||||
static void
|
||||
sp_done(sp_t *sp)
|
||||
{
|
||||
th_subscription_t *s = sp->sp_s;
|
||||
th_transport_t *t = sp->sp_s->ths_transport;
|
||||
|
||||
dtimer_disarm(&sp->sp_timer);
|
||||
|
||||
muxer_deinit(sp->sp_muxer, s);
|
||||
|
||||
LIST_REMOVE(s, ths_transport_link);
|
||||
free(s);
|
||||
|
||||
TAILQ_REMOVE(&probequeue, t, tht_probe_link);
|
||||
t->tht_on_probe_queue = 0;
|
||||
|
||||
subscription_reschedule();
|
||||
|
||||
serviceprobe_engage();
|
||||
free(sp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
sp_timeout(void *aux, int64_t now)
|
||||
{
|
||||
sp_t *sp = aux;
|
||||
th_transport_t *t = sp->sp_s->ths_transport;
|
||||
|
||||
syslog(LOG_INFO,
|
||||
"Probe %6s %s\n",
|
||||
sp->sp_ok ? "Ok" : "Failed", t->tht_servicename);
|
||||
|
||||
if(sp->sp_ok) {
|
||||
if(t->tht_channel == NULL && t->tht_servicename != NULL) {
|
||||
transport_set_channel(t, t->tht_servicename);
|
||||
t->tht_config_change(t);
|
||||
}
|
||||
}
|
||||
|
||||
sp_done(sp);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sp_packet_input(void *opaque, th_muxstream_t *tms, th_pkt_t *pkt)
|
||||
{
|
||||
sp_t *sp = opaque;
|
||||
|
||||
if(tms->tms_stream->st_type == HTSTV_MPEG2VIDEO ||
|
||||
tms->tms_stream->st_type == HTSTV_H264) {
|
||||
sp->sp_ok = 1;
|
||||
dtimer_arm(&sp->sp_timer, sp_timeout, sp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup IPTV (TS over UDP) output
|
||||
*/
|
||||
|
||||
static void
|
||||
serviceprobe_engage(void)
|
||||
{
|
||||
th_transport_t *t;
|
||||
th_subscription_t *s;
|
||||
th_muxer_t *tm;
|
||||
sp_t *sp;
|
||||
|
||||
if((t = TAILQ_FIRST(&probequeue)) == NULL)
|
||||
return;
|
||||
|
||||
sp = calloc(1, sizeof(sp_t));
|
||||
|
||||
sp->sp_s = s = calloc(1, sizeof(th_subscription_t));
|
||||
s->ths_title = "probe";
|
||||
s->ths_weight = INT32_MAX;
|
||||
|
||||
if(t->tht_status != TRANSPORT_RUNNING)
|
||||
transport_start(t, INT32_MAX);
|
||||
|
||||
s->ths_transport = t;
|
||||
LIST_INSERT_HEAD(&t->tht_subscriptions, s, ths_transport_link);
|
||||
|
||||
sp->sp_muxer = tm = muxer_init(s, sp_packet_input, sp);
|
||||
muxer_play(tm, AV_NOPTS_VALUE);
|
||||
|
||||
dtimer_arm(&sp->sp_timer, sp_timeout, sp, 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
serviceprobe_add(th_transport_t *t)
|
||||
{
|
||||
int was_first = TAILQ_FIRST(&probequeue) == NULL;
|
||||
|
||||
if(t->tht_on_probe_queue)
|
||||
return;
|
||||
|
||||
TAILQ_INSERT_TAIL(&probequeue, t, tht_probe_link);
|
||||
t->tht_on_probe_queue = 1;
|
||||
|
||||
if(was_first)
|
||||
serviceprobe_engage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
serviceprobe_setup(void)
|
||||
{
|
||||
TAILQ_INIT(&probequeue);
|
||||
}
|
26
serviceprobe.h
Normal file
26
serviceprobe.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Functions for transport probing
|
||||
* Copyright (C) 2007 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SERVICE_PROBE_H_
|
||||
#define SERVICE_PROBE_H_
|
||||
|
||||
void serviceprobe_setup(void);
|
||||
|
||||
void serviceprobe_add(th_transport_t *t);
|
||||
|
||||
#endif /* SERVICE_PROBE_H_ */
|
|
@ -52,7 +52,7 @@ struct th_subscription_list subscriptions;
|
|||
static dtimer_t auto_reschedule_timer;
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
subscription_reschedule(void)
|
||||
{
|
||||
th_subscription_t *s;
|
||||
|
@ -151,6 +151,7 @@ subscription_create(th_channel_t *ch, unsigned int weight, const char *name,
|
|||
return s;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
subscription_set_weight(th_subscription_t *s, unsigned int weight)
|
||||
{
|
||||
|
|
|
@ -32,4 +32,6 @@ void subscriptions_init(void);
|
|||
|
||||
void subscription_stop(th_subscription_t *s);
|
||||
|
||||
void subscription_reschedule(void);
|
||||
|
||||
#endif /* SUBSCRIPTIONS_H */
|
||||
|
|
|
@ -151,7 +151,7 @@ transport_stop(th_transport_t *t, int flush_subscriptions)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
static int
|
||||
int
|
||||
transport_start(th_transport_t *t, unsigned int weight)
|
||||
{
|
||||
th_stream_t *st;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
unsigned int transport_compute_weight(struct th_transport_list *head);
|
||||
|
||||
int transport_start(th_transport_t *t, unsigned int weight);
|
||||
|
||||
void transport_stop(th_transport_t *t, int flush_subscriptions);
|
||||
|
||||
th_transport_t *transport_create(const char *identifier, int type,
|
||||
|
|
8
tvhead.h
8
tvhead.h
|
@ -80,6 +80,7 @@ TAILQ_HEAD(event_queue, event);
|
|||
LIST_HEAD(pvr_rec_list, pvr_rec);
|
||||
TAILQ_HEAD(ref_update_queue, ref_update);
|
||||
LIST_HEAD(th_transport_list, th_transport);
|
||||
TAILQ_HEAD(th_transport_queue, th_transport);
|
||||
LIST_HEAD(th_dvb_mux_list, th_dvb_mux);
|
||||
LIST_HEAD(th_dvb_mux_instance_list, th_dvb_mux_instance);
|
||||
LIST_HEAD(th_stream_list, th_stream);
|
||||
|
@ -500,6 +501,13 @@ typedef struct th_transport {
|
|||
int tht_scrambled;
|
||||
int tht_caid;
|
||||
|
||||
/**
|
||||
* Autoprobing support
|
||||
*/
|
||||
|
||||
TAILQ_ENTRY(th_transport) tht_probe_link;
|
||||
int tht_on_probe_queue;
|
||||
|
||||
} th_transport_t;
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue