e5fbb671dd20e7f770fee744a5c8c676fd45d509
[dcpomatic.git] / src / wx / video_view.h
1 /*
2     Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #ifndef DCPOMATIC_VIDEO_VIEW_H
22 #define DCPOMATIC_VIDEO_VIEW_H
23
24 #include "lib/dcpomatic_time.h"
25 #include "lib/timer.h"
26 #include "lib/types.h"
27 #include "lib/exception_store.h"
28 #include <boost/shared_ptr.hpp>
29 #include <boost/signals2.hpp>
30 #include <boost/thread.hpp>
31 #include <boost/noncopyable.hpp>
32
33 class Image;
34 class wxWindow;
35 class FilmViewer;
36 class Player;
37 class PlayerVideo;
38
39 class VideoView : public ExceptionStore, public boost::noncopyable
40 {
41 public:
42         VideoView (FilmViewer* viewer);
43         virtual ~VideoView () {}
44
45         /** @return the thing displaying the image */
46         virtual wxWindow* get () const = 0;
47         /** Re-make and display the image from the current _player_video */
48         virtual void update () = 0;
49         /** Called when playback starts */
50         virtual void start ();
51         /** Called when playback stops */
52         virtual void stop () {}
53
54         enum NextFrameResult {
55                 FAIL,
56                 AGAIN,
57                 SUCCESS
58         };
59
60         /** Get the next frame and display it; used after seek */
61         virtual NextFrameResult display_next_frame (bool) = 0;
62
63         void clear ();
64         bool reset_metadata (boost::shared_ptr<const Film> film, dcp::Size player_video_container_size);
65
66         /** Emitted from the GUI thread when our display changes in size */
67         boost::signals2::signal<void()> Sized;
68
69
70         /* Accessors for FilmViewer */
71
72         int dropped () const {
73                 boost::mutex::scoped_lock lm (_mutex);
74                 return _dropped;
75         }
76
77         int errored () const {
78                 boost::mutex::scoped_lock lm (_mutex);
79                 return _errored;
80         }
81
82         int gets () const {
83                 boost::mutex::scoped_lock lm (_mutex);
84                 return _gets;
85         }
86
87         StateTimer const & state_timer () const {
88                 return _state_timer;
89         }
90
91         dcpomatic::DCPTime position () const {
92                 boost::mutex::scoped_lock lm (_mutex);
93                 return _player_video.second;
94         }
95
96
97         /* Setters for FilmViewer so it can tell us our state and
98          * we can then use (thread) safely.
99          */
100
101         void set_video_frame_rate (int r) {
102                 boost::mutex::scoped_lock lm (_mutex);
103                 _video_frame_rate = r;
104         }
105
106         void set_length (dcpomatic::DCPTime len) {
107                 boost::mutex::scoped_lock lm (_mutex);
108                 _length = len;
109         }
110
111         void set_eyes (Eyes eyes) {
112                 boost::mutex::scoped_lock lm (_mutex);
113                 _eyes = eyes;
114         }
115
116         void set_three_d (bool t) {
117                 boost::mutex::scoped_lock lm (_mutex);
118                 _three_d = t;
119         }
120
121 protected:
122         NextFrameResult get_next_frame (bool non_blocking);
123         boost::optional<int> time_until_next_frame () const;
124         dcpomatic::DCPTime one_video_frame () const;
125
126         int video_frame_rate () const {
127                 boost::mutex::scoped_lock lm (_mutex);
128                 return _video_frame_rate;
129         }
130
131         dcpomatic::DCPTime length () const {
132                 boost::mutex::scoped_lock lm (_mutex);
133                 return _length;
134         }
135
136         std::pair<boost::shared_ptr<PlayerVideo>, dcpomatic::DCPTime> player_video () const {
137                 boost::mutex::scoped_lock lm (_mutex);
138                 return _player_video;
139         }
140
141         void add_dropped () {
142                 boost::mutex::scoped_lock lm (_mutex);
143                 ++_dropped;
144         }
145
146         void add_get () {
147                 boost::mutex::scoped_lock lm (_mutex);
148                 ++_gets;
149         }
150
151         FilmViewer* _viewer;
152
153         StateTimer _state_timer;
154
155 private:
156         /** Mutex protecting all the state in this class */
157         mutable boost::mutex _mutex;
158
159         std::pair<boost::shared_ptr<PlayerVideo>, dcpomatic::DCPTime> _player_video;
160         int _video_frame_rate;
161         /** length of the film we are playing, or 0 if there is none */
162         dcpomatic::DCPTime _length;
163         Eyes _eyes;
164         bool _three_d;
165
166         int _dropped;
167         int _errored;
168         int _gets;
169 };
170
171 #endif