de->de_s = subscription_create_from_channel(prch, NULL, weight,
buf, prch->prch_flags,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (de->de_s == NULL) {
tvherror("dvr", "unable to create new channel subcription for '%s'",
channel_get_name(de->de_channel));
pthread_join(de->de_thread, NULL);
- subscription_unsubscribe(de->de_s);
+ subscription_unsubscribe(de->de_s, 0);
de->de_s = NULL;
de->de_chain = NULL;
/* Subscribe to the mux */
om->om_requeue = 1;
if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab", SUBSCRIPTION_PRIO_EPG,
- SUBSCRIPTION_EPG))) {
+ SUBSCRIPTION_EPG | SUBSCRIPTION_ONESHOT))) {
TAILQ_INSERT_TAIL(&epggrab_ota_pending, om, om_q_link);
om->om_q_type = EPGGRAB_OTA_MUX_PENDING;
if (r == SM_CODE_NO_FREE_ADAPTER)
LIST_REMOVE(hs, hs_link);
LIST_INSERT_HEAD(&htsp->htsp_dead_subscriptions, hs, hs_link);
- subscription_unsubscribe(hs->hs_s);
+ subscription_unsubscribe(hs->hs_s, 0);
if(hs->hs_prch.prch_st != NULL)
profile_chain_close(&hs->hs_prch);
SUBSCRIPTION_STREAMING,
htsp->htsp_peername,
htsp->htsp_username,
- htsp->htsp_clientname);
+ htsp->htsp_clientname,
+ NULL);
return NULL;
}
{
profile_chain_t prch;
th_subscription_t *s;
+ int err = 0;
memset(&prch, 0, sizeof(prch));
prch.prch_id = mm;
s = subscription_create_from_mux(&prch, (tvh_input_t *)mi,
weight, name,
SUBSCRIPTION_NONE | flags,
- NULL, NULL, NULL);
- return s ? 0 : -EIO;
+ NULL, NULL, NULL, &err);
+ return s ? 0 : (err ? err : SM_CODE_UNDEFINED_ERROR);
}
void
n = LIST_NEXT(s, ths_global_link);
t = s->ths_service;
if (t && t->s_type == STYPE_RAW && !strcmp(s->ths_title, name))
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
s = n;
}
}
/* Upate timer */
if (!mms->mms_enabled) {
if (mms->mms_sub)
- subscription_unsubscribe(mms->mms_sub);
+ subscription_unsubscribe(mms->mms_sub, 0);
mms->mms_sub = NULL;
mms->mms_active = 0;
gtimer_disarm(&mms->mms_timer);
= subscription_create_from_mux(mms->mms_prch, NULL, mms->mms_weight,
mms->mms_creator ?: "",
SUBSCRIPTION_NONE,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
/* Failed (try-again soon) */
if (!mms->mms_sub) {
/* Cancel sub */
} else {
if (mms->mms_sub) {
- subscription_unsubscribe(mms->mms_sub);
+ subscription_unsubscribe(mms->mms_sub, 0);
mms->mms_sub = NULL;
}
mms->mms_active = 0;
if (delconf)
hts_settings_remove("muxsched/%s", idnode_uuid_as_str(&mms->mms_id));
if (mms->mms_sub)
- subscription_unsubscribe(mms->mms_sub);
+ subscription_unsubscribe(mms->mms_sub, 0);
gtimer_disarm(&mms->mms_timer);
idnode_unlink(&mms->mms_id);
free(mms->mms_cronstr);
if (mm->mm_active) continue;
/* Attempt to tune */
- r = mpegts_mux_subscribe(mm, NULL, "scan", mm->mm_scan_weight, mm->mm_scan_flags);
+ r = mpegts_mux_subscribe(mm, NULL, "scan", mm->mm_scan_weight,
+ mm->mm_scan_flags | SUBSCRIPTION_ONESHOT);
/* Started */
if (!r) {
rtsp_clean(session_t *rs)
{
if (rs->subs) {
- subscription_unsubscribe(rs->subs);
+ subscription_unsubscribe(rs->subs, 0);
rs->subs = NULL;
}
if (rs->prch.prch_pro)
rs->prch.prch_flags |
SUBSCRIPTION_STREAMING,
addrbuf, hc->hc_username,
- http_arg_get(&hc->hc_args, "User-Agent"));
+ http_arg_get(&hc->hc_args, "User-Agent"),
+ NULL);
if (!rs->subs)
goto endrtp;
if (rs->run) {
prch.prch_id = s;
sub = subscription_create_from_service(&prch, NULL, SUBSCRIPTION_PRIO_MAPPER,
"service_mapper",
- 0, NULL, NULL, "service_mapper");
+ 0, NULL, NULL, "service_mapper",
+ NULL);
/* Failed */
if (!sub) {
pthread_mutex_unlock(&sq->sq_mutex);
pthread_mutex_lock(&global_lock);
- subscription_unsubscribe(sub);
+ subscription_unsubscribe(sub, 0);
if(err) {
tvhinfo("service_mapper", "%s: failed [err %s]", s->s_nicename, err);
subscription_reschedule();
}
+/**
+ *
+ */
+static service_instance_t *
+subscription_start_instance
+ (th_subscription_t *s, int *error)
+{
+ service_instance_t *si;
+
+ if (s->ths_channel)
+ tvhtrace("subscription", "%04X: find service for %s weight %d",
+ shortid(s), channel_get_name(s->ths_channel), s->ths_weight);
+ else
+ tvhtrace("subscription", "%04X: find instance for %s weight %d",
+ shortid(s), s->ths_service->s_nicename, s->ths_weight);
+ si = service_find_instance(s->ths_service, s->ths_channel,
+ s->ths_source,
+ &s->ths_instances, error, s->ths_weight,
+ s->ths_flags, s->ths_timeout,
+ dispatch_clock > s->ths_postpone_end ?
+ 0 : s->ths_postpone_end - dispatch_clock);
+ return s->ths_current_instance = si;
+}
/**
*
}
error = s->ths_testing_error;
- if (s->ths_channel)
- tvhtrace("subscription", "%04X: find service for %s weight %d",
- shortid(s), channel_get_name(s->ths_channel), s->ths_weight);
- else
- tvhtrace("subscription", "%04X: find instance for %s weight %d",
- shortid(s), s->ths_service->s_nicename, s->ths_weight);
- si = service_find_instance(s->ths_service, s->ths_channel,
- s->ths_source,
- &s->ths_instances, &error, s->ths_weight,
- s->ths_flags, s->ths_timeout,
- dispatch_clock > s->ths_postpone_end ?
- 0 : s->ths_postpone_end - dispatch_clock);
+ si = subscription_start_instance(s, &error);
s->ths_current_instance = si;
if(si == NULL) {
while ((s = LIST_FIRST(&subscriptions_remove))) {
LIST_REMOVE(s, ths_remove_link);
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
}
if (postpone <= 0 || postpone == INT_MAX)
* Delete
*/
void
-subscription_unsubscribe(th_subscription_t *s)
+subscription_unsubscribe(th_subscription_t *s, int quiet)
{
service_t *t = s->ths_service;
char buf[512];
s->ths_username ?: "<N/A>",
s->ths_client ?: "<N/A>");
}
- tvhlog(LOG_INFO, "subscription", "%04X: %s", shortid(s), buf);
+ tvhlog(quiet ? LOG_TRACE : LOG_INFO, "subscription", "%04X: %s", shortid(s), buf);
if (t) {
service_remove_subscriber(t, s, SM_CODE_OK);
const char *hostname,
const char *username,
const char *client,
+ int *error,
service_t *service)
{
th_subscription_t *s;
assert(prch);
assert(prch->prch_id);
+ if (error)
+ *error = 0;
+
if (!service)
ch = prch->prch_id;
tvhtrace("subscription", "%04X: creating subscription for %s weight %d using profile %s",
shortid(s), channel_get_name(ch), weight, pro_name);
else
- tvhtrace("subscription", "%04X: creating subscription for service %s weight %d sing profile %s",
+ tvhtrace("subscription", "%04X: creating subscription for service %s weight %d using profile %s",
shortid(s), service->s_nicename, weight, pro_name);
#endif
s->ths_channel = ch;
}
#endif
- subscription_reschedule();
+ if (flags & SUBSCRIPTION_ONESHOT) {
+ if (subscription_start_instance(s, error) == NULL) {
+ subscription_unsubscribe(s, 1);
+ return NULL;
+ }
+ } else {
+ subscription_reschedule();
+ }
return s;
}
tvh_input_t *ti,
unsigned int weight,
const char *name,
- int flags, const char *hostname,
- const char *username, const char *client)
+ int flags,
+ const char *hostname,
+ const char *username,
+ const char *client,
+ int *error)
{
assert(prch->prch_st);
return subscription_create_from_channel_or_service
- (prch, ti, weight, name, flags, hostname, username, client, NULL);
+ (prch, ti, weight, name, flags, hostname, username, client,
+ error, NULL);
}
/**
unsigned int weight,
const char *name,
int flags,
- const char *hostname, const char *username,
- const char *client)
+ const char *hostname,
+ const char *username,
+ const char *client,
+ int *error)
{
assert(prch->prch_st);
return subscription_create_from_channel_or_service
(prch, ti, weight, name, flags, hostname, username, client,
- prch->prch_id);
+ error, prch->prch_id);
}
/**
int flags,
const char *hostname,
const char *username,
- const char *client)
+ const char *client,
+ int *error)
{
mpegts_mux_t *mm = prch->prch_id;
mpegts_service_t *s = mpegts_service_create_raw(mm);
return subscription_create_from_channel_or_service
(prch, ti, weight, name, flags, hostname, username, client,
- (service_t *)s);
+ error, (service_t *)s);
}
#endif
pthread_mutex_lock(&global_lock);
LIST_FOREACH(s, &subscriptions, ths_global_link)
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
/* clear remaining subscriptions */
subscription_reschedule();
pthread_mutex_unlock(&global_lock);
st = calloc(1, sizeof(*st));
streaming_target_init(st, dummy_callback, NULL, 0);
prch->prch_st = st;
- s = subscription_create_from_service(prch, NULL, 1, "dummy", 0, NULL, NULL, "dummy");
+ s = subscription_create_from_service(prch, NULL, 1, "dummy", 0, NULL, NULL, "dummy", NULL);
tvhlog(LOG_NOTICE, "subscription",
"%04X: Dummy join %s ok", shortid(s), id);
#define SUBSCRIPTION_NONE 0x002
#define SUBSCRIPTION_STREAMING 0x004
#define SUBSCRIPTION_RESTART 0x008
-#define SUBSCRIPTION_INITSCAN 0x010 ///< for mux subscriptions
-#define SUBSCRIPTION_IDLESCAN 0x020 ///< for mux subscriptions
-#define SUBSCRIPTION_USERSCAN 0x040 ///< for mux subscriptions
-#define SUBSCRIPTION_EPG 0x080 ///< for mux subscriptions
+#define SUBSCRIPTION_ONESHOT 0x010
+#define SUBSCRIPTION_INITSCAN 0x020 ///< for mux subscriptions
+#define SUBSCRIPTION_IDLESCAN 0x040 ///< for mux subscriptions
+#define SUBSCRIPTION_USERSCAN 0x080 ///< for mux subscriptions
+#define SUBSCRIPTION_EPG 0x100 ///< for mux subscriptions
/* Some internal priorities */
#define SUBSCRIPTION_PRIO_KEEP 1 ///< Keep input rolling
void subscription_done(void);
-void subscription_unsubscribe(th_subscription_t *s);
+void subscription_unsubscribe(th_subscription_t *s, int quiet);
void subscription_set_weight(th_subscription_t *s, unsigned int weight);
int flags,
const char *hostname,
const char *username,
- const char *client);
+ const char *client,
+ int *error);
th_subscription_t *
int flags,
const char *hostname,
const char *username,
- const char *client);
+ const char *client,
+ int *error);
#if ENABLE_MPEGTS
struct tvh_input;
int flags,
const char *hostname,
const char *username,
- const char *client);
+ const char *client,
+ int *error);
#endif
th_subscription_t *subscription_create(struct profile_chain *prch,
prch.prch_flags | SUBSCRIPTION_STREAMING,
addrbuf,
hc->hc_username,
- http_arg_get(&hc->hc_args, "User-Agent"));
+ http_arg_get(&hc->hc_args, "User-Agent"),
+ NULL);
if(s) {
name = tvh_strdupa(service->s_nicename);
pthread_mutex_unlock(&global_lock);
http_stream_run(hc, &prch, name, s);
pthread_mutex_lock(&global_lock);
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
res = 0;
}
}
prch.prch_flags |
SUBSCRIPTION_STREAMING,
addrbuf, hc->hc_username,
- http_arg_get(&hc->hc_args, "User-Agent"));
+ http_arg_get(&hc->hc_args, "User-Agent"),
+ NULL);
if (s) {
name = tvh_strdupa(s->ths_title);
if (s->ths_service->s_update_pids(s->ths_service, &pids) == 0) {
http_stream_run(hc, &prch, name, s);
pthread_mutex_lock(&global_lock);
}
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
res = 0;
}
}
NULL, weight ?: 100, "HTTP",
prch.prch_flags | SUBSCRIPTION_STREAMING,
addrbuf, hc->hc_username,
- http_arg_get(&hc->hc_args, "User-Agent"));
+ http_arg_get(&hc->hc_args, "User-Agent"),
+ NULL);
if(s) {
name = tvh_strdupa(channel_get_name(ch));
pthread_mutex_unlock(&global_lock);
http_stream_run(hc, &prch, name, s);
pthread_mutex_lock(&global_lock);
- subscription_unsubscribe(s);
+ subscription_unsubscribe(s, 0);
res = 0;
}
}
pthread_mutex_lock(&global_lock);
if (sub)
- subscription_unsubscribe(sub);
+ subscription_unsubscribe(sub, 0);
http_stream_postop(tcp_id);
pthread_mutex_unlock(&global_lock);
return ret;