bd3558966d9c087638d52dfe1e5987c969717522
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) {
50)   // free all movies
51)   while (!m_playlist.empty()) {
52)     m_playlist.back().freeMovie();
53)     m_playlist.pop_back();
54)   }
55) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

58) }
59) 
Stefan Schuermans implemented base class for...

Stefan Schuermans authored 13 years ago

60) /// check for update of configuration
61) void Player::updateConfig()
62) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

74) }
75) 
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

76) /// callback when requsted time reached
77) void Player::timeCall()
78) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

91) }
92) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

194)   }
195) }
196) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

199) {
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

205) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

236)         m_curValid = false;
237)         break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

238)       }
239)       wrapped = true;
240)     }
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

241)     if (!m_curValid)
242)       break;
Stefan Schuermans first version, plays videos...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

253) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

266) 
Stefan Schuermans implemented automatic check...

Stefan Schuermans authored 13 years ago

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