]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
subscription: add ONESHOT subscription type for mux subs
authorJaroslav Kysela <perex@perex.cz>
Tue, 10 Mar 2015 14:07:40 +0000 (15:07 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 11 Mar 2015 20:41:13 +0000 (21:41 +0100)
src/dvr/dvr_rec.c
src/epggrab/otamux.c
src/htsp_server.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_mux_sched.c
src/input/mpegts/mpegts_network_scan.c
src/satip/rtsp.c
src/service_mapper.c
src/subscriptions.c
src/subscriptions.h
src/webui/webui.c

index 832a78a200c28fa97ad7b524d8ed465da24559d7..741a2e8aef26abe168e2f574f68e376eb2f01771 100644 (file)
@@ -87,7 +87,7 @@ dvr_rec_subscribe(dvr_entry_t *de)
 
   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));
@@ -117,7 +117,7 @@ dvr_rec_unsubscribe(dvr_entry_t *de, int stopcode)
   
   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;
index c91c967d014ebea3ecf52394698729aa1f4726f7..320a0900ed763df3cf7672dcd5647cffaf018b1d 100644 (file)
@@ -547,7 +547,7 @@ next_one:
   /* 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)
index e19cb2dc88c63695f10358532b068ab10402f5a1..6e3e726173e737057cbaa16e263cb916354d07f8 100644 (file)
@@ -330,7 +330,7 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs)
   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);
@@ -2028,7 +2028,8 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
                                              SUBSCRIPTION_STREAMING,
                                              htsp->htsp_peername,
                                              htsp->htsp_username,
-                                             htsp->htsp_clientname);
+                                             htsp->htsp_clientname,
+                                             NULL);
   return NULL;
 }
 
index 29fe20bc047e3dcbd53076c201a6227b8dd794b4..8cb6233540e1843734150afcf3d003acbca4aa93 100644 (file)
@@ -1130,13 +1130,14 @@ mpegts_mux_subscribe
 {
   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
@@ -1153,7 +1154,7 @@ mpegts_mux_unsubscribe_by_name
       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;
     }
   }
index 06689f148959e92faea70a6990a924cc2f48bbda..9e35ba86ea5b6aad1554589f043d4872ff8f6a60 100644 (file)
@@ -39,7 +39,7 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms )
   /* 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);
@@ -214,7 +214,7 @@ mpegts_mux_sched_timer ( void *p )
       = 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) {
@@ -232,7 +232,7 @@ mpegts_mux_sched_timer ( void *p )
   /* 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;
@@ -310,7 +310,7 @@ mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf )
   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);
index 711e350bce26ae85dca81a9e1a9d5bf9b4781109..fb3bc14028bfd409d3c06845c0574ca34b8cf24e 100644 (file)
@@ -53,7 +53,8 @@ mpegts_network_scan_timer_cb ( void *p )
     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) {
index e275a1a74d8f52b73c3317038858b208418e8284..3ec9e0be36269aaefc9d92baef2f4bedf60484b5 100644 (file)
@@ -226,7 +226,7 @@ static void
 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)
@@ -293,7 +293,8 @@ rtsp_start
                                    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) {
index b7d98bf3deaaac20376b8ce78dfeec4dc4842adc..a04176d1f548d01d0aa70b525459d325c1910427 100644 (file)
@@ -377,7 +377,8 @@ service_mapper_thread ( void *aux )
     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) {
@@ -433,7 +434,7 @@ service_mapper_thread ( void *aux )
     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);
index 28abf6231fe75f848812b273c10f8b3b28a4fc1d..28fe69dbdc26349361e79aef1ab0e21842b86f94 100644 (file)
@@ -219,6 +219,29 @@ subscription_reschedule_cb(void *aux)
   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;
+}
 
 /**
  *
@@ -278,18 +301,7 @@ subscription_reschedule(void)
     }
 
     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) {
@@ -325,7 +337,7 @@ subscription_reschedule(void)
 
   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)
@@ -487,7 +499,7 @@ subscription_input(void *opauqe, streaming_message_t *sm)
  * 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];
@@ -517,7 +529,7 @@ subscription_unsubscribe(th_subscription_t *s)
              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);
@@ -621,6 +633,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch,
                                             const char *hostname,
                                             const char *username,
                                             const char *client,
+                                            int *error,
                                             service_t *service)
 {
   th_subscription_t *s;
@@ -629,6 +642,9 @@ subscription_create_from_channel_or_service(profile_chain_t *prch,
   assert(prch);
   assert(prch->prch_id);
 
+  if (error)
+    *error = 0;
+
   if (!service)
     ch = prch->prch_id;
 
@@ -640,7 +656,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch,
     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;
@@ -656,7 +672,14 @@ subscription_create_from_channel_or_service(profile_chain_t *prch,
   }
 #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;
 }
 
@@ -665,12 +688,16 @@ subscription_create_from_channel(profile_chain_t *prch,
                                  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);
 }
 
 /**
@@ -682,13 +709,15 @@ subscription_create_from_service(profile_chain_t *prch,
                                  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);
 }
 
 /**
@@ -704,7 +733,8 @@ subscription_create_from_mux(profile_chain_t *prch,
                              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);
@@ -714,7 +744,7 @@ subscription_create_from_mux(profile_chain_t *prch,
 
   return subscription_create_from_channel_or_service
     (prch, ti, weight, name, flags, hostname, username, client,
-     (service_t *)s);
+     error, (service_t *)s);
 }
 #endif
 
@@ -833,7 +863,7 @@ subscription_done(void)
 
   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);
@@ -972,7 +1002,7 @@ subscription_dummy_join(const char *id, int first)
   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);
index 229bcc9b823291ad4eee0b6c2f238f51c51034fd..7221f21f86c77cc540b170d86b9f432fa1b5e483 100644 (file)
@@ -29,10 +29,11 @@ extern struct th_subscription_list subscriptions;
 #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
@@ -126,7 +127,7 @@ void subscription_init(void);
 
 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);
 
@@ -140,7 +141,8 @@ subscription_create_from_channel(struct profile_chain *prch,
                                 int flags,
                                 const char *hostname,
                                 const char *username,
-                                const char *client);
+                                const char *client,
+                                int *error);
 
 
 th_subscription_t *
@@ -151,7 +153,8 @@ subscription_create_from_service(struct profile_chain *prch,
                                 int flags,
                                 const char *hostname,
                                 const char *username,
-                                const char *client);
+                                const char *client,
+                                int *error);
 
 #if ENABLE_MPEGTS
 struct tvh_input;
@@ -163,7 +166,8 @@ subscription_create_from_mux(struct profile_chain *prch,
                              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,
index 66494e9cf30bb9a0a79fc224f7b826ad3a84ca70..16ecee5ab22ddef91e8849028aaa2770a51388e8 100644 (file)
@@ -773,13 +773,14 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
                                          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;
     }
   }
@@ -851,7 +852,8 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight)
                                      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) {
@@ -859,7 +861,7 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight)
         http_stream_run(hc, &prch, name, s);
         pthread_mutex_lock(&global_lock);
       }
-      subscription_unsubscribe(s);
+      subscription_unsubscribe(s, 0);
       res = 0;
     }
   }
@@ -912,14 +914,15 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
                  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;
     }
   }
@@ -1290,7 +1293,7 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
 
   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;