[SCM] kodi-pvr-hts/master: Refactor subscription to class

tiber-guest at users.alioth.debian.org tiber-guest at users.alioth.debian.org
Wed Mar 2 23:01:47 UTC 2016


The following commit has been merged in the master branch:
commit cfd4dfe6171b4d227934c470b6f544cb5fa5e571
Author: Glenn-1990 <g_christiaensen at msn.com>
Date:   Mon Oct 19 15:48:22 2015 +0200

    Refactor subscription to class

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c43917c..e5fbb79 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,9 @@ set(HTS_SOURCES_TVHEADEND
                 src/tvheadend/Settings.cpp
                 src/tvheadend/Settings.h
                 src/tvheadend/ChannelTuningPredictor.h
-                src/tvheadend/ChannelTuningPredictor.cpp)
+                src/tvheadend/ChannelTuningPredictor.cpp
+                src/tvheadend/Subscription.cpp
+                src/tvheadend/Subscription.h)
 
 set(HTS_SOURCES_TVHEADEND_ENTITY
                 src/tvheadend/entity/AutoRecording.h
diff --git a/pvr.hts/resources/language/resource.language.en_gb/strings.po b/pvr.hts/resources/language/resource.language.en_gb/strings.po
index 8d34340..4fa3452 100644
--- a/pvr.hts/resources/language/resource.language.en_gb/strings.po
+++ b/pvr.hts/resources/language/resource.language.en_gb/strings.po
@@ -193,3 +193,35 @@ msgstr ""
 msgctxt "#30403"
 msgid "Use predictive tuning to speedup channel switches"
 msgstr ""
+
+#empty strings from id 30404 to 30449
+
+#. Subscription states representation
+
+msgctxt "#30450"
+msgid "No free adapter available"
+msgstr ""
+
+msgctxt "#30451"
+msgid "Scrambled channel"
+msgstr ""
+
+msgctxt "#30452"
+msgid "No signal"
+msgstr ""
+
+msgctxt "#30453"
+msgid "Tuning failed"
+msgstr ""
+
+msgctxt "#30454"
+msgid "User limit reached"
+msgstr ""
+
+msgctxt "#30455"
+msgid "No access"
+msgstr ""
+
+msgctxt "#30456"
+msgid "Subscription error"
+msgstr ""
diff --git a/src/HTSPDemuxer.cpp b/src/HTSPDemuxer.cpp
index 5de5e0b..c5f3323 100644
--- a/src/HTSPDemuxer.cpp
+++ b/src/HTSPDemuxer.cpp
@@ -31,7 +31,8 @@ using namespace tvheadend;
 
 CHTSPDemuxer::CHTSPDemuxer ( CHTSPConnection &conn )
   : m_conn(conn), m_pktBuffer((size_t)-1),
-    m_seekTime(INVALID_SEEKTIME)
+    m_seekTime(INVALID_SEEKTIME),
+    m_subscription(conn)
 {
   m_lastUse = 0;
 }
@@ -43,11 +44,15 @@ CHTSPDemuxer::~CHTSPDemuxer ()
 void CHTSPDemuxer::Connected ( void )
 {
   /* Re-subscribe */
-  if (m_subscription.active)
+  if (m_subscription.IsActive())
   {
     tvhdebug("demux re-starting stream");
-    SendSubscribe(true);
-    SendSpeed(true);
+    m_subscription.SendSubscribe(true);
+    m_subscription.SendSpeed(true);
+
+    /* Reset status */
+    m_signalInfo.Clear();
+    m_sourceInfo.Clear();
   }
 }
 
@@ -58,8 +63,8 @@ void CHTSPDemuxer::Connected ( void )
 void CHTSPDemuxer::Close0 ( void )
 {
   /* Send unsubscribe */
-  if (m_subscription.active)
-    SendUnsubscribe();
+  if (m_subscription.IsActive())
+    m_subscription.SendUnsubscribe();
 
   /* Clear */
   Flush();
@@ -81,22 +86,21 @@ bool CHTSPDemuxer::Open ( uint32_t channelId, enum eSubscriptionWeight weight )
 
   /* Close current stream */
   Close0();
-  
-  /* Create new subscription */
-  m_subscription = SSubscription();
-  m_subscription.channelId = channelId;
-  m_subscription.weight = weight;
 
-  /* Open */
-  SendSubscribe();
+  /* Open new subscription */
+  m_subscription.SendSubscribe(channelId, weight);
   
+  /* Reset status */
+  m_signalInfo.Clear();
+  m_sourceInfo.Clear();
+
   /* Send unsubscribe if subscribing failed */
-  if (!m_subscription.active)
-    SendUnsubscribe();
+  if (!m_subscription.IsActive())
+    m_subscription.SendUnsubscribe();
   else
     m_lastUse = time(NULL);
   
-  return m_subscription.active;
+  return m_subscription.IsActive();
 }
 
 void CHTSPDemuxer::Close ( void )
@@ -150,26 +154,11 @@ void CHTSPDemuxer::Abort ( void )
 bool CHTSPDemuxer::Seek 
   ( int time, bool _unused(backwards), double *startpts )
 {
-  htsmsg_t *m;
-
-  CLockObject lock(m_conn.Mutex());
-  if (!m_subscription.active)
+  if (!m_subscription.IsActive())
     return false;
 
-  tvhdebug("demux seek %d", time);
-
-  /* Build message */
-  m = htsmsg_create_map();  
-  htsmsg_add_u32(m, "subscriptionId", m_subscription.subscriptionId);
-  htsmsg_add_s64(m, "time",           (int64_t)time * 1000);
-  htsmsg_add_u32(m, "absolute",       1);
-
-  /* Send and Wait */
-  m = m_conn.SendAndWait("subscriptionSeek", m);
-  if (!m)
+  if (!m_subscription.SendSeek(time))
     return false;
-  
-  htsmsg_destroy(m);
 
   /* Wait for time */
   if (!m_seekCond.Wait(m_conn.Mutex(), m_seekTime, Settings::GetInstance().GetResponseTimeout()))
@@ -191,18 +180,16 @@ bool CHTSPDemuxer::Seek
 void CHTSPDemuxer::Speed ( int speed )
 {
   CLockObject lock(m_conn.Mutex());
-  if (!m_subscription.active)
+  if (!m_subscription.IsActive())
     return;
-  m_subscription.speed = speed;
-  SendSpeed();
+  m_subscription.SendSpeed(speed);
 }
 
 void CHTSPDemuxer::Weight ( enum eSubscriptionWeight weight )
 {
-  if (!m_subscription.active || m_subscription.weight == weight)
+  if (!m_subscription.IsActive() || m_subscription.GetWeight() == static_cast<uint32_t>(weight))
     return;
-  m_subscription.weight = weight;
-  SendWeight();
+  m_subscription.SendWeight(static_cast<uint32_t>(weight));
 }
 
 PVR_ERROR CHTSPDemuxer::CurrentStreams ( PVR_STREAM_PROPERTIES *streams )
@@ -238,99 +225,6 @@ PVR_ERROR CHTSPDemuxer::CurrentSignal ( PVR_SIGNAL_STATUS &sig )
 }
 
 /* **************************************************************************
- * Send Messages
- * *************************************************************************/
-
-void CHTSPDemuxer::SendSubscribe ( bool force )
-{
-  htsmsg_t *m;
-
-  /* Reset status */
-  m_signalInfo.Clear();
-  m_sourceInfo.Clear();
-
-  /* Build message */
-  m = htsmsg_create_map();
-  htsmsg_add_s32(m, "channelId",       m_subscription.channelId);
-  htsmsg_add_u32(m, "subscriptionId",  m_subscription.subscriptionId);
-  htsmsg_add_u32(m, "weight",          m_subscription.weight);
-  htsmsg_add_u32(m, "timeshiftPeriod", (uint32_t)~0);
-  htsmsg_add_u32(m, "normts",          1);
-  htsmsg_add_u32(m, "queueDepth",      2000000);
-
-  /* Send and Wait for response */
-  tvhdebug("demux subscribe to %d", m_subscription.channelId);
-  if (force)
-    m = m_conn.SendAndWait0("subscribe", m);
-  else
-    m = m_conn.SendAndWait("subscribe", m);
-  if (m == NULL)
-    return;
-
-  htsmsg_destroy(m);
-
-  m_subscription.active = true;
-  tvhdebug("demux successfully subscribed to %d", m_subscription.channelId);
-}
-
-void CHTSPDemuxer::SendUnsubscribe ( void )
-{
-  htsmsg_t *m;
-
-  /* Build message */
-  m = htsmsg_create_map();
-  htsmsg_add_u32(m, "subscriptionId", m_subscription.subscriptionId);
-
-  /* Mark subscription as inactive immediately in case this command fails */
-  m_subscription.active = false;
-  
-  /* Send and Wait */
-  tvhdebug("demux unsubscribe from %d", m_subscription.channelId);
-  if ((m = m_conn.SendAndWait("unsubscribe", m)) == NULL)
-    return;
-
-  htsmsg_destroy(m);
-  tvhdebug("demux successfully unsubscribed %d", m_subscription.channelId);
-}
-
-void CHTSPDemuxer::SendSpeed ( bool force )
-{
-  htsmsg_t *m;
-  int speed = m_subscription.speed / 10; // XBMC uses values an order of magnitude larger than tvheadend
-
-  /* Build message */
-  m = htsmsg_create_map();
-  htsmsg_add_u32(m, "subscriptionId", m_subscription.subscriptionId);
-  htsmsg_add_s32(m, "speed",          speed);
-  tvhdebug("demux send speed %d", speed);
-
-  /* Send and Wait */
-  if (force)
-    m = m_conn.SendAndWait0("subscriptionSpeed", m);
-  else
-    m = m_conn.SendAndWait("subscriptionSpeed", m);
-  if (m)
-    htsmsg_destroy(m);
-}
-
-void CHTSPDemuxer::SendWeight ( void )
-{
-  CLockObject lock(m_conn.Mutex());
-  htsmsg_t *m;
-
-  /* Build message */
-  m = htsmsg_create_map();
-  htsmsg_add_u32(m, "subscriptionId", m_subscription.subscriptionId);
-  htsmsg_add_s32(m, "weight",         m_subscription.weight);
-  tvhdebug("demux send weight %u", m_subscription.weight);
-
-  /* Send and Wait */
-  m = m_conn.SendAndWait("subscriptionChangeWeight", m);
-  if (m)
-    htsmsg_destroy(m);
-}
-
-/* **************************************************************************
  * Parse incoming data
  * *************************************************************************/
 
@@ -342,7 +236,7 @@ bool CHTSPDemuxer::ProcessMessage ( const char *method, htsmsg_t *m )
   if (!strcmp("muxpkt", method))
     ParseMuxPacket(m);
   else if (!strcmp("subscriptionStatus", method))
-    ParseSubscriptionStatus(m);
+    m_subscription.ParseSubscriptionStatus(m);
   else if (!strcmp("queueStatus", method))
     ParseQueueStatus(m);
   else if (!strcmp("signalStatus", method))
@@ -375,7 +269,7 @@ void CHTSPDemuxer::ParseMuxPacket ( htsmsg_t *m )
   int         iStreamId;
   
   /* Ignore packets while switching channels */
-  if (!m_subscription.active)
+  if (!m_subscription.IsActive())
   {
     tvhdebug("Ignored mux packet due to channel switch");
     return;
@@ -617,24 +511,6 @@ void CHTSPDemuxer::ParseSubscriptionSpeed ( htsmsg_t *m )
     tvhtrace("recv speed %d", u32);
 }
 
-void CHTSPDemuxer::ParseSubscriptionStatus ( htsmsg_t *m )
-{
-  const char *status;
-  status = htsmsg_get_str(m, "status");
-
-  // not for preTuning and postTuning subscriptions
-  if (m_subscription.weight == SUBSCRIPTION_WEIGHT_PRETUNING ||
-      m_subscription.weight == SUBSCRIPTION_WEIGHT_POSTTUNING)
-    return;
-
-  // this field is absent when everything is fine
-  if (status != NULL)
-  {
-    tvhinfo("Bad subscription status: %s", status);
-    XBMC->QueueNotification(QUEUE_INFO, status);
-  }
-}
-
 void CHTSPDemuxer::ParseQueueStatus ( htsmsg_t *_unused(m) )
 {
   uint32_t u32;
diff --git a/src/HTSPTypes.h b/src/HTSPTypes.h
index 91f5f8d..9771099 100644
--- a/src/HTSPTypes.h
+++ b/src/HTSPTypes.h
@@ -62,17 +62,6 @@ enum eHTSPEventType
   HTSP_EVENT_REC_UPDATE = 4,
 };
 
-/* streaming uses a weight of 100 by default on the tvh side  */
-/* lowest configurable streaming weight in tvh is 50          */
-/* predictive tuning should be lower to avoid conflicts       */
-/* weight 0 means that tvh will use the weight of it's config */
-enum eSubscriptionWeight {
-  SUBSCRIPTION_WEIGHT_NORMAL     = 100,
-  SUBSCRIPTION_WEIGHT_PRETUNING  = 40,
-  SUBSCRIPTION_WEIGHT_POSTTUNING = 30,
-  SUBSCRIPTION_WEIGHT_SERVERCONF = 0,
-};
-
 struct SHTSPEvent
 {
   eHTSPEventType m_type;
@@ -96,22 +85,3 @@ struct SHTSPEvent
 };
 
 typedef std::vector<SHTSPEvent> SHTSPEventList;
-
-struct SSubscription
-{
-  uint32_t subscriptionId;
-  uint32_t channelId;
-  int      speed;
-  bool     active;
-  enum eSubscriptionWeight weight;
-
-  SSubscription() :
-    channelId(0),
-    speed (1000),
-    active(false),
-    weight(SUBSCRIPTION_WEIGHT_NORMAL)
-  {
-    static uint32_t previousId = 0;
-    subscriptionId = ++previousId;
-  }
-};
diff --git a/src/Tvheadend.h b/src/Tvheadend.h
index d157bbb..a4b254d 100644
--- a/src/Tvheadend.h
+++ b/src/Tvheadend.h
@@ -41,6 +41,7 @@
 #include "tvheadend/status/Quality.h"
 #include "tvheadend/status/SourceInfo.h"
 #include "tvheadend/status/TimeshiftStatus.h"
+#include "tvheadend/Subscription.h"
 #include "TimeRecordings.h"
 #include "AutoRecordings.h"
 #include <map>
@@ -267,17 +268,17 @@ public:
   }
   inline uint32_t GetSubscriptionId() const
   {
-    return m_subscription.subscriptionId;
+    return m_subscription.GetId();
   }
   inline uint32_t GetChannelId() const
   {
-    if (m_subscription.active)
-      return m_subscription.channelId;
+    if (m_subscription.IsActive())
+      return m_subscription.GetChannelId();
     return 0;
   }
   inline time_t GetLastUse() const
   {
-    if (m_subscription.active)
+    if (m_subscription.IsActive())
       return m_lastUse;
     return 0;
   }
