BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
5b311bf
Branches
Tags
master
Blinker
src
noarch
Player.cpp
converted player module to use list tracker
Stefan Schuermans
commited
5b311bf
at 2011-12-11 13:03:52
Player.cpp
Blame
History
Raw
/* Blinker Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <list> #include <string> #include <BlinkenLib/BlinkenFrame.h> #include <BlinkenLib/BlinkenMovie.h> #include "CallMgr.h" #include "Directory.h" #include "File.h" #include "Module.h" #include "ListTracker.h" #include "ListTracker_impl.h" #include "OutStreamFile.h" #include "Player.h" #include "PlayerMovie.h" #include "StreamMgr.h" #include "Time.h" #include "TimeCallee.h" namespace Blinker { /** * @brief constructor * @param[in] callMgr callback manager * @param[in] streamMgr stream manager * @param[in] dirBase base directory */ Player::Player(CallMgr &callMgr, StreamMgr &streamMgr, const Directory &dirBase): Module(callMgr, streamMgr, dirBase), m_fileOutStream(dirBase.getFile("outstream"), streamMgr), m_playlistTracker(*this, dirBase.getSubdir("playlist")), m_curValid(false), m_curEntry(m_playlistTracker.m_list.begin()), m_curFrame(0), m_curChange(false) { // load playlist m_playlistTracker.init(); checkCurChanged(); } /// virtual destructor Player::~Player() { // cancel time callback request m_callMgr.cancelTimeCall(this); // free all movies m_playlistTracker.clear(); } /// check for update of configuration void Player::updateConfig() { // output stream name file was modified -> re-get output stream if (m_fileOutStream.checkModified()) { m_fileOutStream.update(); sendFrame(); } // playlist update m_playlistTracker.updateConfig(); checkCurChanged(); } /// callback when requested time reached void Player::timeCall() { // leave if time is not yet ready to next frame if (Time::now() < m_nextTime) { // request call at time for next frame m_callMgr.requestTimeCall(this, m_nextTime); return; } // go to next frame ++m_curFrame; // process new current frame procFrame(); } /// check if current movie changed and react void Player::checkCurChanged() { // current movie changed if (m_curChange) { m_curChange = false; // go to begin of new current movie and start playing now m_curFrame = 0; m_nextTime = Time::now(); procFrame(); } // if (m_curChange) } /// process current frame void Player::procFrame() { // movie finished -> next movie // use while loops to handle empty movies / empty playlist m_curValid = true; bool wrapped = false; while (true) { // playlist finished -> re-start from beginning while (m_curEntry == m_playlistTracker.m_list.end()) { m_curEntry = m_playlistTracker.m_list.begin(); m_curFrame = 0; // detect empty playlist or playlist with only empty movies if (wrapped) { m_curValid = false; break; } wrapped = true; } if (!m_curValid) break; // movie not yet finished -> done if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pObj->m_pMovie)) break; // movie finished -> next movie ++m_curEntry; m_curFrame = 0; } // send new frame to stream sendFrame(); // if a frame is there if (m_curValid) { // calculate time for next frame stBlinkenFrame *pFrame = BlinkenMovieGetFrame(m_curEntry->m_pObj->m_pMovie, m_curFrame); Time duration; duration.fromMs(BlinkenFrameGetDuration(pFrame)); m_nextTime += duration; // request call at time for next frame m_callMgr.requestTimeCall(this, m_nextTime); } } /// send current frame to output stream void Player::sendFrame() { // frame avalable -> send it if (m_curValid) { stBlinkenFrame *pFrame = BlinkenMovieGetFrame(m_curEntry->m_pObj->m_pMovie, m_curFrame); m_fileOutStream.setFrame(pFrame); } // no frame available -> send this information else m_fileOutStream.setFrame(NULL); } } // namespace Blinker