return r;
}
+static void
+satip_frontend_extra_shutdown
+ ( satip_frontend_t *lfe, uint8_t *session, long stream_id )
+{
+ http_client_t *rtsp;
+ tvhpoll_t *efd;
+ tvhpoll_event_t ev;
+ int r, nfds;
+ char b[32];
+
+ if (session[0] == '\0' || stream_id <= 0)
+ return;
+
+ efd = tvhpoll_create(1);
+ rtsp = http_client_connect(lfe, RTSP_VERSION_1_0, "rstp",
+ lfe->sf_device->sd_info.addr, 554,
+ satip_frontend_bindaddr(lfe));
+ if (rtsp == NULL)
+ goto done;
+
+ rtsp->hc_rtsp_session = strdup((char *)session);
+
+ memset(&ev, 0, sizeof(ev));
+ ev.events = TVHPOLL_IN;
+ ev.fd = rtsp->hc_fd;
+ ev.data.ptr = rtsp;
+ tvhpoll_add(efd, &ev, 1);
+ rtsp->hc_efd = efd;
+
+ snprintf(b, sizeof(b), "/stream=%li", stream_id);
+ r = rtsp_teardown(rtsp, b, NULL);
+ if (r < 0) {
+ tvhtrace("satip", "bad shutdown for session %s stream id %li", session, stream_id);
+ } else {
+ while (1) {
+ r = http_client_run(rtsp);
+ if (r != HTTP_CON_RECEIVING && r != HTTP_CON_SENDING) {
+ printf("%s", rtsp->hc_data);
+ break;
+ }
+ nfds = tvhpoll_wait(efd, &ev, 1, 100);
+ if (nfds == 0)
+ break;
+ if (nfds < 0) {
+ if (ERRNO_AGAIN(errno))
+ continue;
+ break;
+ }
+ if(ev.events & (TVHPOLL_ERR | TVHPOLL_HUP))
+ break;
+ }
+ }
+
+ http_client_close(rtsp);
+ tvhlog(LOG_INFO, "satip", "extra shutdown done for session %s", session);
+
+done:
+ tvhpoll_destroy(efd);
+}
+
static void
satip_frontend_shutdown1 ( http_client_t *rtsp, tvhpoll_t *efd,
int shutdown2, int timeout )
}
static void
-satip_frontend_shutdown ( http_client_t *rtsp, tvhpoll_t *efd, int shutdown2 )
+satip_frontend_shutdown
+ ( satip_frontend_t *lfe, http_client_t *rtsp, tvhpoll_t *efd, int shutdown2 )
{
satip_frontend_shutdown1(rtsp, efd, shutdown2, 250);
if (shutdown2)
dvb_mux_t *lm;
char buf[256];
struct iovec *iovec;
- uint8_t b[2048];
+ uint8_t b[2048], session[32];
uint8_t *p;
sbuf_t sb;
int pos, nfds, i, r, tc, rtp_port, start = 0;
size_t c;
tvhpoll_event_t ev[3];
tvhpoll_t *efd;
- int changing, ms, fatal, running, play2, exit_flag, rtsp_flags, position, reply;
+ int changing, ms, fatal, running, play2, exit_flag;
+ int rtsp_flags, position, reply;
uint32_t seq, nseq, unc;
udp_multirecv_t um;
uint64_t u64, u64_2;
+ long stream_id;
/* If set - the thread will be cancelled */
exit_flag = 0;
+ /* Remember session for extra shutdown (workaround for IDL4K firmware bug) */
+ session[0] = '\0';
+ stream_id = 0;
/* Setup poll */
efd = tvhpoll_create(4);
if (!tvheadend_running) { exit_flag = 1; goto done; }
if (rtsp && nfds == 0) {
- satip_frontend_shutdown(rtsp, efd, lfe->sf_device->sd_shutdown2);
+ satip_frontend_shutdown(lfe, rtsp, efd, lfe->sf_device->sd_shutdown2);
http_client_close(rtsp);
rtsp = NULL;
}
rtsp_flags);
pthread_mutex_unlock(&lfe->sf_dvr_lock);
if (r < 0) {
- tvherror("satip", "%s - failed to tune", buf);
+ tvherror("satip", "%s - failed to tune (%i)", buf, r);
satip_frontend_tuning_error(lfe, tr);
goto done;
}
if (ev[0].data.ptr == rtsp) {
r = http_client_run(rtsp);
if (r < 0) {
+ if (rtsp->hc_code == 404) {
+ tvhlog(LOG_WARNING, "satip", "%s - RTSP 404 ERROR (retrying)", buf);
+ satip_frontend_extra_shutdown(lfe, session, stream_id);
+ start = 1;
+ http_client_close(rtsp);
+ rtsp = NULL;
+ break;
+ }
tvhlog(LOG_ERR, "satip", "%s - RTSP error %d (%s) [%i-%i]",
buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code);
satip_frontend_tuning_error(lfe, tr);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
} else {
+ strncpy((char *)session, rtsp->hc_rtsp_session ?: "", sizeof(session));
+ session[sizeof(session)-1] = '\0';
+ stream_id = rtsp->hc_rtsp_stream_id;
tvhdebug("satip", "%s #%i - new session %s stream id %li",
rtsp->hc_host, lfe->sf_number,
rtsp->hc_rtsp_session, rtsp->hc_rtsp_stream_id);
rtsp_flags | SATIP_SETUP_PLAY);
pthread_mutex_unlock(&lfe->sf_dvr_lock);
if (r < 0) {
- tvherror("satip", "%s - failed to tune2", buf);
+ tvherror("satip", "%s - failed to tune2 (%i)", buf, r);
satip_frontend_tuning_error(lfe, tr);
fatal = 1;
}
tvhpoll_rem(efd, ev, 3);
if (exit_flag) {
- satip_frontend_shutdown(rtsp, efd, lfe->sf_device->sd_shutdown2);
+ satip_frontend_shutdown(lfe, rtsp, efd, lfe->sf_device->sd_shutdown2);
http_client_close(rtsp);
rtsp = NULL;
}