implemented halting player by another stream
Stefan Schuermans

Stefan Schuermans commited on 2011-12-21 20:08:38
Showing 4 changed files, with 89 additions and 9 deletions.

... ...
@@ -23,6 +23,19 @@
23 23
       The file <code>outstream</code> contains the name of the stream to
24 24
       send the frames to.
25 25
     </p>
26
+    <h3>Halt Stream</h3>
27
+    <p>
28
+      The player can be halted whenever another stream is active.
29
+      Therefore, the name of the other stream is written to the file
30
+      <code>haltstream</code>.
31
+      When the halt stream becoms active, the current frame is frozen,
32
+      i.e. the frame is kept.
33
+      When the halt stream ends, the player resumes with the remaining
34
+      time for the current frame and continues as usual afterwards.
35
+      <br>
36
+      If this feature is not needed, the file <code>haltstream</code>
37
+      should not exist.
38
+    </p>
26 39
   </body>
27 40
 </html>
28 41
 
... ...
@@ -12,13 +12,15 @@
12 12
 #include "CallMgr.h"
13 13
 #include "Directory.h"
14 14
 #include "File.h"
15
-#include "Module.h"
15
+#include "InStreamFile.h"
16 16
 #include "ListTracker.h"
17 17
 #include "ListTracker_impl.h"
18
+#include "Module.h"
18 19
 #include "OutStreamFile.h"
19 20
 #include "Player.h"
20 21
 #include "PlayerMovie.h"
21 22
 #include "StreamMgr.h"
23
+#include "StreamRecv.h"
22 24
 #include "Time.h"
23 25
 #include "TimeCallee.h"
24 26
 
... ...
@@ -34,13 +36,16 @@ Player::Player(CallMgr &callMgr, StreamMgr &streamMgr,
34 36
                const Directory &dirBase):
35 37
   Module(callMgr, streamMgr, dirBase),
36 38
   m_fileOutStream(dirBase.getFile("outstream"), streamMgr),
39
+  m_fileHaltStream(dirBase.getFile("haltstream"), streamMgr),
37 40
   m_playlistTracker(*this, dirBase.getSubdir("playlist")),
38 41
   m_curValid(false),
39 42
   m_curEntry(m_playlistTracker.m_list.begin()),
40 43
   m_curFrame(0),
41
-  m_curChange(false)
44
+  m_curChange(false),
45
+  m_halted(false)
42 46
 {
43 47
   // load playlist
48
+  m_fileHaltStream.setStreamRecv(this);
44 49
   m_playlistTracker.init();
45 50
   checkCurChanged();
46 51
 }
... ...
@@ -53,6 +58,7 @@ Player::~Player()
53 58
 
54 59
   // free all movies
55 60
   m_playlistTracker.clear();
61
+  m_fileHaltStream.setStreamRecv(NULL);
56 62
 }
57 63
 
58 64
 /// check for update of configuration
... ...
@@ -64,14 +70,59 @@ void Player::updateConfig()
64 70
     sendFrame();
65 71
   }
66 72
 
73
+  // halt stream name file was modified -> re-get halt stream
74
+  if (m_fileHaltStream.checkModified())
75
+    m_fileHaltStream.update();
76
+
67 77
   // playlist update
68 78
   m_playlistTracker.updateConfig();
69 79
   checkCurChanged();
70 80
 }
71 81
 
82
+/**
83
+ * @brief set current frame
84
+ * @param[in] stream stream name
85
+ * @param[in] pFrame current frame (NULL for none)
86
+ */
87
+void Player::setFrame(const std::string &stream, stBlinkenFrame *pFrame)
88
+{
89
+  // this is coming from the halt stream, which will halt the player
90
+  // whenever a frame is available on this halt stream
91
+
92
+  // halt stream came to life -> halt player
93
+  if (pFrame && !m_halted) {
94
+    m_halted = true;
95
+    if (m_curValid) {
96
+      // store remaining frame time
97
+      m_remainTime = m_nextTime - Time::now();
98
+      if (m_remainTime < Time::zero)
99
+        m_remainTime = Time::zero;
100
+    }
101
+    // cancel time call
102
+    m_callMgr.cancelTimeCall(this);
103
+  }
104
+
105
+  // halt stream ended -> continue playing
106
+  else if (!pFrame && m_halted) {
107
+    m_halted = false;
108
+    if (m_curValid) {
109
+      // determine time for next frame
110
+      m_nextTime = Time::now() + m_remainTime;
111
+      // schedule time call
112
+      m_callMgr.requestTimeCall(this, m_nextTime);
113
+    }
114
+  }
115
+
116
+  (void)stream; // unused
117
+}
118
+
72 119
 /// callback when requested time reached