@@ -293,13 +294,13 @@ private:
   tvheadend::status::SourceInfo           m_sourceInfo;
   tvheadend::status::Quality              m_signalInfo;
   tvheadend::status::TimeshiftStatus      m_timeshiftStatus;
-  SSubscription                           m_subscription;
+  tvheadend::Subscription                 m_subscription;
   time_t                                  m_lastUse;
   
   void         Close0         ( void );
   void         Abort0         ( void );
   bool         Open           ( uint32_t channelId,
-                                enum eSubscriptionWeight weight = SUBSCRIPTION_WEIGHT_NORMAL );
+                                tvheadend::eSubscriptionWeight weight = tvheadend::SUBSCRIPTION_WEIGHT_NORMAL );
   void         Close          ( void );
   DemuxPacket *Read           ( void );
   void         Trim           ( void );
@@ -307,14 +308,9 @@ private:
   void         Abort          ( void );
   bool         Seek           ( int time, bool backwards, double *startpts );
   void         Speed          ( int speed );
-  void         Weight         ( enum eSubscriptionWeight weight );
+  void         Weight         ( tvheadend::eSubscriptionWeight weight );
   PVR_ERROR    CurrentStreams ( PVR_STREAM_PROPERTIES *streams );
   PVR_ERROR    CurrentSignal  ( PVR_SIGNAL_STATUS &sig );
