0fee1b0dbe796d5c03abdc7b516de170331aed5b
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 implemented specialized set...

Stefan Schuermans authored 12 years ago

16) #include "OutStreamFile.h"
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

17) #include "Player.h"
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 specialized set...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 13 years ago

34)   m_dirPlaylist(dirBase.getSubdir("playlist")),
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

36)   m_curEntry(m_playlist.begin()),
37)   m_curFrame(0)
38) {
39)   // load playlist
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

41) }
42) 
43) /// virtual destructor
44) Player::~Player()
45) {
Stefan Schuermans cancel time callback reques...

Stefan Schuermans authored 13 years ago

46)   // cancel time callback request
47)   m_callMgr.cancelTimeCall(this);
48) 
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

49)   // free all movies
50)   while (!m_playlist.empty()) {
51)     m_playlist.back().freeMovie();
52)     m_playlist.pop_back();
53)   }
54) }
55) 
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

56) /// check for update of configuration
57) void Player::updateConfig()
58) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

59)   // output stream name file was modified -> re-get output stream
60)   if (m_fileOutStream.checkModified()) {
Stefan Schuermans implemented specialized set...

Stefan Schuermans authored 12 years ago

61)     m_fileOutStream.update();
62)     sendFrame();
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

63)   }
64) 
65)   // playlist update (directory modified -> full, otherwise -> light)
66)   if (m_dirPlaylist.checkModified())
67)     updatePlaylistFull();
68)   else
69)     updatePlaylistLight();
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

70) }
71) 
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

72) /// callback when requsted time reached
73) void Player::timeCall()
74) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

75)   // leave if time is not yet ready to next frame
76)   if (Time::now() < m_nextTime) {
77)     // request call at time for next frame
78)     m_callMgr.requestTimeCall(this, m_nextTime);
79)     return;
80)   }
81) 
82)   // go to next frame
83)   ++m_curFrame;
84) 
85)   // process new current frame
86)   procFrame();
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

87) }
88) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

131) {
132)   // get list of files in playlist directory
133)   typedef std::list<std::string> Filelist;
134)   Filelist curFiles;
135)   m_dirPlaylist.getEntries(Directory::TypeFile, curFiles);
136) 
137)   // walk through current playlist and file list simultaneously
138)   bool                     bWasEmpty = m_playlist.empty();
139)   Filelist::const_iterator itFile    = curFiles.begin();
140)   Playlist::iterator       itEntry   = m_playlist.begin();
141)   bool                     bCurChg   = false;
142)   while (itFile != curFiles.end() || itEntry != m_playlist.end()) {
143) 
144)     // new movie inserted
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

147)       // load movie
148)       Entry entry(*itFile, m_dirPlaylist.getFile(*itFile));
149)       if (entry.loadMovie())
150)         // insert playlist entry
151)         m_playlist.insert(itEntry, entry);
152)       // advance to next file
153)       ++itFile;
154)     }
155) 
156)     // movie removed
157)     // movie changed (=> remove and re-insert in next iteration)
158)     else if (itFile == curFiles.end() || *itFile > itEntry->m_name ||
159)              itEntry->m_file.checkModified()) {
Stefan Schuermans fix comments

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

161)       if (itEntry == m_curEntry) {
162)         // advance current movie to next movie
163)         ++m_curEntry;
164)         bCurChg = true;
165)       }
166)       // remove entry
167)       itEntry->freeMovie();
168)       itEntry = m_playlist.erase(itEntry);
169)       // do not advance to next file
170)     }
171) 
172)     // movie stayed in playlist and did not change
173)     else {
174)       // advance to next file and next entry
175)       ++itFile;
176)       ++itEntry;
177)     }
178) 
Stefan Schuermans fix comments

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

187)   }
188) }
189) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

190) /// process current frame
191) void Player::procFrame()
192) {
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

196)   bool wrapped = false;
197)   while (true) {
198)     // playlist finished -> re-start from beginning
199)     while (m_curEntry == m_playlist.end()) {
200)       m_curEntry = m_playlist.begin();
201)       m_curFrame = 0;
202)       // detect empty playlist or playlist with only empty movies
203)       if (wrapped) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

204)         m_curValid = false;
205)         break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

206)       }
207)       wrapped = true;
208)     }
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

209)     if (!m_curValid)
210)       break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

211)     // movie not yet finished -> done
212)     if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pMovie))
213)       break;
214)     // movie finished -> next movie
215)     ++m_curEntry;
216)     m_curFrame = 0;
217)   }
218) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

221) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

222)   // if a frame is there
223)   if (m_curValid) {
224)     // calculate time for next frame
225)     stBlinkenFrame *pFrame =
226)       BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
227)     Time duration;
228)     duration.fromMs(BlinkenFrameGetDuration(pFrame));
229)     m_nextTime += duration;
230)     // request call at time for next frame
231)     m_callMgr.requestTimeCall(this, m_nextTime);
232)   }
233) }
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

234) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

235) /// send current frame to output stream
236) void Player::sendFrame()
237) {
Stefan Schuermans implemented specialized set...

Stefan Schuermans authored 12 years ago

238)   // frame avalable -> send it
239)   if (m_curValid) {
240)     stBlinkenFrame *pFrame =
241)       BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame);
242)     m_fileOutStream.setFrame(pFrame);
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

243)   }
Stefan Schuermans implemented specialized set...

Stefan Schuermans authored 12 years ago

244)   // no frame available -> send this information
245)   else
246)     m_fileOutStream.setFrame(NULL);