73 120
 void Player::timeCall()
74 121
 {
122
+  // leave if halted
123
+  if (m_halted)
124
+    return;
125
+
75 126
   // leave if time is not yet ready to next frame
76 127
   if (Time::now() < m_nextTime) {
77 128
     // request call at time for next frame
... ...
@@ -95,6 +146,7 @@ void Player::checkCurChanged()
95 146
 
96 147
     // go to begin of new current movie and start playing now
97 148
     m_curFrame = 0;
149
+    m_remainTime = Time::zero;
98 150
     m_nextTime = Time::now();
99 151
     procFrame();
100 152
 
... ...
@@ -135,13 +187,13 @@ void Player::procFrame()
135 187
 
136 188
   // if a frame is there
137 189
   if (m_curValid) {
138
-    // calculate time for next frame
190
+    // get frame time and calculate absolute time for next frame
139 191
     stBlinkenFrame *pFrame =
140 192
       BlinkenMovieGetFrame(m_curEntry->m_pObj->m_pMovie, m_curFrame);
141
-    Time duration;
142
-    duration.fromMs(BlinkenFrameGetDuration(pFrame));
143
-    m_nextTime += duration;
193
+    m_remainTime.fromMs(BlinkenFrameGetDuration(pFrame));
194
+    m_nextTime += m_remainTime;
144 195
     // request call at time for next frame
196
+    if (!m_halted)
145 197
       m_callMgr.requestTimeCall(this, m_nextTime);
146 198
   }
147 199
 }
... ...
@@ -14,17 +14,19 @@
14 14
 #include "CallMgr.h"
15 15
 #include "Directory.h"
16 16
 #include "File.h"
17
-#include "Module.h"
17
+#include "InStreamFile.h"
18 18
 #include "ListTracker.h"
19
+#include "Module.h"
19 20
 #include "OutStreamFile.h"
20 21
 #include "StreamMgr.h"
22
+#include "StreamRecv.h"
21 23
 #include "Time.h"
22 24
 #include "TimeCallee.h"
23 25
 
24 26
 namespace Blinker {
25 27
 
26 28
 /// a movie player
27
-class Player: public Module, public TimeCallee
29
+class Player: public Module, public StreamRecv, public TimeCallee
28 30
 {
29 31
 protected:
30 32
   /// movie in playlist
... ...
@@ -59,6 +61,13 @@ public:
59 61
   /// check for update of configuration
60 62
   virtual void updateConfig();
61 63
 
64
+  /**
65
+   * @brief set current frame
66
+   * @param[in] stream stream name
67
+   * @param[in] pFrame current frame (NULL for none)
68
+   */
69
+  virtual void setFrame(const std::string &stream, stBlinkenFrame *pFrame);
70
+
62 71
   /// callback when requested time reached
63 72
   virtual void timeCall();
64 73
 
... ...
@@ -74,12 +83,18 @@ protected:
74 83
 
75 84
 protected:
76 85
   OutStreamFile   m_fileOutStream;   ///< output stream name file
86
+  InStreamFile    m_fileHaltStream;  /**< halt stream name file
87
+                                          (player halts if stream active) */
77 88
   PlaylistTracker m_playlistTracker; ///< current playlist
78 89
   bool            m_curValid;        ///< if there is a current frame
79 90
   PlaylistIt      m_curEntry;        ///< current playlist entry
80 91
   int             m_curFrame;        ///< current frame in movie
81 92
   bool            m_curChange;       ///< current movie changed
82
-  Time            m_nextTime;        ///< when to show next frame
93
+  bool            m_halted;          ///< if player is halted
94
+  Time            m_remainTime;      /**< remaining time of current frame
95
+                                          (valid if m_curValid && m_halted) */
96
+  Time            m_nextTime;        /**< when to show next frame
97
+                                          (valid if m_curValid && !m_halted) */
83 98
 }; // class Player
84 99
 
85 100
 } // namespace Blinker
86 101