Supporters update.
[dcpomatic.git] / src / wx / video_view.h
1 /*
2     Copyright (C) 2019-2021 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
22 #ifndef DCPOMATIC_VIDEO_VIEW_H
23 #define DCPOMATIC_VIDEO_VIEW_H
24
25
26 #include "lib/dcpomatic_time.h"
27 #include "lib/exception_store.h"
28 #include "lib/signaller.h"
29 #include "lib/timer.h"
30 #include "lib/types.h"
31 #include <dcp/warnings.h>
32 #include <dcp/types.h>
33 LIBDCP_DISABLE_WARNINGS
34 #include <wx/wx.h>
35 LIBDCP_ENABLE_WARNINGS
36 #include <boost/signals2.hpp>
37 #include <boost/thread.hpp>
38
39
40 class FilmViewer;
41 class Image;
42 class Player;
43 class PlayerVideo;
44 class wxWindow;
45
46
47 class VideoView : public ExceptionStore, public Signaller
48 {
49 public:
50         VideoView (FilmViewer* viewer);
51         virtual ~VideoView () {}
52
53         VideoView (VideoView const&) = delete;
54         VideoView& operator= (VideoView const&) = delete;
55
56         /** @return the thing displaying the image */
57         virtual wxWindow* get () const = 0;
58         /** Re-make and display the image from the current _player_video */
59         virtual void update () = 0;
60         /** Called when playback starts */
61         virtual void start ();
62         /** Called when playback stops */
63         virtual void stop () {}
64
65         enum NextFrameResult {
66                 FAIL,
67                 AGAIN,
68                 SUCCESS
69         };
70
71         /** Get the next frame and display it; used after seek */
72         virtual NextFrameResult display_next_frame (bool) = 0;
73
74         void clear ();
75         bool reset_metadata (std::shared_ptr<const Film> film, dcp::Size player_video_container_size);
76
77         /** Emitted from the GUI thread when our display changes in size */
78         boost::signals2::signal<void()> Sized;
79         /** Emitted from the GUI thread when a lot of frames are being dropped */
80         boost::signals2::signal<void()> TooManyDropped;
81
82
83         /* Accessors for FilmViewer */
84
85         int dropped () const {
86                 boost::mutex::scoped_lock lm (_mutex);
87                 return _dropped;
88         }
89
90         int errored () const {
91                 boost::mutex::scoped_lock lm (_mutex);
92                 return _errored;
93         }
94
95         int gets () const {
96                 boost::mutex::scoped_lock lm (_mutex);
97                 return _gets;
98         }
99
100         StateTimer const & state_timer () const {
101                 return _state_timer;
102         }
103
104         dcpomatic::DCPTime position () const {
105                 boost::mutex::scoped_lock lm (_mutex);
106                 return _player_video.second;
107         }
108
109
110         /* Setters for FilmViewer so it can tell us our state and
111          * we can then use (thread) safely.
112          */
113
114         void set_video_frame_rate (int r) {
115                 boost::mutex::scoped_lock lm (_mutex);
116                 _video_frame_rate = r;
117         }
118
119         void set_length (dcpomatic::DCPTime len) {
120                 boost::mutex::scoped_lock lm (_mutex);
121                 _length = len;
122         }
123
124         void set_eyes (Eyes eyes) {
125                 boost::mutex::scoped_lock lm (_mutex);
126                 _eyes = eyes;
127         }
128
129         void set_three_d (bool t) {
130                 boost::mutex::scoped_lock lm (_mutex);
131                 _three_d = t;
132         }
133
134         void set_optimise_for_j2k (bool o) {
135                 _optimise_for_j2k = o;
136         }
137
138 protected:
139         NextFrameResult get_next_frame (bool non_blocking);
140         boost::optional<int> time_until_next_frame () const;
141         dcpomatic::DCPTime one_video_frame () const;
142
143         wxColour pad_colour () const;
144
145         wxColour outline_content_colour () const {
146                 return wxColour(255, 0, 0);
147         }
148
149         wxColour outline_subtitles_colour () const {
150                 return wxColour(0, 255, 0);
151         }
152
153         wxColour crop_guess_colour () const {
154                 return wxColour(0, 0, 255);
155         }
156
157         int video_frame_rate () const {
158                 boost::mutex::scoped_lock lm (_mutex);
159                 return _video_frame_rate;
160         }
161
162         dcpomatic::DCPTime length () const {
163                 boost::mutex::scoped_lock lm (_mutex);
164                 return _length;
165         }
166
167         std::pair<std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime> player_video () const {
168                 boost::mutex::scoped_lock lm (_mutex);
169                 return _player_video;
170         }
171
172         void add_dropped ();
173
174         void add_get () {
175                 boost::mutex::scoped_lock lm (_mutex);
176                 ++_gets;
177         }
178
179         FilmViewer* _viewer;
180
181         StateTimer _state_timer;
182
183         bool _optimise_for_j2k = false;
184
185 private:
186         /** Mutex protecting all the state in this class */
187         mutable boost::mutex _mutex;
188
189         std::pair<std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime> _player_video;
190         int _video_frame_rate = 0;
191         /** length of the film we are playing, or 0 if there is none */
192         dcpomatic::DCPTime _length;
193         Eyes _eyes = Eyes::LEFT;
194         bool _three_d = false;
195
196         int _dropped = 0;
197         struct timeval _dropped_check_period_start;
198         int _errored = 0;
199         int _gets = 0;
200 };
201
202
203 #endif