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