From: spdfrk Date: Sun, 14 Mar 2021 12:08:58 +0000 (+0100) Subject: remote timeshift: fix crash on multiple subscriptions and cleanup X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ea441d668a3c010f32519201dd02901076d2e19;p=thirdparty%2Ftvheadend.git remote timeshift: fix crash on multiple subscriptions and cleanup --- diff --git a/src/input/mpegts/iptv/iptv_private.h b/src/input/mpegts/iptv/iptv_private.h index b854bdece..c5dcf1367 100644 --- a/src/input/mpegts/iptv/iptv_private.h +++ b/src/input/mpegts/iptv/iptv_private.h @@ -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; }; diff --git a/src/input/mpegts/iptv/iptv_rtcp.c b/src/input/mpegts/iptv/iptv_rtcp.c index 2b37da005..5370dc0b9 100644 --- a/src/input/mpegts/iptv/iptv_rtcp.c +++ b/src/input/mpegts/iptv/iptv_rtcp.c @@ -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; } diff --git a/src/input/mpegts/iptv/iptv_rtsp.c b/src/input/mpegts/iptv/iptv_rtsp.c index 9d1235d8a..3ab0f9170 100644 --- a/src/input/mpegts/iptv/iptv_rtsp.c +++ b/src/input/mpegts/iptv/iptv_rtsp.c @@ -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; } diff --git a/src/input/mpegts/iptv/iptv_udp.c b/src/input/mpegts/iptv/iptv_udp.c index b77688556..599d9e629 100644 --- a/src/input/mpegts/iptv/iptv_udp.c +++ b/src/input/mpegts/iptv/iptv_udp.c @@ -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://@: */ @@ -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; diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index dc28e43bc..08a4c9498 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -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; } diff --git a/src/profile.c b/src/profile.c index 27631f30d..9f5c4f076 100644 --- a/src/profile.c +++ b/src/profile.c @@ -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; } diff --git a/src/streaming.c b/src/streaming.c index 267ccdd9a..0e513e46a 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -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) {