b3b45af39ecb670ce786a14135e2ef31401ea67e
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

1) /* Blinker
2)    Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3)    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4)    a blinkenarea.org project */
5) 
6) #include <list>
7) #include <string>
8) 
9) #include <BlinkenLib/BlinkenFrame.h>
10) #include <BlinkenLib/BlinkenMovie.h>
11) 
12) #include "CallMgr.h"
13) #include "Directory.h"
14) #include "File.h"
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

15) #include "Module.h"
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

16) #include "Player.h"
Stefan Schuermans implemented stream printer...

Stefan Schuermans authored 13 years ago

17) #include "SettingFile.h"
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

18) #include "StreamMgr.h"
19) #include "Time.h"
20) #include "TimeCallee.h"
21) 
22) namespace Blinker {
23) 
24) /**
25)  * @brief constructor
26)  * @param[in] callMgr callback manager
27)  * @param[in] streamMgr stream manager
28)  * @param[in] dirBase base directory
29)  */
30) Player::Player(CallMgr &callMgr, StreamMgr &streamMgr,
31)                const Directory &dirBase):
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

32)   Module(callMgr, streamMgr, dirBase),
Stefan Schuermans implemented stream printer...

Stefan Schuermans authored 13 years ago

33)   m_fileOutStream(dirBase.getFile("outstream")),
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

34)   m_dirPlaylist(dirBase.getSubdir("playlist")),
Stefan Schuermans implemented stream printer...

Stefan Schuermans authored 13 years ago

35)   m_pOutStream(NULL),
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

36)   m_curValid(false),
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

37)   m_curEntry(m_playlist.begin()),
38)   m_curFrame(0)
39) {
40)   // get output stream
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

41)   getOutStream();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

42) 
43)   // load playlist
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

44)   updatePlaylistFull();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

45) }
46) 
47) /// virtual destructor
48) Player::~Player()
49) {
Stefan Schuermans cancel time callback reques...

Stefan Schuermans authored 13 years ago

50)   // cancel time callback request
51)   m_callMgr.cancelTimeCall(this);
52) 
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

53)   // free all movies
54)   while (!m_playlist.empty()) {
55)     m_playlist.back().freeMovie();
56)     m_playlist.pop_back();
57)   }
58) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

59)   // release output stream
60)   releaseOutStream();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

61) }
62) 
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

63) /// check for update of configuration
64) void Player::updateConfig()
65) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

66)   // output stream name file was modified -> re-get output stream
67)   if (m_fileOutStream.checkModified()) {
68)     releaseOutStream();
69)     getOutStream();
70)   }
71) 
72)   // playlist update (directory modified -> full, otherwise -> light)
73)   if (m_dirPlaylist.checkModified())
74)     updatePlaylistFull();
75)   else
76)     updatePlaylistLight();
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

77) }
78) 
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

79) /// callback when requsted time reached
80) void Player::timeCall()
81) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

82)   // leave if time is not yet ready to next frame
83)   if (Time::now() < m_nextTime) {
84)     // request call at time for next frame
85)     m_callMgr.requestTimeCall(this, m_nextTime);
86)     return;
87)   }
88) 
89)   // go to next frame
90)   ++m_curFrame;
91) 
92)   // process new current frame
93)   procFrame();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

94) }
95) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

96) /// light update of playlist, i.e. stat all files in current playlist
97) void Player::updatePlaylistLight()
98) {
99)   // walk through all files in playlist and check for modification
100)   Playlist::iterator itEntry = m_playlist.begin();
101)   bool               bCurChg = false;
102)   while (itEntry != m_playlist.end()) {
103) 
104)     // movie changed
105)     if (itEntry->m_file.checkModified()) {
106)       // check if changed movie is current movie
107)       if (itEntry == m_curEntry) {
108)         // advance current movie to next movie
109)         ++m_curEntry;
110)         bCurChg = true;
111)       }
112)       // remove entry
113)       itEntry->freeMovie();
114)       itEntry = m_playlist.erase(itEntry);
115)       // re-load entry
116)       itEntry->freeMovie();
117)       if (!itEntry->loadMovie()) {
118)         // loading movie failed -> remove entry
119)         itEntry = m_playlist.erase(itEntry);
120)         // do not advance to next file
121)         continue;
122)       }
123)     }
124) 
125)     // advance to next file
126)     ++itEntry;
127) 
128)   } // while itEntry
129) 
130)   // current movie entry changed
131)   if (bCurChg) {
132)     // go to begin of new current movie and start playing now
133)     m_curFrame = 0;
134)     m_nextTime = Time::now();
135)     procFrame();
136)   }
137) }
138) 
139) /// full update of playlist, i.e. scan files in playlist directory
140) void Player::updatePlaylistFull()
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

