summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2019-11-06 01:09:13 +0100
committerCarl Hetherington <cth@carlh.net>2020-01-08 21:56:47 +0100
commit805487369e57e5eb57911805ba6de78b653d79ad (patch)
tree73c07ac5f6617c915df2f50d695367d3d6c56a6c
parent694a9f48880efd428c8137e975de3581ad0a75a9 (diff)
Various timing hacks and development.
-rw-r--r--src/wx/film_viewer.cc27
-rw-r--r--src/wx/film_viewer.h5
-rw-r--r--src/wx/gl_video_view.cc23
-rw-r--r--src/wx/gl_video_view.h3
-rw-r--r--src/wx/simple_video_view.cc14
-rw-r--r--src/wx/simple_video_view.h4
-rw-r--r--src/wx/video_view.h10
7 files changed, 52 insertions, 34 deletions
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 5c73f292c..f40ed229f 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -122,7 +122,7 @@ FilmViewer::~FilmViewer ()
/** Ask for ::get() to be called next time we are idle */
void
-FilmViewer::request_idle_get ()
+FilmViewer::request_idle_display_next_frame ()
{
if (_idle_get) {
return;
@@ -140,7 +140,7 @@ FilmViewer::idle_handler ()
return;
}
- if (_video_view->get(true)) {
+ if (_video_view->display_next_frame(true)) {
_idle_get = false;
} else {
/* get() could not complete quickly so we'll try again later */
@@ -156,7 +156,6 @@ FilmViewer::set_film (shared_ptr<Film> film)
}
_film = film;
- _video_position = DCPTime ();
_video_view->clear ();
_video_view->set_image (shared_ptr<Image>());
@@ -302,7 +301,7 @@ FilmViewer::resume ()
--_suspended;
if (_playing && !_suspended) {
if (_audio.isStreamOpen()) {
- _audio.setStreamTime (_video_position.seconds());
+ _audio.setStreamTime (_video_view->position().seconds());
_audio.startStream ();
}
_video_view->start ();
@@ -323,7 +322,7 @@ FilmViewer::start ()
}
if (_audio.isStreamOpen()) {
- _audio.setStreamTime (_video_position.seconds());
+ _audio.setStreamTime (_video_view->position().seconds());
_audio.startStream ();
}
@@ -393,7 +392,7 @@ FilmViewer::film_change (ChangeType type, Film::Property p)
void
FilmViewer::slow_refresh ()
{
- seek (_video_position, true);
+ seek (_video_view->position(), true);
}
/** Try to re-get the current frame quickly by resetting the metadata
@@ -458,7 +457,9 @@ FilmViewer::seek (DCPTime t, bool accurate)
_butler->seek (t, accurate);
if (!_playing) {
- request_idle_get ();
+ request_idle_display_next_frame ();
+ } else {
+ while (!_video_view->display_next_frame(false)) {}
}
resume ();
@@ -536,7 +537,7 @@ FilmViewer::uncorrected_time () const
return DCPTime::from_seconds (const_cast<RtAudio*>(&_audio)->getStreamTime());
}
- return _video_position;
+ return _video_view->position();
}
DCPTime
@@ -547,7 +548,7 @@ FilmViewer::time () const
DCPTime::from_frames (average_latency(), _film->audio_frame_rate());
}
- return _video_position;
+ return _video_view->position();
}
int
@@ -620,7 +621,7 @@ FilmViewer::show_closed_captions ()
void
FilmViewer::seek_by (DCPTime by, bool accurate)
{
- seek (_video_position + by, accurate);
+ seek (_video_view->position() + by, accurate);
}
void
@@ -634,5 +635,9 @@ int
FilmViewer::time_until_next_frame () const
{
DCPTime const next = position() + one_video_frame();
- return max ((next.seconds() - time().seconds()) * 1000, 1.0);
+ std::cout << to_string(next) << " " << to_string(time()) << " " << ((next.seconds() - time().seconds()) * 1000) << "\n";
+ if (next < time()) {
+ return 0;
+ }
+ return (next.seconds() - time().seconds()) * 1000;
}
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index 6b6aa78f5..beb1a5d74 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -69,7 +69,7 @@ public:
void seek_by (dcpomatic::DCPTime by, bool accurate);
/** @return our `playhead' position; this may not lie exactly on a frame boundary */
dcpomatic::DCPTime position () const {
- return _video_position;
+ return _video_view->position();
}
dcpomatic::DCPTime one_video_frame () const;
@@ -159,7 +159,7 @@ private:
void calculate_sizes ();
void player_change (ChangeType type, int, bool);
void idle_handler ();
- void request_idle_get ();
+ void request_idle_display_next_frame ();
void film_change (ChangeType, Film::Property);
void recreate_butler ();
void config_changed (Config::Property);
@@ -178,7 +178,6 @@ private:
bool _coalesce_player_changes;
std::list<int> _pending_player_changes;
- dcpomatic::DCPTime _video_position;
Position<int> _inter_position;
dcp::Size _inter_size;
diff --git a/src/wx/gl_video_view.cc b/src/wx/gl_video_view.cc
index c69ab210a..ebf8b8fe2 100644
--- a/src/wx/gl_video_view.cc
+++ b/src/wx/gl_video_view.cc
@@ -55,6 +55,7 @@ GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent)
: VideoView (viewer)
, _vsync_enabled (false)
, _thread (0)
+ , _one_shot (false)
{
_canvas = new wxGLCanvas (parent, wxID_ANY, 0, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE);
_canvas->Bind (wxEVT_PAINT, boost::bind(&GLVideoView::paint, this));
@@ -105,7 +106,7 @@ GLVideoView::~GLVideoView ()
}
static void
- check_gl_error (char const * last)
+check_gl_error (char const * last)
{
GLenum const e = glGetError ();
if (e != GL_NO_ERROR) {
@@ -278,25 +279,29 @@ try
}
while (true) {
- if (!_viewer->film() || !_viewer->playing()) {
+ if ((!_viewer->film() || !_viewer->playing()) && !_one_shot) {
dcpomatic_sleep_milliseconds (40);
continue;
}
+ _one_shot = false;
+
dcpomatic::DCPTime const next = _viewer->position() + _viewer->one_video_frame();
if (next >= _viewer->film()->length()) {
_viewer->stop ();
_viewer->Finished ();
- return;
+ continue;
}
get_next_frame (false);
set_image (_player_video.first->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true));
draw ();
- _viewer->_video_position = _player_video.second;
- std::cout << "sleep " << _viewer->time_until_next_frame() << "\n";
+ while (_viewer->time_until_next_frame() < 5) {
+ get_next_frame (true);
+ }
+
dcpomatic_sleep_milliseconds (_viewer->time_until_next_frame());
}
@@ -318,3 +323,11 @@ GLVideoView::context () const
boost::mutex::scoped_lock lm (_context_mutex);
return _context;
}
+
+bool
+GLVideoView::display_next_frame (bool non_blocking)
+{
+ bool const g = get_next_frame (non_blocking);
+ _one_shot = true;
+ return g;
+}
diff --git a/src/wx/gl_video_view.h b/src/wx/gl_video_view.h
index e32a1ede9..4ad4b1283 100644
--- a/src/wx/gl_video_view.h
+++ b/src/wx/gl_video_view.h
@@ -40,6 +40,8 @@ public:
void update ();
void start ();
+ bool display_next_frame (bool);
+
bool vsync_enabled () const {
return _vsync_enabled;
}
@@ -59,4 +61,5 @@ private:
boost::optional<dcp::Size> _size;
bool _vsync_enabled;
boost::thread* _thread;
+ bool _one_shot;
};
diff --git a/src/wx/simple_video_view.cc b/src/wx/simple_video_view.cc
index 619a35cce..e66ed815e 100644
--- a/src/wx/simple_video_view.cc
+++ b/src/wx/simple_video_view.cc
@@ -149,7 +149,7 @@ SimpleVideoView::timer ()
return;
}
- get (false);
+ display_next_frame (false);
DCPTime const next = _viewer->position() + _viewer->one_video_frame();
if (next >= _viewer->film()->length()) {
@@ -173,21 +173,21 @@ SimpleVideoView::start ()
}
/** Try to get a frame from the butler and display it.
- * @param lazy true to return false quickly if no video is available quickly (i.e. we are waiting for the butler).
+ * @param non_blocking true to return false quickly if no video is available quickly (i.e. we are waiting for the butler).
* false to ask the butler to block until it has video (unless it is suspended).
* @return true on success, false if we did nothing because it would have taken too long.
*/
bool
-SimpleVideoView::get (bool lazy)
+SimpleVideoView::display_next_frame (bool non_blocking)
{
- bool r = get_next_frame (lazy);
+ bool r = get_next_frame (non_blocking);
if (!r) {
- if (lazy) {
+ if (non_blocking) {
/* No video available; return saying we failed */
return false;
} else {
/* Player was suspended; come back later */
- signal_manager->when_idle (boost::bind(&SimpleVideoView::get, this, false));
+ signal_manager->when_idle (boost::bind(&SimpleVideoView::display_next_frame, this, false));
return false;
}
}
@@ -210,7 +210,6 @@ SimpleVideoView::display_player_video ()
/* Too late; just drop this frame before we try to get its image (which will be the time-consuming
part if this frame is J2K).
*/
- _viewer->_video_position = _player_video.second;
++_viewer->_dropped;
return;
}
@@ -243,7 +242,6 @@ SimpleVideoView::display_player_video ()
_viewer->ImageChanged (_player_video.first);
_viewer->_state_timer.unset ();
- _viewer->_video_position = _player_video.second;
_viewer->_inter_position = _player_video.first->inter_position ();
_viewer->_inter_size = _player_video.first->inter_size ();
diff --git a/src/wx/simple_video_view.h b/src/wx/simple_video_view.h
index 1d5242a1a..e8bb932e4 100644
--- a/src/wx/simple_video_view.h
+++ b/src/wx/simple_video_view.h
@@ -37,14 +37,12 @@ public:
}
void update ();
-
void start ();
+ bool display_next_frame (bool non_blocking);
private:
void paint ();
void timer ();
- /* XXX_b: rename this (there's already a get() in the parent) */
- bool get (bool lazy);
void display_player_video ();
wxPanel* _panel;
diff --git a/src/wx/video_view.h b/src/wx/video_view.h
index 827d1bf73..d6e76ada7 100644
--- a/src/wx/video_view.h
+++ b/src/wx/video_view.h
@@ -53,13 +53,15 @@ public:
boost::signals2::signal<void()> Sized;
- /* XXX_b: to remove */
- virtual bool get (bool) {
- return true;
- }
+ virtual bool display_next_frame (bool) = 0;
+
/* XXX_b: to remove */
virtual void display_player_video () {}
+ dcpomatic::DCPTime position () const {
+ return _player_video.second;
+ }
+
protected:
/* XXX_b: to remove */
friend class FilmViewer;