Move things round a bit.
[dcpomatic.git] / src / lib / player_manager.cc
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "player_manager.h"
21 #include "player.h"
22 #include "film_state.h"
23 #include "screen.h"
24
25 using namespace std;
26 using namespace boost;
27
28 PlayerManager* PlayerManager::_instance = 0;
29
30 PlayerManager::PlayerManager ()
31 {
32
33 }
34
35 PlayerManager *
36 PlayerManager::instance ()
37 {
38         if (_instance == 0) {
39                 _instance = new PlayerManager ();
40         }
41
42         return _instance;
43 }
44
45 void
46 PlayerManager::setup (shared_ptr<const FilmState> fs, shared_ptr<const Screen> sc)
47 {
48         boost::mutex::scoped_lock lm (_players_mutex);
49         
50         _players.clear ();
51         _players.push_back (shared_ptr<Player> (new Player (fs, sc, Player::SPLIT_NONE)));
52 }
53
54 void
55 PlayerManager::setup (shared_ptr<const FilmState> fs_a, shared_ptr<const FilmState> fs_b, shared_ptr<const Screen> sc)
56 {
57         boost::mutex::scoped_lock lm (_players_mutex);
58         
59         _players.clear ();
60
61         _players.push_back (shared_ptr<Player> (new Player (fs_a, sc, Player::SPLIT_LEFT)));
62         _players.push_back (shared_ptr<Player> (new Player (fs_b, sc, Player::SPLIT_RIGHT)));
63 }
64
65 void
66 PlayerManager::pause_or_unpause ()
67 {
68         boost::mutex::scoped_lock lm (_players_mutex);
69         
70         for (list<shared_ptr<Player> >::iterator i = _players.begin(); i != _players.end(); ++i) {
71                 (*i)->command ("pause");
72         }
73 }
74
75 void
76 PlayerManager::set_position (float p)
77 {
78         boost::mutex::scoped_lock lm (_players_mutex);
79         
80         stringstream s;
81         s << "pausing_keep_force seek " << p << " 2";
82         for (list<shared_ptr<Player> >::iterator i = _players.begin(); i != _players.end(); ++i) {
83                 (*i)->command (s.str ());
84         }
85 }
86
87 float
88 PlayerManager::position () const
89 {
90         boost::mutex::scoped_lock lm (_players_mutex);
91         
92         if (_players.empty ()) {
93                 return 0;
94         }
95
96         return _players.front()->position ();
97 }
98
99 void
100 PlayerManager::child_exited (pid_t pid)
101 {
102         boost::mutex::scoped_lock lm (_players_mutex);
103         
104         list<shared_ptr<Player> >::iterator i = _players.begin();
105         while (i != _players.end() && (*i)->mplayer_pid() != pid) {
106                 ++i;
107         }
108         
109         if (i == _players.end()) {
110                 return;
111         }
112
113         _players.erase (i);
114 }
115
116 PlayerManager::State
117 PlayerManager::state () const
118 {
119         boost::mutex::scoped_lock lm (_players_mutex);
120
121         if (_players.empty ()) {
122                 return QUIESCENT;
123         }
124
125         if (_players.front()->paused ()) {
126                 return PAUSED;
127         }
128
129         return PLAYING;
130 }
131
132 void
133 PlayerManager::stop ()
134 {
135         boost::mutex::scoped_lock lm (_players_mutex);
136         _players.clear ();
137 }