From: Jaroslav Kysela Date: Mon, 4 May 2015 19:16:54 +0000 (+0200) Subject: IPTV RTSP: send proper teardown on close X-Git-Tag: v4.1~62 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb6cdcb99d1c230f2c36bdddb888b0d274083ee5;p=thirdparty%2Ftvheadend.git IPTV RTSP: send proper teardown on close --- diff --git a/src/http.h b/src/http.h index d9241d262..ebd3ec8c0 100644 --- a/src/http.h +++ b/src/http.h @@ -323,6 +323,8 @@ struct http_client { struct http_client_ssl *hc_ssl; /* ssl internals */ + gtimer_t hc_close_timer; + /* callbacks */ int (*hc_hdr_received) (http_client_t *hc); int (*hc_data_received)(http_client_t *hc, void *buf, size_t len); diff --git a/src/idnode.c b/src/idnode.c index d1c13a715..ba8af4024 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -215,7 +215,6 @@ idnode_handler(size_t off, idnode_t *in, const char *action) } idc = idc->ic_super; } - } void diff --git a/src/input/mpegts/iptv/iptv_rtsp.c b/src/input/mpegts/iptv/iptv_rtsp.c index 360e116fc..842468890 100644 --- a/src/input/mpegts/iptv/iptv_rtsp.c +++ b/src/input/mpegts/iptv/iptv_rtsp.c @@ -20,15 +20,25 @@ #include "tvheadend.h" #include "iptv_private.h" #include "http.h" -#include "udp.h" typedef struct { http_client_t *hc; udp_multirecv_t um; - char *url; + char *path; + char *query; gtimer_t alive_timer; + int play; } rtsp_priv_t; +/* + * + */ +static void +iptv_rtsp_close_cb ( void *aux ) +{ + http_client_close((http_client_t *)aux); +} + /* * Alive timeout */ @@ -49,22 +59,33 @@ static int iptv_rtsp_header ( http_client_t *hc ) { iptv_mux_t *im = hc->hc_aux; - rtsp_priv_t *rp = im->im_data; + rtsp_priv_t *rp; int r; - if (im == NULL) + if (im == NULL) { + /* teardown (or teardown timeout) */ + if (hc->hc_cmd == RTSP_CMD_TEARDOWN) { + pthread_mutex_lock(&global_lock); + gtimer_arm(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0); + pthread_mutex_unlock(&global_lock); + } return 0; + } if (hc->hc_code != HTTP_STATUS_OK) { tvherror("iptv", "invalid error code %d for '%s'", hc->hc_code, im->mm_iptv_url); return 0; } + rp = im->im_data; + switch (hc->hc_cmd) { case RTSP_CMD_SETUP: r = rtsp_setup_decode(hc, 0); - if (r >= 0) - rtsp_play(hc, rp->url, ""); + if (r >= 0) { + rtsp_play(hc, rp->path, rp->query); + rp->play = 1; + } break; case RTSP_CMD_PLAY: hc->hc_cmd = HTTP_CMD_NONE; @@ -139,7 +160,8 @@ iptv_rtsp_start rp = calloc(1, sizeof(*rp)); rp->hc = hc; udp_multirecv_init(&rp->um, IPTV_PKTS, IPTV_PKT_PAYLOAD); - rp->url = strdup(u->raw); + rp->path = strdup(u->path ?: ""); + rp->query = strdup(u->query ?: ""); im->im_data = rp; im->mm_iptv_fd = rtp->fd; @@ -158,6 +180,7 @@ iptv_rtsp_stop ( iptv_mux_t *im ) { rtsp_priv_t *rp = im->im_data; + int play = rp->play; lock_assert(&global_lock); @@ -165,11 +188,15 @@ iptv_rtsp_stop return; im->im_data = NULL; rp->hc->hc_aux = NULL; + if (play) + rtsp_teardown(rp->hc, rp->path, ""); pthread_mutex_unlock(&iptv_lock); gtimer_disarm(&rp->alive_timer); udp_multirecv_free(&rp->um); - http_client_close(rp->hc); - free(rp->url); + if (!play) + http_client_close(rp->hc); + free(rp->path); + free(rp->query); free(rp); pthread_mutex_lock(&iptv_lock); }