Desktop.ini
#macOS files
.DS_Store
+_codeql_detected_source_root
.list = channel_class_epg_running_list,
.opts = PO_EXPERT | PO_DOC_NLIST,
},
-#if ENABLE_TIMESHIFT
- {
- .type = PT_BOOL,
- .id = "remote_timeshift",
- .name = N_("Remote timeshift"),
- .desc = N_("Pass timeshift commands to a remote RTSP server"),
- .off = offsetof(channel_t, ch_remote_timeshift),
- .opts = PO_ADVANCED,
- },
-#endif
{
.type = PT_STR,
.islist = 1,
int ch_dvr_extra_time_pre;
int ch_dvr_extra_time_post;
int ch_epg_running;
- int ch_remote_timeshift;
LIST_HEAD(, dvr_entry) ch_dvrs;
LIST_HEAD(, dvr_autorec_entry) ch_autorecs;
LIST_HEAD(, dvr_timerec_entry) ch_timerecs;
profile_id = htsmsg_get_str(in, "profile");
#if ENABLE_TIMESHIFT
- if(ch->ch_remote_timeshift) {
- timeshiftPeriod = ~0;
- } else {
- if (timeshift_conf.enabled) {
- timeshiftPeriod = htsmsg_get_u32_or_default(in, "timeshiftPeriod", 0);
- if (!timeshift_conf.unlimited_period)
- timeshiftPeriod = MIN(timeshiftPeriod, timeshift_conf.max_period * 60);
- }
+ if (timeshift_conf.enabled) {
+ timeshiftPeriod = htsmsg_get_u32_or_default(in, "timeshiftPeriod", 0);
+ if (!timeshift_conf.unlimited_period)
+ timeshiftPeriod = MIN(timeshiftPeriod, timeshift_conf.max_period * 60);
}
#endif
streaming_target_init(&hs->hs_input, &htsp_streaming_input_ops, hs, 0);
#if ENABLE_TIMESHIFT
- if (ch->ch_remote_timeshift) {
- tvhdebug(LS_HTSP, "using remote timeshift (RTSP)");
- } else {
- if (timeshiftPeriod != 0) {
- if (timeshiftPeriod == ~0)
- tvhdebug(LS_HTSP, "using timeshift buffer (unlimited)");
- else
- tvhdebug(LS_HTSP, "using timeshift buffer (%u mins)",
- timeshiftPeriod / 60);
- }
+ if (timeshiftPeriod != 0) {
+ if (timeshiftPeriod == ~0)
+ tvhdebug(LS_HTSP, "using timeshift buffer (unlimited)");
+ else
+ tvhdebug(LS_HTSP, "using timeshift buffer (%u mins)",
+ timeshiftPeriod / 60);
}
#endif
pro = profile_find_by_list(htsp->htsp_granted_access->aa_profiles, profile_id,
"htsp", SUBSCRIPTION_PACKET | SUBSCRIPTION_HTSP);
profile_chain_init(&hs->hs_prch, pro, ch, 1);
- if (profile_chain_work(&hs->hs_prch, &hs->hs_input, timeshiftPeriod, ch->ch_remote_timeshift ?
- PROFILE_WORK_REMOTE_TS : PROFILE_WORK_NONE)) {
+ if (profile_chain_work(&hs->hs_prch, &hs->hs_input, timeshiftPeriod)) {
tvherror(LS_HTSP, "unable to create profile chain '%s'", profile_get_name(pro));
profile_chain_close(&hs->hs_prch);
free(hs);
htsmsg_add_u32(rep, "weight", hs->hs_s->ths_weight >= 0 ? hs->hs_s->ths_weight : 0);
#if ENABLE_TIMESHIFT
- if (ch->ch_remote_timeshift) {
+ if (timeshiftPeriod)
htsmsg_add_u32(rep, "timeshiftPeriod", timeshiftPeriod);
- } else {
- if (timeshiftPeriod)
- htsmsg_add_u32(rep, "timeshiftPeriod", timeshiftPeriod);
- }
#endif
htsp_reply(htsp, in, rep);
void iptv_input_unpause ( void *aux );
-struct rtsp_st {
- // Note: input MUST BE FIRST in struct
- streaming_target_t input; ///< Input source
- streaming_target_t *output; ///< Output dest
- streaming_target_t *tsfix;
- pthread_t st_thread;
- volatile int run;
- volatile int rtsp_input_start;
- iptv_mux_t *im;
-};
-
-typedef struct rtsp_st rtsp_st_t;
-#if ENABLE_TIMESHIFT
-void *rtsp_status_thread(void *p) ;
-streaming_target_t* rtsp_st_create(streaming_target_t *out, profile_chain_t *prch);
-void rtsp_st_destroy(streaming_target_t *st);
-#endif
#endif /* __IPTV_PRIVATE_H__ */
/******************************************************************************
return r;
}
-/*
- * Send the status message
- */
-#if ENABLE_TIMESHIFT
-static void rtsp_timeshift_fill_status(rtsp_st_t *ts, rtsp_priv_t *rp,
- timeshift_status_t *status) {
- int64_t start, end, current;
-
- if (rp == NULL) {
- start = 0;
- end = 3600;
- current = 0;
- } else {
- start = 0;
- end = rp->range_end - rp->range_start;
- current = rp->position - rp->range_start;
- }
- status->full = 0;
-
- tvhdebug(LS_TIMESHIFT,
- "remote ts status start %"PRId64" end %"PRId64 " current %"PRId64, start, end,
- current);
-
- status->shift = ts_rescale_inv(current, 1);
- status->pts_start = ts_rescale_inv(start, 1);
- status->pts_end = ts_rescale_inv(end, 1);
-}
-
-static void rtsp_timeshift_status
- ( rtsp_st_t *pd, rtsp_priv_t *rp )
-{
- streaming_message_t *tsm, *tsm2;
- timeshift_status_t *status;
-
- status = calloc(1, sizeof(timeshift_status_t));
- rtsp_timeshift_fill_status(pd, rp, status);
- tsm = streaming_msg_create_data(SMT_TIMESHIFT_STATUS, status);
- tsm2 = streaming_msg_clone(tsm);
- streaming_target_deliver2(pd->output, tsm);
- streaming_target_deliver2(pd->tsfix, tsm2);
-}
-
-void *rtsp_status_thread(void *p) {
- int64_t mono_now, mono_last_status = 0;
- rtsp_st_t *pd = p;
- rtsp_priv_t *rp;
-
- while (pd->run) {
- mono_now = getfastmonoclock();
- if(pd->im == NULL)
- continue;
- rp = (rtsp_priv_t*) pd->im->im_data;
- if(rp == NULL || !pd->rtsp_input_start)
- continue;
- if (mono_now >= (mono_last_status + sec2mono(1))) {
- // In case no buffer updates available assume the buffer is being filled
- if(rp->hc && rp->hc->hc_rtsp_keep_alive_cmd != RTSP_CMD_DESCRIBE)
- rp->range_end++;
- rtsp_timeshift_status(pd, rp);
- mono_last_status = mono_now;
- }
- }
- return NULL;
-}
-
-static void rtsp_input(void *opaque, streaming_message_t *sm) {
- rtsp_st_t *pd = (rtsp_st_t*) opaque;
- iptv_mux_t *mux;
- streaming_skip_t *data;
- rtsp_priv_t *rp;
-
- if(pd == NULL || sm == NULL)
- return;
-
- 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;
- streaming_target_deliver2(pd->output, sm);
- break;
- case SMT_START:
- pd->rtsp_input_start = 1;
- streaming_target_deliver2(pd->output, sm);
- break;
- case SMT_SKIP:
- mux = (iptv_mux_t*) pd->im;
- if (mux == NULL || mux->im_data == NULL)
- break;
- rp = (rtsp_priv_t*) mux->im_data;
- if (rp->start_position == 0)
- rp->start_position = rp->hc->hc_rtsp_stream_start;
- rtsp_pause(rp->hc, rp->path, rp->query);
- mux->mm_iptv_rtp_seq = -1;
- data = (streaming_skip_t*) sm->sm_data;
- rtsp_set_position(rp->hc,
- rp->range_start + ts_rescale(data->time, 1));
- tvhinfo(LS_IPTV, "rtsp: skip: %" PRItime_t " + %" PRId64, rp->range_start,
- ts_rescale(data->time, 1));
- streaming_msg_free(sm);
- break;
- case SMT_SPEED:
- mux = (iptv_mux_t*) pd->im;
- if (mux == NULL || mux->im_data == NULL)
- break;
- rp = (rtsp_priv_t*) mux->im_data;
- tvhinfo(LS_IPTV, "rtsp: set speed: %i", sm->sm_code);
- if (sm->sm_code == 0) {
- rtsp_pause(rp->hc, rp->path, rp->query);
- } else {
- rtsp_set_speed(rp->hc, sm->sm_code / 100);
- }
- streaming_msg_free(sm);
- break;
- case SMT_EXIT:
- pd->run = 0;
- streaming_target_deliver2(pd->output, sm);
- break;
- default:
- streaming_target_deliver2(pd->output, sm);
- }
-}
-
-static htsmsg_t*
-rtsp_input_info(void *opaque, htsmsg_t *list) {
- return list;
-}
-
-static streaming_ops_t rtsp_input_ops =
-{ .st_cb = rtsp_input, .st_info = rtsp_input_info };
-
-streaming_target_t* rtsp_st_create(streaming_target_t *out, profile_chain_t *prch) {
- rtsp_st_t *h = calloc(1, sizeof(rtsp_st_t));
-
- h->output = out;
- h->tsfix = prch->prch_share;
- h->run = 1;
- tvh_thread_create(&h->st_thread, NULL, rtsp_status_thread, h, "rtsp-st");
- streaming_target_init(&h->input, &rtsp_input_ops, h, 0);
-
- return &h->input;
-}
-
-void rtsp_st_destroy(streaming_target_t *st) {
- rtsp_st_t *h = (rtsp_st_t*)st;
- h->run = 0;
- free(st);
-}
-#endif
/*
* Initialise RTSP handler
*/
*/
int
profile_chain_work(profile_chain_t *prch, struct streaming_target *dst,
- uint32_t timeshift_period, profile_work_flags_t flags)
+ uint32_t timeshift_period)
{
profile_t *pro = prch->prch_pro;
if (pro && pro->pro_work)
- return pro->pro_work(prch, dst, timeshift_period, flags);
+ return pro->pro_work(prch, dst, timeshift_period);
return -1;
}
timeshift_destroy(prch->prch_timeshift);
prch->prch_timeshift = NULL;
}
-#if ENABLE_IPTV
- if(prch->prch_rtsp) {
- rtsp_st_destroy(prch->prch_rtsp);
- prch->prch_rtsp = NULL;
- }
-#endif
#endif
if (prch->prch_gh) {
globalheaders_destroy(prch->prch_gh);
static int
profile_htsp_work(profile_chain_t *prch,
streaming_target_t *dst,
- uint32_t timeshift_period, profile_work_flags_t flags)
+ uint32_t timeshift_period)
{
profile_sharer_t *prsh;
prch->prch_share = prsh->prsh_tsfix;
#if ENABLE_TIMESHIFT
-#if ENABLE_IPTV
- if (flags & PROFILE_WORK_REMOTE_TS)
- dst = prch->prch_rtsp = rtsp_st_create(dst, prch);
- else
-#endif
- if (timeshift_period > 0)
- dst = prch->prch_timeshift = timeshift_create(dst, timeshift_period);
+ if (timeshift_period > 0)
+ dst = prch->prch_timeshift = timeshift_create(dst, timeshift_period);
#endif
dst = prch->prch_gh = globalheaders_create(dst);
prch->prch_flags = SUBSCRIPTION_PACKET;
prch->prch_sq.sq_maxsize = qsize;
- r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0);
+ r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0);
if (r) {
profile_chain_close(prch);
return r;
prch->prch_flags = SUBSCRIPTION_PACKET;
prch->prch_sq.sq_maxsize = qsize;
- r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0);
+ r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0);
if (r) {
profile_chain_close(prch);
return r;
prch->prch_flags = SUBSCRIPTION_PACKET;
prch->prch_sq.sq_maxsize = qsize;
- r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0);
+ r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0);
if (r) {
profile_chain_close(prch);
return r;
prch->prch_flags = SUBSCRIPTION_PACKET;
prch->prch_sq.sq_maxsize = qsize;
- r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0);
+ r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0);
if (r) {
profile_chain_close(prch);
return r;
static int
profile_transcode_work(profile_chain_t *prch,
streaming_target_t *dst,
- uint32_t timeshift_period, profile_work_flags_t flags)
+ uint32_t timeshift_period)
{
profile_sharer_t *prsh;
profile_transcode_t *pro = (profile_transcode_t *)prch->prch_pro;
prch->prch_flags = SUBSCRIPTION_PACKET;
prch->prch_sq.sq_maxsize = qsize;
- r = profile_transcode_work(prch, &prch->prch_sq.sq_st, 0, 0);
+ r = profile_transcode_work(prch, &prch->prch_sq.sq_st, 0);
if (r) {
profile_chain_close(prch);
return r;
PROFILE_SVF_UHD
} profile_svfilter_t;
-typedef enum {
- PROFILE_WORK_NONE = 0,
- PROFILE_WORK_REMOTE_TS
-} profile_work_flags_t;
+
struct profile;
struct muxer;
struct streaming_target *prch_tsfix;
#if ENABLE_TIMESHIFT
struct streaming_target *prch_timeshift;
- struct streaming_target *prch_rtsp;
#endif
struct streaming_target prch_input;
struct streaming_target *prch_share;
void (*pro_conf_changed)(struct profile *pro);
int (*pro_work)(profile_chain_t *prch, struct streaming_target *dst,
- uint32_t timeshift_period, profile_work_flags_t flags);
+ uint32_t timeshift_period);
int (*pro_reopen)(profile_chain_t *prch, muxer_config_t *m_cfg,
muxer_hints_t *hints, int flags);
int (*pro_open)(profile_chain_t *prch, muxer_config_t *m_cfg,
}
int profile_chain_work(profile_chain_t *prch, struct streaming_target *dst,
- uint32_t timeshift_period, profile_work_flags_t flags);
+ uint32_t timeshift_period);
int profile_chain_reopen(profile_chain_t *prch,
muxer_config_t *m_cfg,
muxer_hints_t *hints, int flags);
for (n = 0; n < len; n++) {
p = buf + n;
if (strncmp(p, "a=range", 7) == 0) {
- // Parse remote timeshift buffer info
+ // Parse RTSP range info
if (strncmp(p + 8, "npt=", 4) == 0) {
sscanf(p + 8, "npt=%" PRItime_t "-%" PRItime_t, &hc->hc_rtsp_range_start,
&hc->hc_rtsp_range_end);