]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
remote timeshift: fix crash on multiple subscriptions and cleanup
authorspdfrk <spdfrk123456@gmail.com>
Sun, 14 Mar 2021 12:08:58 +0000 (13:08 +0100)
committerFlole998 <Flole998@users.noreply.github.com>
Tue, 16 Mar 2021 03:16:18 +0000 (04:16 +0100)
src/input/mpegts/iptv/iptv_private.h
src/input/mpegts/iptv/iptv_rtcp.c
src/input/mpegts/iptv/iptv_rtsp.c
src/input/mpegts/iptv/iptv_udp.c
src/plumbing/tsfix.c
src/profile.c
src/streaming.c

index b854bdece85571e9a4aa418affce902126cf4370..c5dcf13670f605132fc8b200174bc1058d1b9e30 100644 (file)
@@ -124,6 +124,7 @@ typedef struct {
   /* Connection to the RTCP remote */
   udp_connection_t *connection;
   int connection_fd;
+  udp_multirecv_t um;
 
   uint32_t source_ssrc;
   uint32_t my_ssrc;
@@ -172,6 +173,7 @@ struct iptv_mux
   uint32_t              mm_iptv_rtp_seq;
 
   sbuf_t                mm_iptv_buffer;
+  sbuf_t                im_temp_buffer;
 
   uint32_t              mm_iptv_buffer_limit;
 
@@ -189,11 +191,11 @@ struct iptv_mux
 
   void                 *im_opaque;
 
-  udp_multirecv_t      im_um1;
-  udp_multirecv_t      im_um2;
+  udp_multirecv_t      im_um;
+
   char                 im_use_retransmission;
-  sbuf_t               im_temp_buffer;
   char                 im_is_ce_detected;
+
   rtcp_t               im_rtcp_info;
 };
 
index 2b37da005ed3e041ba88ae7631ee5d900faf8ad2..5370dc0b9e40da2103073671b711fee75bb4125f 100644 (file)
@@ -371,8 +371,8 @@ rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len)
           ssrc, n, (uint32_t )sizeof(network_buffer));
     }
 
-  // Cleanup
-  sbuf_free(&network_buffer);
+    // Cleanup
+    sbuf_free(&network_buffer);
   }
   return 0;
 }
index 9d1235d8a8bbb37c49ffb4ccd0872f8af44c7d5a..3ab0f91702b1e1dc5259969457282b62f936d3c5 100644 (file)
@@ -173,16 +173,16 @@ iptv_rtsp_header ( http_client_t *hc )
         hc->hc_rtcp_server_port, im->mm_iptv_interface, im->mm_nicename) == 0) {
       im->im_use_retransmission = 1;
     }
-    if (rp->start_position == 0) {
-      if (rtsp_play_decode(hc) == 0)
+    if (rtsp_play_decode(hc) == 0) {
+      if (rp->start_position == 0)
         rp->position = rp->start_position = hc->hc_rtsp_stream_start;
-      else
-        rp->position = rp->start_position = time(NULL);
-    } else if (rtsp_play_decode(hc) == 0) {
-      rp->position = hc->hc_rtsp_stream_start;
-      tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t,
-          hc->hc_rtsp_stream_start);
-    }
+      else {
+        rp->position = hc->hc_rtsp_stream_start;
+        tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t,
+            hc->hc_rtsp_stream_start);
+      }
+    } else
+      rp->position = rp->start_position = time(NULL);
     hc->hc_cmd = HTTP_CMD_NONE;
     tvh_mutex_lock(&global_lock);
     if (im->mm_active)
@@ -241,8 +241,8 @@ iptv_rtsp_data
       http_client_close(hc);
       return -1;
     }
-    udp_multirecv_init(&im->im_um1, IPTV_PKTS, IPTV_PKT_PAYLOAD);
-    udp_multirecv_init(&im->im_um2, IPTV_PKTS, IPTV_PKT_PAYLOAD);
+    udp_multirecv_init(&im->im_um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
+    udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
     sbuf_alloc_(&im->im_temp_buffer, IPTV_BUF_SIZE);
     break;
   case RTSP_CMD_GET_PARAMETER:
@@ -303,12 +303,11 @@ iptv_rtsp_start
     return SM_CODE_TUNING_FAILED;
   }
   rp = calloc(1, sizeof(*rp));
-  rtcp_init(&im->im_rtcp_info);
-  im->im_rtcp_info.connection = rtcp;
   rp->hc = hc;
   rp->path = strdup(u->path ?: "");
   rp->query = strdup(u->query ?: "");
 