-
-  void SendSubscribe   ( bool force = false );
-  void SendUnsubscribe ( void );
-  void SendSpeed       ( bool force = false );
-  void SendWeight      ( void );
   
   void ParseMuxPacket           ( htsmsg_t *m );
   void ParseSourceInfo          ( htsmsg_t *m );
@@ -322,7 +318,6 @@ private:
   void ParseSubscriptionStop    ( htsmsg_t *m );
   void ParseSubscriptionSkip    ( htsmsg_t *m );
   void ParseSubscriptionSpeed   ( htsmsg_t *m );
-  void ParseSubscriptionStatus  ( htsmsg_t *m );
   void ParseQueueStatus         ( htsmsg_t *m );
   void ParseSignalStatus        ( htsmsg_t *m );
   void ParseTimeshiftStatus     ( htsmsg_t *m );
diff --git a/src/tvheadend/Subscription.cpp b/src/tvheadend/Subscription.cpp
new file mode 100644
index 0000000..9c94ad6
--- /dev/null
+++ b/src/tvheadend/Subscription.cpp
@@ -0,0 +1,301 @@
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "Subscription.h"
+#include "../Tvheadend.h"
+
+using namespace PLATFORM;
+using namespace tvheadend;
+
+Subscription::Subscription(CHTSPConnection &conn) :
+  m_channelId(0),
+  m_speed(1000),
+  m_weight(SUBSCRIPTION_WEIGHT_NORMAL),
+  m_id(0),
+  m_state(SUBSCRIPTION_STOPPED),
+  m_conn(conn)
+{
+}
+
+bool Subscription::IsActive() const
+{
+  CLockObject lock(m_mutex);
+  return (GetState() != SUBSCRIPTION_STOPPED);
+}
+
+uint32_t Subscription::GetId() const
+{
+  CLockObject lock(m_mutex);
+  return m_id;
+}
+
+void Subscription::SetId(uint32_t id)
+{
+  CLockObject lock(m_mutex);
+  m_id = id;
+}
+
+uint32_t Subscription::GetChannelId() const
+{
+  CLockObject lock(m_mutex);
+  return m_channelId;
+}
+
+void Subscription::SetChannelId(uint32_t id)
+{
+  CLockObject lock(m_mutex);
+  m_channelId = id;
+}
+
+uint32_t Subscription::GetWeight() const
+{
+  CLockObject lock(m_mutex);
+  return m_weight;
+}
+
+void Subscription::SetWeight(uint32_t weight)
+{
+  CLockObject lock(m_mutex);
+  m_weight = weight;
+}
+
+int32_t Subscription::GetSpeed() const
+{
+  CLockObject lock(m_mutex);
+  return m_speed;
+}
+
+void Subscription::SetSpeed(int32_t speed)
+{
+  CLockObject lock(m_mutex);
+  m_speed = speed;
+}
+
+eSubsriptionState Subscription::GetState() const
+{
+  CLockObject lock(m_mutex);
+  return m_state;
+}
+
+void Subscription::SetState(eSubsriptionState state)
+{
+  CLockObject lock(m_mutex);
+  m_state = state;
+}
+
+void Subscription::SendSubscribe(uint32_t channelId, uint32_t weight, bool restart)
+{
+  /* We don't want to change anything when restarting a subscription */
+  if (!restart)
+  {
+    SetChannelId(channelId);
+    SetWeight(weight);
+    SetId(GetNextId());
+    SetSpeed(1000); //set back to normal
+  }
+
+  /* Build message */
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_s32(m, "channelId",       GetChannelId());
+  htsmsg_add_u32(m, "subscriptionId",  GetId());
+  htsmsg_add_u32(m, "weight",          GetWeight());
+  htsmsg_add_u32(m, "timeshiftPeriod", static_cast<uint32_t>(~0));
+  htsmsg_add_u32(m, "normts",          1);
+  htsmsg_add_u32(m, "queueDepth",      PACKET_QUEUE_DEPTH);
+  tvhdebug("demux subscribe to %d",    GetChannelId());
+
+  /* Send and Wait for response */
+  if (restart)
+    m = m_conn.SendAndWait0("subscribe", m);
+  else
+    m = m_conn.SendAndWait("subscribe", m);
+  if (m == NULL)
+    return;
+
+  htsmsg_destroy(m);
+
+  SetState(SUBSCRIPTION_STARTING);
+  tvhdebug("demux successfully subscribed to channel id %d, subscription id %d", GetChannelId(), GetId());
+}
+
+void Subscription::SendUnsubscribe(void)
+{
+  /* Build message */
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_u32(m, "subscriptionId",   GetId());
+  tvhdebug("demux unsubscribe from %d", GetChannelId());
+
+  /* Mark subscription as inactive immediately in case this command fails */
+  SetState(SUBSCRIPTION_STOPPED);
+
+  /* Send and Wait */
+  if ((m = m_conn.SendAndWait("unsubscribe", m)) == NULL)
+    return;
+
+  htsmsg_destroy(m);
+  tvhdebug("demux successfully unsubscribed from channel id %d, subscription id %d", GetChannelId(), GetId());
+}
+
+bool Subscription::SendSeek(int time)
+{
+  /* Build message */
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_u32(m, "subscriptionId", GetId());
+  htsmsg_add_s64(m, "time",           static_cast<int64_t>(time * 1000LL));
+  htsmsg_add_u32(m, "absolute",       1);
+  tvhdebug("demux send seek %d",      time);
+
+  /* Send and Wait */
+  {
+    CLockObject lock(m_conn.Mutex());
+    m = m_conn.SendAndWait("subscriptionSeek", m);
+  }
+  if (m)
+  {
+    htsmsg_destroy(m);
+    return true;
+  }
+
+  return false;
+}
+
+void Subscription::SendSpeed(int32_t speed, bool restart)
+{
+  /* We don't want to change the speed when restarting a subscription */
+  if (!restart)
+    SetSpeed(speed);
+
+  /* Build message */
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_u32(m, "subscriptionId", GetId());
+  htsmsg_add_s32(m, "speed",          GetSpeed() / 10); // Kodi uses values an order of magnitude larger than tvheadend
+  tvhdebug("demux send speed %d",     GetSpeed() / 10);
+
+  if (restart)
+    m = m_conn.SendAndWait0("subscriptionSpeed", m);
+  else
+    m = m_conn.SendAndWait("subscriptionSpeed", m);
+
+  if (m)
+    htsmsg_destroy(m);
+}
+
+void Subscription::SendWeight(uint32_t weight)
+{
+  SetWeight(weight);
+
+  /* Build message */
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_u32(m, "subscriptionId", GetId());
+  htsmsg_add_s32(m, "weight",         GetWeight());
+  tvhdebug("demux send weight %u",    GetWeight());
+
+  /* Send and Wait */
+  {
+    CLockObject lock(m_conn.Mutex());
+    m = m_conn.SendAndWait("subscriptionChangeWeight", m);
+  }
+  if (m)
+    htsmsg_destroy(m);
+}
+
+void Subscription::ParseSubscriptionStatus ( htsmsg_t *m )
+{
+  /* Not for preTuning and postTuning subscriptions */
+  if (GetWeight() == static_cast<uint32_t>(SUBSCRIPTION_WEIGHT_PRETUNING) ||
+      GetWeight() == static_cast<uint32_t>(SUBSCRIPTION_WEIGHT_POSTTUNING))
+  {
+    SetState(SUBSCRIPTION_PREPOSTTUNING);
+    return;
+  }
+
+  const char *status = htsmsg_get_str(m, "status");
+
+  if (status != NULL)
+    tvhinfo("Bad subscription status: %s", status);
+
+  /* 'subscriptionErrors' was added in htsp v20, use 'status' for older backends */
+  if (m_conn.GetProtocol() >= 20)
+  {
+    const char *error = htsmsg_get_str(m, "subscriptionError");
+
+    /* This field is absent when everything is fine */
+    if (error != NULL)
+    {
+      if (!strcmp("badSignal", error))
+        SetState(SUBSCRIPTION_NOSIGNAL);
+      else if (!strcmp("scrambled", error))
+        SetState(SUBSCRIPTION_SCRAMBLED);
+      else if (!strcmp("userLimit", error))
+        SetState(SUBSCRIPTION_USERLIMIT);
+      else if (!strcmp("noFreeAdapter", error))
+        SetState(SUBSCRIPTION_NOFREEADAPTER);
+      else if (!strcmp("tuningFailed", error))
+        SetState(SUBSCRIPTION_TUNINGFAILED);
+      else if (!strcmp("userAccess", error))
+        SetState(SUBSCRIPTION_NOACCESS);
+      else
+        SetState(SUBSCRIPTION_UNKNOWN);
+
+      /* Show an OSD message */
+      ShowStateNotification();
+    }
+    else
+      SetState(SUBSCRIPTION_RUNNING);
+  }
+  else
+  {
+    /* This field is absent when everything is fine */
+    if (status != NULL)
+    {
+      SetState(SUBSCRIPTION_UNKNOWN);
+
+      /* Show an OSD message */
+      XBMC->QueueNotification(ADDON::QUEUE_INFO, status);
+    }
+    else
+      SetState(SUBSCRIPTION_RUNNING);
+  }
+}
+
+void Subscription::ShowStateNotification(void)
+{
+  if (GetState() == SUBSCRIPTION_NOFREEADAPTER)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30450));
+  else if (GetState() == SUBSCRIPTION_SCRAMBLED)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30451));
+  else if (GetState() == SUBSCRIPTION_NOSIGNAL)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30452));
+  else if (GetState() == SUBSCRIPTION_TUNINGFAILED)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30453));
+  else if (GetState() == SUBSCRIPTION_USERLIMIT)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30454));
+  else if (GetState() == SUBSCRIPTION_NOACCESS)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30455));
+  else if (GetState() == SUBSCRIPTION_UNKNOWN)
+    XBMC->QueueNotification(ADDON::QUEUE_WARNING, XBMC->GetLocalizedString(30456));
+}
+
+uint32_t Subscription::GetNextId()
+{
+  static uint32_t id = 0;
+  return ++id;
+}
diff --git a/src/tvheadend/Subscription.h b/src/tvheadend/Subscription.h
new file mode 100644
index 0000000..cea83aa
--- /dev/null
+++ b/src/tvheadend/Subscription.h
@@ -0,0 +1,141 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2015 Team Kodi
+ *      http://kodi.tv
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "platform/threads/mutex.h"
+
+extern "C"
+{
+#include "libhts/htsmsg.h"
+}
+
+class CHTSPConnection;
+
+namespace tvheadend
+{
+  /* streaming uses a weight of 100 by default on the tvh side  */
+  /* lowest configurable streaming weight in tvh is 50          */
+  /* predictive tuning should be lower to avoid conflicts       */
+  /* weight 0 means that tvh will use the weight of it's config */
+  enum eSubscriptionWeight {
+    SUBSCRIPTION_WEIGHT_NORMAL     = 100,
+    SUBSCRIPTION_WEIGHT_PRETUNING  = 40,
+    SUBSCRIPTION_WEIGHT_POSTTUNING = 30,
+    SUBSCRIPTION_WEIGHT_SERVERCONF = 0,
+  };
+
+  enum eSubsriptionState
+  {
+    SUBSCRIPTION_STOPPED                        = 0,  /* subscription is stopped or not started yet */
+    SUBSCRIPTION_STARTING                       = 1,  /* subscription is starting */
+    SUBSCRIPTION_RUNNING                        = 2,  /* subscription is running normal */
+    SUBSCRIPTION_NOFREEADAPTER                  = 3,  /* subscription has no free adapter to use */
+    SUBSCRIPTION_SCRAMBLED                      = 4,  /* subscription is not running because the channel is scrambled */
+    SUBSCRIPTION_NOSIGNAL                       = 5,  /* subscription is not running because of a weak/no input signal */
+    SUBSCRIPTION_TUNINGFAILED                   = 6,  /* subscription could not be started because of a tuning error */
+    SUBSCRIPTION_USERLIMIT                      = 7,  /* userlimit is reached, so we could not start this subscription */
+    SUBSCRIPTION_NOACCESS                       = 8,  /* we have no rights to watch this channel */
+    SUBSCRIPTION_UNKNOWN                        = 9,  /* subscription state is unknown, also used for pretuning and posttuning subscriptions */
+    SUBSCRIPTION_PREPOSTTUNING                  = 10, /* used for pre and posttuning subscriptions (we do not care what the actual state is) */
+  };
+
+  static const int PACKET_QUEUE_DEPTH = 2000000;
+
+  class Subscription
+  {
+  public:
+    Subscription(CHTSPConnection &conn);
+
+    bool              IsActive() const;
+    uint32_t          GetId() const;
+    uint32_t          GetChannelId() const;
+    uint32_t          GetWeight() const;
+    int32_t           GetSpeed() const;
+    eSubsriptionState GetState() const;
+
+    /**
+     * Subscribe to a channel on the backend
+     * @param channelId the channel to subscribe to
+     * @param weight the desired subscription weight
+     * @param restart restart the current subscription (i.e. after lost connection), other parameters will be ignored
+     */
+    void SendSubscribe(uint32_t channelId = 0, uint32_t weight = SUBSCRIPTION_WEIGHT_NORMAL, bool restart = false);
+
+    /**
+     * Unsubscribe from a channel on the backend
+     */
+    void SendUnsubscribe();
+
+    /**
+     * Send a seek to the backend
+     * @param time timestamp to seek to
+     * @return false if the command failed, true otherwise
+     */
+    bool SendSeek(int time);
+
+    /**
+     * Change the subscription speed on the backend
+     * @param speed the desired speed of the subscription
+     * @param restart resent the current subscription speed (i.e. after lost connection), other parameters will be ignored
+     */
+    void SendSpeed(int32_t speed = 1000, bool restart = false);
+
+    /**
+     * Change the subscription weight on the backend
+     * @param weight the desired subscription weight
+     */
+    void SendWeight(uint32_t weight);
+
+    /**
+     * Parse the subscription status out of the incoming htsp data
+     * @param m message containing the status field
+     */
+    void ParseSubscriptionStatus(htsmsg_t *m);
+
+  private:
+
+    void SetId(uint32_t id);
+    void SetChannelId(uint32_t id);
+    void SetWeight(uint32_t weight);
+    void SetSpeed(int32_t speed);
+    void SetState(eSubsriptionState state);
+
+    /**
+     * Show a notification to the user depending on the subscription state
+     */
+    void ShowStateNotification();
+
+    /**
+     * Get the next unique subscription Id
+     */
+    static uint32_t GetNextId();
+
+    uint32_t          m_id;
+    uint32_t          m_channelId;
+    uint32_t          m_weight;
+    int32_t           m_speed;
+    eSubsriptionState m_state;
+    CHTSPConnection   &m_conn;
+
+    mutable PLATFORM::CMutex  m_mutex;
+  };
+}

-- 
kodi-pvr-hts packaging



More information about the pkg-multimedia-commits mailing list