X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Fvideo_waveform_plot.cc;h=c6fa883fa871c227b321dea92819d126998cd922;hb=981100bbff6883ff024b41d4b62e00b2ab8caec4;hp=e2083caa632b230ef1c33c6e59761dcda2befe9f;hpb=533de5cc51d93a8403816fc0f04ca1d5aa733242;p=dcpomatic.git diff --git a/src/wx/video_waveform_plot.cc b/src/wx/video_waveform_plot.cc index e2083caa6..c6fa883fa 100644 --- a/src/wx/video_waveform_plot.cc +++ b/src/wx/video_waveform_plot.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -22,7 +22,9 @@ #include "film_viewer.h" #include "wx_util.h" #include "lib/image.h" +#include "lib/film.h" #include "lib/dcp_video.h" +#include "lib/player_video.h" #include #include #include @@ -32,16 +34,19 @@ using std::cout; using std::min; +using std::max; using std::string; using boost::weak_ptr; using boost::shared_ptr; using dcp::locale_convert; int const VideoWaveformPlot::_vertical_margin = 8; +int const VideoWaveformPlot::_pixel_values = 4096; int const VideoWaveformPlot::_x_axis_width = 52; -VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, FilmViewer* viewer) +VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, weak_ptr film, weak_ptr viewer) : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) + , _film (film) , _dirty (true) , _enabled (false) , _component (0) @@ -51,10 +56,14 @@ VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, FilmViewer* viewer) SetDoubleBuffered (true); #endif - _viewer_connection = viewer->ImageChanged.connect (boost::bind (&VideoWaveformPlot::set_image, this, _1)); + shared_ptr fv = viewer.lock (); + DCPOMATIC_ASSERT (fv); + + _viewer_connection = fv->ImageChanged.connect (boost::bind (&VideoWaveformPlot::set_image, this, _1)); Bind (wxEVT_PAINT, boost::bind (&VideoWaveformPlot::paint, this)); Bind (wxEVT_SIZE, boost::bind (&VideoWaveformPlot::sized, this, _1)); + Bind (wxEVT_MOTION, boost::bind (&VideoWaveformPlot::mouse_moved, this, _1)); SetMinSize (wxSize (640, 512)); SetBackgroundColour (wxColour (0, 0, 0)); @@ -111,7 +120,7 @@ VideoWaveformPlot::paint () p.AddLineToPoint (_x_axis_width - 4, y); gc->StrokePath (p); int x = 4; - int const n = i * 4096 / label_gaps; + int const n = i * _pixel_values / label_gaps; if (n < 10) { x += extra[0]; } else if (n < 100) { @@ -153,7 +162,7 @@ VideoWaveformPlot::create_waveform () int* ip = _image->data (_component) + x; for (int y = 0; y < image_size.height; ++y) { - strip[*ip * waveform_height / 4096]++; + strip[*ip * waveform_height / _pixel_values]++; ip += image_size.width; } @@ -185,7 +194,11 @@ VideoWaveformPlot::set_image (weak_ptr image) } shared_ptr pv = image.lock (); - _image = DCPVideo::convert_to_xyz (pv, boost::bind (¬e)); + DCPOMATIC_ASSERT (pv); + /* We must copy the PlayerVideo here as we will call ::image() on it, potentially + with a different pixel_format than was used when ::prepare() was called. + */ + _image = DCPVideo::convert_to_xyz (pv->shallow_copy(), boost::bind (¬e)); _dirty = true; Refresh (); } @@ -220,3 +233,34 @@ VideoWaveformPlot::set_contrast (int b) _dirty = true; Refresh (); } + +void +VideoWaveformPlot::mouse_moved (wxMouseEvent& ev) +{ + if (!_image) { + return; + } + + if (_dirty) { + create_waveform (); + _dirty = false; + } + + shared_ptr film = _film.lock (); + if (!film) { + return; + } + + dcp::Size const full = film->frame_size (); + + double const xs = static_cast (full.width) / _waveform->size().width; + int const x1 = max (0, min (full.width - 1, int (floor (ev.GetPosition().x - _x_axis_width - 0.5) * xs))); + int const x2 = max (0, min (full.width - 1, int (floor (ev.GetPosition().x - _x_axis_width + 0.5) * xs))); + + double const ys = static_cast (_pixel_values) / _waveform->size().height; + int const fy = _waveform->size().height - (ev.GetPosition().y - _vertical_margin); + int const y1 = max (0, min (_pixel_values - 1, int (floor (fy - 0.5) * ys))); + int const y2 = max (0, min (_pixel_values - 1, int (floor (fy + 0.5) * ys))); + + MouseMoved (x1, x2, y1, y2); +}