SAT>IP Server: fixed issues for the Elgato SAT>IP Android app
This commit is contained in:
parent
ce01edeb8c
commit
c4adde611f
4 changed files with 92 additions and 64 deletions
19
src/http.c
19
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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -60,11 +60,10 @@ satip_server_http_xml(http_connection_t *hc)
|
|||
<manufacturerURL>http://tvheadend.org</manufacturerURL>\n\
|
||||
<modelDescription>TVHeadend %s</modelDescription>\n\
|
||||
<modelName>TVHeadend SAT>IP</modelName>\n\
|
||||
<modelNumber>1</modelNumber>\n\
|
||||
<modelURL>http://tvheadend.org</modelURL>\n\
|
||||
<modelNumber>1.0</modelNumber>\n\
|
||||
<modelURL></modelURL>\n\
|
||||
<serialNumber>123456</serialNumber>\n\
|
||||
<UDN>uuid:%s</UDN>\n\
|
||||
<UPC>TVHeadend %s</UPC>\n\
|
||||
<iconList>\n\
|
||||
<icon>\n\
|
||||
<mimetype>image/png</mimetype>\n\
|
||||
|
@ -74,7 +73,7 @@ satip_server_http_xml(http_connection_t *hc)
|
|||
<url>http://%s:%d/static/satip-icon40.png</url>\n\
|
||||
</icon>\n\
|
||||
<icon>\n\
|
||||
<mimetype>image/jpg</mimetype>\n\
|
||||
<mimetype>image/jpeg</mimetype>\n\
|
||||
<width>40</width>\n\
|
||||
<height>40</height>\n\
|
||||
<depth>16</depth>\n\
|
||||
|
@ -88,7 +87,7 @@ satip_server_http_xml(http_connection_t *hc)
|
|||
<url>http://%s:%d/static/satip-icon120.png</url>\n\
|
||||
</icon>\n\
|
||||
<icon>\n\
|
||||
<mimetype>image/jpg</mimetype>\n\
|
||||
<mimetype>image/jpeg</mimetype>\n\
|
||||
<width>120</width>\n\
|
||||
<height>120</height>\n\
|
||||
<depth>16</depth>\n\
|
||||
|
@ -100,7 +99,7 @@ satip_server_http_xml(http_connection_t *hc)
|
|||
</device>\n\
|
||||
</root>\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];
|
||||
|
|
Loading…
Add table
Reference in a new issue