diff --git a/src/http.c b/src/http.c
index 9f1f8cca..ec0bbecd 100644
--- a/src/http.c
+++ b/src/http.c
@@ -949,6 +949,8 @@ http_parse_get_args(http_connection_t *hc, char *args)
{
char *k, *v;
+ if (args && *args == '&')
+ args++;
while(args) {
k = args;
if((args = strchr(args, '=')) == NULL)
@@ -1008,13 +1010,18 @@ http_serve_requests(http_connection_t *hc)
goto error;
if(!*hdrline)
- break; /* header complete */
+ break; /* header complete */
- if((n = http_tokenize(hdrline, argv, 2, -1)) < 2)
- continue;
-
- if((c = strrchr(argv[0], ':')) == NULL)
- goto error;
+ if((n = http_tokenize(hdrline, argv, 2, -1)) < 2) {
+ if ((c = strchr(hdrline, ':')) != NULL) {
+ *c = '\0';
+ argv[0] = hdrline;
+ argv[1] = c + 1;
+ } else {
+ continue;
+ }
+ } else if((c = strrchr(argv[0], ':')) == NULL)
+ goto error;
*c = 0;
http_arg_set(&hc->hc_args, argv[0], argv[1]);
diff --git a/src/satip/rtp.c b/src/satip/rtp.c
index ef372578..d1c39fd2 100644
--- a/src/satip/rtp.c
+++ b/src/satip/rtp.c
@@ -48,6 +48,7 @@ typedef struct satip_rtp_session {
int um_packet;
uint16_t seq;
signal_status_t sig;
+ int sig_lock;
pthread_mutex_t lock;
} satip_rtp_session_t;
@@ -114,6 +115,8 @@ satip_rtp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len)
struct iovec *v = rtp->um_iovec + rtp->um_packet;
assert((len % 188) == 0);
+ if (len > 0)
+ rtp->sig_lock = 1;
for ( ; len >= 188 ; data += 188, len -= 188) {
pid = ((data[1] & 0x1f) << 8) | data[2];
if (pid != last_pid && !rtp->pids.all) {
@@ -372,8 +375,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
const char *bw, *tmode, *gi, *plp, *t2id, *sm, *c2tft, *ds, *specinv;
int i, j, r, level = 0, lock = 0, quality = 0;
- if (rtp->sig.snr > 0)
- lock = 1;
+ lock = rtp->sig_lock;
switch (rtp->sig.signal_scale) {
case SIGNAL_STATUS_SCALE_RELATIVE:
level = MIN(240, MAX(0, (rtp->sig.signal * 245) / 0xffff));
@@ -382,6 +384,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
level = MIN(240, MAX(0, (rtp->sig.signal + 90000) / 375));
break;
default:
+ level = lock ? 10 : 0;
break;
}
switch (rtp->sig.snr_scale) {
@@ -392,6 +395,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
quality = MIN(15, MAX(0, (rtp->sig.snr / 2000)));
break;
default:
+ quality = lock ? 1 : 0;
break;
}
diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c
index 390b0773..f57df44d 100644
--- a/src/satip/rtsp.c
+++ b/src/satip/rtsp.c
@@ -300,6 +300,10 @@ rtsp_clean(session_t *rs)
{
slave_subscription_t *sub;
+ if (rs->run) {
+ satip_rtp_close((void *)(intptr_t)rs->stream);
+ rs->run = 0;
+ }
if (rs->subs) {
while ((sub = LIST_FIRST(&rs->slaves)) != NULL)
rtsp_slave_remove(rs, (mpegts_service_t *)rs->subs->ths_service,
@@ -321,6 +325,7 @@ rtsp_clean(session_t *rs)
static int
rtsp_validate_service(mpegts_service_t *s)
{
+ int av = 0, enc = 0;
elementary_stream_t *st;
pthread_mutex_lock(&s->s_stream_mutex);
@@ -328,12 +333,15 @@ rtsp_validate_service(mpegts_service_t *s)
pthread_mutex_unlock(&s->s_stream_mutex);
return 0;
}
- TAILQ_FOREACH(st, &s->s_components, es_link)
+ TAILQ_FOREACH(st, &s->s_components, es_link) {
+ if (st->es_type == SCT_CA)
+ enc = 1;
if (st->es_pid > 0 &&
(SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
- break;
+ av = 1;
+ }
pthread_mutex_unlock(&s->s_stream_mutex);
- return st != NULL;
+ return enc && av;
}
/*
@@ -398,7 +406,8 @@ end:
*/
static int
rtsp_start
- (http_connection_t *hc, session_t *rs, char *addrbuf, int newmux, int setup)
+ (http_connection_t *hc, session_t *rs, char *addrbuf,
+ int newmux, int setup, int oldrun)
{
mpegts_network_t *mn, *mn2;
dvb_network_t *ln;
@@ -422,22 +431,24 @@ rtsp_start
}
}
if (mux == NULL && mn2) {
+ dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf));
+ tvhwarn("satips", "%i/%s/%i: create mux %s",
+ rs->frontend, rs->session, rs->stream, buf);
mux = (dvb_mux_t *)
mn2->mn_create_mux(mn2, (void *)(intptr_t)rs->nsession,
MPEGTS_ONID_NONE, MPEGTS_TSID_NONE,
- &rs->dmc, 0);
+ &rs->dmc, 1);
if (mux)
created = 1;
}
if (mux == NULL) {
dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf));
- tvhwarn("satips", "%i: unable to create mux %s", rs->frontend, buf);
+ tvhwarn("satips", "%i/%s/%i: unable to create mux %s",
+ rs->frontend, rs->session, rs->stream, buf);
goto endclean;
}
if (rs->mux == mux)
goto pids;
- if (rs->run)
- satip_rtp_close((void *)(intptr_t)rs->stream);
rtsp_clean(rs);
rs->mux = mux;
rs->mux_created = created;
@@ -452,9 +463,9 @@ rtsp_start
http_arg_get(&hc->hc_args, "User-Agent"),
NULL);
if (!rs->subs)
- goto endrtp;
- if (rs->run) {
- /* restart streaming */
+ goto endclean;
+ /* retrigger play when new setup arrived */
+ if (oldrun) {
setup = 0;
rs->run = 0;
}
@@ -466,7 +477,7 @@ pids:
}
if (!setup && !rs->run) {
if (rs->mux == NULL)
- goto endrtp;
+ goto endclean;
satip_rtp_queue((void *)(intptr_t)rs->stream,
rs->subs, &rs->prch.prch_sq,
hc->hc_peer, rs->rtp_peer_port,
@@ -481,9 +492,6 @@ pids:
pthread_mutex_unlock(&global_lock);
return 0;
-endrtp:
- satip_rtp_close((void *)(intptr_t)rs->stream);
- rs->run = 0;
endclean:
rtsp_clean(rs);
pthread_mutex_unlock(&global_lock);
@@ -598,7 +606,7 @@ rtsp_process_describe(http_connection_t *hc)
session_t *rs;
htsbuf_queue_t q;
char buf[96];
- int stream;
+ int stream, first = 1;
htsbuf_queue_init(&q, 0);
@@ -614,27 +622,30 @@ rtsp_process_describe(http_connection_t *hc)
if (TAILQ_FIRST(&hc->hc_req_args))
goto error;
- if (hc->hc_session) {
- pthread_mutex_lock(&rtsp_lock);
- TAILQ_FOREACH(rs, &rtsp_sessions, link)
- if (rs->stream == stream)
- break;
- if (rs) {
- rtsp_describe_header(rs, &q);
- rtsp_describe_session(rs, &q);
+ pthread_mutex_lock(&rtsp_lock);
+ TAILQ_FOREACH(rs, &rtsp_sessions, link) {
+ if (hc->hc_session) {
+ if (strcmp(hc->hc_session, rs->session))
+ continue;
+ if (stream > 0 && rs->stream != stream)
+ continue;
}
- pthread_mutex_unlock(&rtsp_lock);
- if (rs == NULL) {
+ if (first) {
+ rtsp_describe_header(hc->hc_session ? rs : NULL, &q);
+ first = 0;
+ }
+ rtsp_describe_session(rs, &q);
+ }
+ pthread_mutex_unlock(&rtsp_lock);
+
+ if (first) {
+ if (hc->hc_session) {
http_error(hc, HTTP_STATUS_BAD_SESSION);
return 0;
}
- } else {
- pthread_mutex_lock(&rtsp_lock);
rtsp_describe_header(NULL, &q);
- TAILQ_FOREACH(rs, &rtsp_sessions, link)
- rtsp_describe_session(rs, &q);
- pthread_mutex_unlock(&rtsp_lock);
}
+
http_arg_init(&args);
if (hc->hc_session)
http_arg_set(&args, "Session", hc->hc_session);
@@ -875,7 +886,7 @@ static int
rtsp_process_play(http_connection_t *hc, int setup)
{
session_t *rs;
- int errcode = HTTP_STATUS_BAD_REQUEST, r, findex = 0, valid;
+ int errcode = HTTP_STATUS_BAD_REQUEST, r, findex = 0, valid, oldrun = 0;
int stream, delsys = DVB_SYS_NONE, msys, fe, src, freq, pol, sr;
int fec, ro, plts, bw, tmode, mtype, gi, plp, t2id, sm, c2tft, ds, specinv;
char *u, *s;
@@ -922,19 +933,22 @@ rtsp_process_play(http_connection_t *hc, int setup)
delsys = rtsp_delsys(fe, &findex);
if (delsys == DVB_SYS_NONE)
goto error;
+ } else {
+ delsys = msys;
}
if (setup) {
if (delsys == DVB_SYS_NONE) goto error;
if (msys == DVB_SYS_NONE) goto error;
- if (!fe) goto error;
if (!valid) goto error;
if (!rs)
rs = rtsp_new_session(msys, 0, -1);
else if (stream != rs->stream)
rs = rtsp_new_session(msys, rs->nsession, stream);
- else
+ else {
+ oldrun = rs->run;
rtsp_close_session(rs);
+ }
r = parse_transport(hc);
if (r < 0) {
errcode = HTTP_STATUS_BAD_TRANSFER;
@@ -944,7 +958,7 @@ rtsp_process_play(http_connection_t *hc, int setup)
errcode = HTTP_STATUS_METHOD_INVALID;
goto error;
}
- rs->frontend = fe;
+ rs->frontend = fe > 0 ? fe : 1;
rs->rtp_peer_port = r;
dmc = &rs->dmc;
} else {
@@ -953,6 +967,7 @@ rtsp_process_play(http_connection_t *hc, int setup)
errcode = HTTP_STATUS_NOT_FOUND;
goto error;
}
+ oldrun = rs->run;
dmc = &rs->dmc;
if (rs->mux == NULL) goto error;
if (!fe) {
@@ -1106,13 +1121,13 @@ play:
mpegts_pid_del_group(&rs->pids, &delpids);
if (addpids.count > 0)
mpegts_pid_add_group(&rs->pids, &addpids);
- if ((r = rtsp_start(hc, rs, addrbuf, valid, setup)) < 0) {
+ if ((r = rtsp_start(hc, rs, addrbuf, valid, setup, oldrun)) < 0) {
errcode = r;
goto error;
}
if (setup)
- tvhdebug("satips", "%i/%s/%d: setup from %s:%d, RTP: %d, RTCP: %d, pids ",
+ tvhdebug("satips", "%i/%s/%d: setup from %s:%d, RTP: %d, RTCP: %d",
rs->frontend, rs->session, rs->stream,
addrbuf, IP_PORT(*hc->hc_peer),
rs->rtp_peer_port, rs->rtp_peer_port + 1);
diff --git a/src/satip/server.c b/src/satip/server.c
index 24d96bed..150c11bc 100644
--- a/src/satip/server.c
+++ b/src/satip/server.c
@@ -60,11 +60,10 @@ satip_server_http_xml(http_connection_t *hc)
http://tvheadend.org\n\
TVHeadend %s\n\
TVHeadend SAT>IP\n\
-1\n\
-http://tvheadend.org\n\
+1.0\n\
+\n\
123456\n\
uuid:%s\n\
-TVHeadend %s\n\
\n\
\n\
image/png\n\
@@ -74,7 +73,7 @@ satip_server_http_xml(http_connection_t *hc)
http://%s:%d/static/satip-icon40.png\n\
\n\
\n\
-image/jpg\n\
+image/jpeg\n\
40\n\
40\n\
16\n\
@@ -88,7 +87,7 @@ satip_server_http_xml(http_connection_t *hc)
http://%s:%d/static/satip-icon120.png\n\
\n\
\n\
-image/jpg\n\
+image/jpeg\n\
120\n\
120\n\
16\n\
@@ -100,7 +99,7 @@ satip_server_http_xml(http_connection_t *hc)
\n\
\n"
- char buf[sizeof(MSG) + 1024], buf2[16];
+ char buf[sizeof(MSG) + 1024], buf2[64];
char *devicelist = NULL;
htsbuf_queue_t q;
mpegts_network_t *mn;
@@ -122,18 +121,18 @@ satip_server_http_xml(http_connection_t *hc)
} else if (idnode_is_instance(&mn->mn_id, &dvb_network_dvbc_class))
dvbc++;
}
- if (dvbt && (i = config_get_int("satip_dvbt", 0)) > 0) {
- htsbuf_qprintf(&q, "DVBT-%d", i);
- delim++;
- } else {
- dvbt = 0;
- }
if (dvbs && (i = config_get_int("satip_dvbs", 0)) > 0) {
htsbuf_qprintf(&q, "%sDVBS2-%d", delim ? "," : "", i);
delim++;
} else {
dvbs = 0;
}
+ if (dvbt && (i = config_get_int("satip_dvbt", 0)) > 0) {
+ htsbuf_qprintf(&q, "%sDVBT-%d", delim ? "," : "", i);
+ delim++;
+ } else {
+ dvbt = 0;
+ }
if (dvbc && (i = config_get_int("satip_dvbc", 0)) > 0) {
htsbuf_qprintf(&q, "%sDVBC-%d", delim ? "," : "", i);
delim++;
@@ -153,13 +152,14 @@ satip_server_http_xml(http_connection_t *hc)
buf, dvbt + dvbs + dvbc ? "tuner settings - global config" : "network assignment");
}
- buf2[0] = '\0';
if (satip_server_rtsp_port != 554)
- snprintf(buf2, sizeof(buf2), ":%d", satip_server_rtsp_port);
+ snprintf(buf2, sizeof(buf2), ":%d %s", satip_server_rtsp_port, satip_server_uuid + 26);
+ else
+ snprintf(buf2, sizeof(buf2), " %s", satip_server_uuid + 26);
snprintf(buf, sizeof(buf), MSG,
buf2, tvheadend_version,
- satip_server_uuid, tvheadend_version,
+ satip_server_uuid,
http_server_ip, http_server_port,
http_server_ip, http_server_port,
http_server_ip, http_server_port,
@@ -170,8 +170,10 @@ satip_server_http_xml(http_connection_t *hc)
free(devicelist);
http_arg_init(&args);
- snprintf(buf2, sizeof(buf2), "%d", satip_server_rtsp_port);
- http_arg_set(&args, "X-SATIP-RTSP-Port", buf2);
+ if (satip_server_rtsp_port != 554) {
+ snprintf(buf2, sizeof(buf2), "%d", satip_server_rtsp_port);
+ http_arg_set(&args, "X-SATIP-RTSP-Port", buf2);
+ }
if (srcs) {
snprintf(buf2, sizeof(buf2), "%d", srcs);
http_arg_set(&args, "X-SATIP-Sources", buf2);
@@ -405,9 +407,9 @@ satips_upnp_discovery_received
if (http_tokenize(ptr, argv, 2, ':') == 2) {
if (strcmp(argv[0], "ST") == 0)
st = argv[1];
- else if (strcmp(argv[0], "HOST") == 0)
+ else if (strcasecmp(argv[0], "HOST") == 0)
host = argv[1];
- else if (strcmp(argv[0], "MAN") == 0)
+ else if (strcasecmp(argv[0], "MAN") == 0)
man = argv[1];
else if (strcmp(argv[0], "DEVICEID.SES.COM") == 0)
deviceid = argv[1];