141) {
142)   // get list of files in playlist directory
143)   typedef std::list<std::string> Filelist;
144)   Filelist curFiles;
145)   m_dirPlaylist.getEntries(Directory::TypeFile, curFiles);
146) 
147)   // walk through current playlist and file list simultaneously
148)   bool                     bWasEmpty = m_playlist.empty();
149)   Filelist::const_iterator itFile    = curFiles.begin();
150)   Playlist::iterator       itEntry   = m_playlist.begin();
151)   bool                     bCurChg   = false;
152)   while (itFile != curFiles.end() || itEntry != m_playlist.end()) {
153) 
154)     // new movie inserted
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

155)     if (itEntry == m_playlist.end() ||
156)         (itFile != curFiles.end() && *itFile < itEntry->m_name)) {
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

157)       // load movie
158)       Entry entry(*itFile, m_dirPlaylist.getFile(*itFile));
159)       if (entry.loadMovie())
160)         // insert playlist entry
161)         m_playlist.insert(itEntry, entry);
162)       // advance to next file
163)       ++itFile;
164)     }
165) 
166)     // movie removed
167)     // movie changed (=> remove and re-insert in next iteration)
168)     else if (itFile == curFiles.end() || *itFile > itEntry->m_name ||
169)              itEntry->m_file.checkModified()) {
Stefan Schuermans fix comments

Stefan Schuermans authored 13 years ago

170)       // check if movie to remove is current movie
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

171)       if (itEntry == m_curEntry) {
172)         // advance current movie to next movie
173)         ++m_curEntry;
174)         bCurChg = true;
175)       }
176)       // remove entry
177)       itEntry->freeMovie();
178)       itEntry = m_playlist.erase(itEntry);
179)       // do not advance to next file
180)     }
181) 
182)     // movie stayed in playlist and did not change
183)     else {
184)       // advance to next file and next entry
185)       ++itFile;
186)       ++itEntry;
187)     }
188) 
Stefan Schuermans fix comments

Stefan Schuermans authored 13 years ago

189)   } // while itFile itEntry
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

190) 
191)   // current movie entry changed - or - playlist was empty and is not now
192)   if (bCurChg || (bWasEmpty && !m_playlist.empty())) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

193)     // go to begin of new current movie and start playing now
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

194)     m_curFrame = 0;
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

195)     m_nextTime = Time::now();
196)     procFrame();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

197)   }
198) }
199) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

200) /// get output stream
201) void Player::getOutStream()
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

202) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

203)   // get name of output stream
204)   m_fileOutStream.getStr(m_nameOutStream);
205) 
206)   // get output stream
207)   m_pOutStream = &m_streamMgr.refStream(m_nameOutStream);
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

208) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

209)   // send current frame to stream
210)   sendFrame();
211) }
212) 
213) /// release output stream
214) void Player::releaseOutStream()
215) {
216)   // send no frame information
217)   if (m_pOutStream)
218)     m_pOutStream->setNoFrame();
219) 
220)   // unreference output stream
221)   m_pOutStream = NULL;
222)   m_streamMgr.unrefStream(m_nameOutStream);
223) }
224) 
225) /// process current frame
226) void Player::procFrame()
227) {
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

228)   // movie finished -> next movie
229)   //   use while loops to handle empty movies / empty playlist
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

230)   m_curValid = true;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

231)   bool wrapped = false;
232)   while (true) {
233)     // playlist finished -> re-start from beginning
234)     while (m_curEntry == m_playlist.end()) {
235)       m_curEntry = m_playlist.begin();
236)       m_curFrame = 0;
237)       // detect empty playlist or playlist with only empty movies
238)       if (wrapped) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

239)         m_curValid = false;
240)         break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

241)       }
242)       wrapped = true;
243)     }
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

244)     if (!m_curValid)
245)       break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

246)     // movie not yet finished -> done
247)     if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pMovie))
248)       break;
249)     // movie finished -> next movie
250)     ++m_curEntry;
251)     m_curFrame = 0;
252)   }
253) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

254)   // send new frame to stream
255)   sendFrame();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

256) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

257)   // if a frame is there
258)   if (m_curValid) {
259)     // calculate time for next frame
260)     stBlinkenFrame *pFrame =
261)       BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
262)     Time duration;
263)     duration.fromMs(BlinkenFrameGetDuration(pFrame));
264)     m_nextTime += duration;
265)     // request call at time for next frame
266)     m_callMgr.requestTimeCall(this, m_nextTime);
267)   }
268) }
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

269) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

270) /// send current frame to output stream
271) void Player::sendFrame()
272) {
273)   if (m_pOutStream) {
274)     // frame avalable -> send it
275)     if (m_curValid) {
276)       stBlinkenFrame *pFrame =
277)         BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
278)       m_pOutStream->setFrame(pFrame);
279)     }
280)     // no frame available -> send this information
281)     else
282)       m_pOutStream->setNoFrame();
283)   }