BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
3032550
Branches
Tags
master
Blinker
src
noarch
Player.cpp
first version, plays videos to stdout
Stefan Schuermans
commited
3032550
at 2011-10-23 11:37:40
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 "Player.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): m_callMgr(callMgr), m_streamMgr(streamMgr), m_dirBase(dirBase), m_dirPlaylist(dirBase.getSubdir("playlist")), m_streamName("TEST"), // TODO m_pStream(NULL), m_curEntry(m_playlist.begin()), m_curFrame(0) { // get output stream m_pStream = &m_streamMgr.refStream(m_streamName); // load playlist updatePlaylist(); } /// virtual destructor Player::~Player() { // free all movies while (!m_playlist.empty()) { m_playlist.back().freeMovie(); m_playlist.pop_back(); } // unreference stream m_pStream = NULL; m_streamMgr.unrefStream(m_streamName); } /// callback when requsted time reached void Player::timeCall() { // show next frame showFrame(); } /// update playlist void Player::updatePlaylist() { // get list of files in playlist directory typedef std::list<std::string> Filelist; Filelist curFiles; m_dirPlaylist.getEntries(Directory::TypeFile, curFiles); // walk through current playlist and file list simultaneously bool bWasEmpty = m_playlist.empty(); Filelist::const_iterator itFile = curFiles.begin(); Playlist::iterator itEntry = m_playlist.begin(); bool bCurChg = false; while (itFile != curFiles.end() || itEntry != m_playlist.end()) { // new movie inserted if (itEntry == m_playlist.end() || *itFile < itEntry->m_name) { // load movie Entry entry(*itFile, m_dirPlaylist.getFile(*itFile)); if (entry.loadMovie()) // insert playlist entry m_playlist.insert(itEntry, entry); // advance to next file ++itFile; } // movie removed // movie changed (=> remove and re-insert in next iteration) else if (itFile == curFiles.end() || *itFile > itEntry->m_name || itEntry->m_file.checkModified()) { // check if movie to remov movie is current movie if (itEntry == m_curEntry) { // advance current movie to next movie ++m_curEntry; bCurChg = true; } // remove entry itEntry->freeMovie(); itEntry = m_playlist.erase(itEntry); // do not advance to next file } // movie stayed in playlist and did not change else { // advance to next file and next entry ++itFile; ++itEntry; } } // while itFile itPlaylist // current movie entry changed - or - playlist was empty and is not now if (bCurChg || (bWasEmpty && !m_playlist.empty())) { // go to begin of movie and start playing now m_curFrame = 0; m_showTime = Time::now(); showFrame(); } } /// show current frame void Player::showFrame() { // leave if time is not yet ready to show frame if (Time::now() < m_showTime) { m_callMgr.requestTimeCall(this, m_showTime); // request call at show time return; } // movie finished -> next movie // use while loops to handle empty movies / empty playlist bool wrapped = false; while (true) { // playlist finished -> re-start from beginning while (m_curEntry == m_playlist.end()) { m_curEntry = m_playlist.begin(); m_curFrame = 0; // detect empty playlist or playlist with only empty movies if (wrapped) { // empty playlist or playlist with only empty movies -> no frame if (m_pStream) m_pStream->setNoFrame(); return; } wrapped = true; } // movie not yet finished -> done if (m_curFrame < BlinkenMovieGetFrameCnt(m_curEntry->m_pMovie)) break; // movie finished -> next movie ++m_curEntry; m_curFrame = 0; } // show frame stBlinkenFrame *pFrame = BlinkenMovieGetFrame(m_curEntry->m_pMovie, m_curFrame); if (m_pStream) m_pStream->setFrame(pFrame); // calculate show time for next frame Time duration; duration.fromMs(BlinkenFrameGetDuration(pFrame)); m_showTime += duration; m_callMgr.requestTimeCall(this, m_showTime); // request call at show time // go to next frame ++m_curFrame; } /* ################# # Player::Entry # ################# */ /// constructor Player::Entry::Entry(const std::string &name, const File &file): m_name(name), m_file(file), m_pMovie(NULL) { } /// load movie from current file bool Player::Entry::loadMovie() { freeMovie(); m_pMovie = BlinkenMovieLoad(m_file.getPath().c_str()); return m_pMovie; } /// free current movie void Player::Entry::freeMovie() { if (m_pMovie) { BlinkenMovieFree(m_pMovie); m_pMovie = NULL; } } } // namespace Blinker