+  rtcp_init(&im->im_rtcp_info);
   im->im_data = rp;
   im->mm_iptv_fd = rtp->fd;
   im->mm_iptv_connection = rtp;
@@ -340,8 +339,8 @@ iptv_rtsp_stop
     rtsp_teardown(rp->hc, rp->path, "");
   tvh_mutex_unlock(&iptv_lock);
   mtimer_disarm(&rp->alive_timer);
-  udp_multirecv_free(&im->im_um1);
-  udp_multirecv_free(&im->im_um2);
+  udp_multirecv_free(&im->im_um);
+  udp_multirecv_free(&im->im_rtcp_info.um);
   if (!play)
     http_client_close(rp->hc);
   free(rp->path);
@@ -463,16 +462,15 @@ void *rtsp_status_thread(void *p) {
 }
 
 static void rtsp_input(void *opaque, streaming_message_t *sm) {
-  int type = sm->sm_type;
   rtsp_st_t *pd = (rtsp_st_t*) opaque;
   iptv_mux_t *mux;
   streaming_skip_t *data;
   rtsp_priv_t *rp;
 
-  if(pd == NULL)
+  if(pd == NULL || sm == NULL)
     return;
 
-  switch (type) {
+  switch (sm->sm_type) {
   case SMT_GRACE:
     if (sm->sm_s != NULL)
       pd->im = (iptv_mux_t*) ((mpegts_service_t*) sm->sm_s)->s_dvb_mux;
@@ -522,7 +520,6 @@ static void rtsp_input(void *opaque, streaming_message_t *sm) {
 
 static htsmsg_t*
 rtsp_input_info(void *opaque, htsmsg_t *list) {
-
   return list;
 }
 
index b77688556d513e559b2ff622c7eb662439f722fe..599d9e62943d5e6e1d2776eddfd734f6f71e2a08 100644 (file)
@@ -37,7 +37,7 @@ iptv_udp_start
   ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url )
 {
   udp_connection_t *conn;
-  udp_multirecv_init(&im->im_um1, IPTV_PKTS, IPTV_PKT_PAYLOAD);
+  udp_multirecv_init(&im->im_um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
 
   /* Note: url->user is used for specifying multicast source address (SSM)
      here. The URL format is rtp://<srcaddr>@<grpaddr>:<port> */
@@ -56,7 +56,7 @@ iptv_udp_start
   if(im->mm_iptv_ret_url && rtcp_connect(&im->im_rtcp_info, im->mm_iptv_ret_url,
           NULL, 0, im->mm_iptv_interface, im->mm_nicename) == 0) {
       im->im_use_retransmission = 1;
-      udp_multirecv_init(&im->im_um2, IPTV_PKTS, IPTV_PKT_PAYLOAD);
+      udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
       sbuf_reset_and_alloc(&im->im_temp_buffer, IPTV_BUF_SIZE);
   }
 
@@ -72,9 +72,9 @@ iptv_udp_stop
 {
   im->im_data = NULL;
   tvh_mutex_unlock(&iptv_lock);
-  udp_multirecv_free(&im->im_um1);
-  if(&im->im_um2) {
-    udp_multirecv_free(&im->im_um2);
+  udp_multirecv_free(&im->im_um);
+  if(&im->im_rtcp_info.um) {
+    udp_multirecv_free(&im->im_rtcp_info.um);
   }
   if(&im->im_temp_buffer)
     sbuf_free(&im->im_temp_buffer);
@@ -88,7 +88,7 @@ iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im )
   struct iovec *iovec;
   ssize_t res = 0;
 
-  n = udp_multirecv_read(&im->im_um1, im->mm_iptv_fd, IPTV_PKTS, &iovec);
+  n = udp_multirecv_read(&im->im_um, im->mm_iptv_fd, IPTV_PKTS, &iovec);
   if (n < 0)
     return -1;
 
@@ -124,7 +124,7 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l
   char is_ret_buffer = 0;
 
   if (im->im_use_retransmission) {
-    n = udp_multirecv_read(&im->im_um2, im->im_rtcp_info.connection_fd, IPTV_PKTS, &iovec);
+    n = udp_multirecv_read(&im->im_rtcp_info.um, im->im_rtcp_info.connection_fd, IPTV_PKTS, &iovec);
     if (n > 0 && !im->im_is_ce_detected) {
       tvhwarn(LS_IPTV, "RET receiving %d unexpected packets for %s", n,
           im->mm_nicename);
@@ -135,10 +135,10 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l
       im->im_rtcp_info.ce_cnt -= n;
       im->im_rtcp_info.last_received_sequence += n;
     } else {
-      n = udp_multirecv_read(&im->im_um1, im->mm_iptv_fd, IPTV_PKTS, &iovec);
+      n = udp_multirecv_read(&im->im_um, im->mm_iptv_fd, IPTV_PKTS, &iovec);
     }
   } else
-    n = udp_multirecv_read(&im->im_um1, im->mm_iptv_fd, IPTV_PKTS, &iovec);
+    n = udp_multirecv_read(&im->im_um, im->mm_iptv_fd, IPTV_PKTS, &iovec);
 
   if (n < 0)
     return -1;
index dc28e43bc66eb2a228883e00009c52d91d741287..08a4c9498f51c15cbc5f0b50034ace6f3dc810d3 100644 (file)
@@ -237,10 +237,10 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog)
   pkt->pkt_dts &= PTS_MASK;
 
   /* Subtract the transport wide start offset */
-  if (!tf->dts_offset_apply)
-    dts = pts_diff(ref, pkt->pkt_dts);
-  else
+  if (tf->dts_offset_apply)
     dts = pts_diff(ref, pkt->pkt_dts + tf->dts_offset);
+  else
+    dts = pts_diff(ref, pkt->pkt_dts);
 
   if (tfs->tfs_last_dts_norm == PTS_UNSET) {
     if (dts < 0 || pkt->pkt_err) {
@@ -632,7 +632,6 @@ static void
 tsfix_input(void *opaque, streaming_message_t *sm)
 {
   tsfix_t *tf = opaque;
-  timeshift_status_t *status;
 
   switch(sm->sm_type) {
   case SMT_PACKET:
@@ -642,7 +641,6 @@ tsfix_input(void *opaque, streaming_message_t *sm)
     }
     tsfix_input_packet(tf, sm);
     return;
-
   case SMT_START:
     tsfix_stop(tf);
     tsfix_start(tf, sm->sm_data);
@@ -650,26 +648,23 @@ tsfix_input(void *opaque, streaming_message_t *sm)
       streaming_msg_free(sm);
       return;
     }
-
     break;
-
   case SMT_STOP:
     tsfix_stop(tf);
     break;
   case SMT_TIMESHIFT_STATUS:
     if(tf->dts_offset == PTS_UNSET) {
+      timeshift_status_t *status;
       status = sm->sm_data;
       tf->dts_offset = status->shift;
     }
     streaming_msg_free(sm);
     return;
-
   case SMT_SKIP:
     if(tf->dts_offset != PTS_UNSET) {
       tf->dts_offset_apply = 1;
     }
     break;
-
   case SMT_GRACE:
   case SMT_EXIT:
   case SMT_SERVICE_STATUS:
@@ -679,7 +674,6 @@ tsfix_input(void *opaque, streaming_message_t *sm)
   case SMT_NOSTART_WARN:
   case SMT_MPEGTS:
   case SMT_SPEED:
-
     break;
   }
 
index 27631f30d492f2efc7a3b3625ade19edc8d292af..9f5c4f076342e60b5580526ff1acfe9868c1a875 100644 (file)
@@ -641,8 +641,6 @@ profile_deliver(profile_chain_t *prch, streaming_message_t *sm)
     }
     sm2 = streaming_msg_create_data(SMT_START,
                                    streaming_start_copy(prsh->prsh_start_msg));
-    if (sm)
-      sm2->sm_s = sm->sm_s;
     streaming_target_deliver(prch->prch_post_share, sm2);
     prch->prch_start_pending = 0;
   }
index 267ccdd9ad79570201fc49278b1540f1d3a385ac..0e513e46a0b07d03fdca3ea4c60768d1c4d57e58 100644 (file)
@@ -201,11 +201,12 @@ streaming_target_disconnect(streaming_pad_t *sp, streaming_target_t *st)
 streaming_message_t *
 streaming_msg_create(streaming_message_type_t type)
 {
-  streaming_message_t *sm = calloc(1, sizeof(streaming_message_t));
+  streaming_message_t *sm = malloc(sizeof(streaming_message_t));
   memoryinfo_alloc(&streaming_msg_memoryinfo, sizeof(*sm));
   sm->sm_type = type;
 #if ENABLE_TIMESHIFT
   sm->sm_time = 0;
+  sm->sm_s = NULL;
 #endif
   return sm;
 }
@@ -263,6 +264,7 @@ streaming_msg_clone(streaming_message_t *src)
   dst->sm_type      = src->sm_type;
 #if ENABLE_TIMESHIFT
   dst->sm_time      = src->sm_time;
+  dst->sm_s         = src->sm_s;
 #endif
 
   switch(src->sm_type) {