X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Fvideo_waveform_plot.cc;h=8e3284682485833dc7395c65b75e1c1edeb3be14;hb=865316f0129c85cdd0248b87502fe97dec94b3f0;hp=339689a2ebdbdaeea28ef45ab4482ec7520c93b3;hpb=54ef7357a87885ec329a25e758fb6b132816ec67;p=dcpomatic.git diff --git a/src/wx/video_waveform_plot.cc b/src/wx/video_waveform_plot.cc index 339689a2e..8e3284682 100644 --- a/src/wx/video_waveform_plot.cc +++ b/src/wx/video_waveform_plot.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2018 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,53 +18,63 @@ */ + +#include "film_viewer.h" #include "video_waveform_plot.h" -#include "control_film_viewer.h" #include "wx_util.h" -#include "lib/image.h" -#include "lib/film.h" #include "lib/dcp_video.h" +#include "lib/film.h" +#include "lib/image.h" +#include "lib/player_video.h" #include #include -#include +#include +LIBDCP_DISABLE_WARNINGS #include -#include -#include +#include +LIBDCP_ENABLE_WARNINGS +#include -using std::cout; -using std::min; + +using std::make_shared; using std::max; +using std::min; +using std::shared_ptr; using std::string; -using boost::weak_ptr; -using boost::shared_ptr; +using std::weak_ptr; +#if BOOST_VERSION >= 106100 +using namespace boost::placeholders; +#endif 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, weak_ptr film, ControlFilmViewer* 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) - , _contrast (0) { #ifndef __WXOSX__ SetDoubleBuffered (true); #endif - _viewer_connection = viewer->ImageChanged.connect (boost::bind (&VideoWaveformPlot::set_image, this, _1)); + auto 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)); + 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)); } + void VideoWaveformPlot::paint () { @@ -79,7 +89,7 @@ VideoWaveformPlot::paint () return; } - wxGraphicsContext* gc = wxGraphicsContext::Create (dc); + auto gc = wxGraphicsContext::Create (dc); if (!gc) { return; } @@ -110,7 +120,7 @@ VideoWaveformPlot::paint () } for (int i = 0; i < label_gaps + 1; ++i) { - wxGraphicsPath p = gc->CreatePath (); + auto p = gc->CreatePath (); int const y = _vertical_margin + height - (i * height / label_gaps) - 1; p.MoveToPoint (label_width + 8, y); p.AddLineToPoint (_x_axis_width - 4, y); @@ -124,7 +134,7 @@ VideoWaveformPlot::paint () } else if (n < 1000) { x += extra[2]; } - gc->DrawText (std_to_wx (locale_convert (n)), x, y - (label_height / 2)); + gc->DrawText (std_to_wx(locale_convert(n)), x, y - (label_height / 2)); } wxImage waveform (_waveform->size().width, height, _waveform->data()[0], true); @@ -134,6 +144,7 @@ VideoWaveformPlot::paint () delete gc; } + void VideoWaveformPlot::create_waveform () { @@ -143,9 +154,9 @@ VideoWaveformPlot::create_waveform () return; } - dcp::Size const image_size = _image->size(); + auto const image_size = _image->size(); int const waveform_height = GetSize().GetHeight() - _vertical_margin * 2; - _waveform.reset (new Image (AV_PIX_FMT_RGB24, dcp::Size (image_size.width, waveform_height), true)); + _waveform = make_shared(AV_PIX_FMT_RGB24, dcp::Size (image_size.width, waveform_height), Image::Alignment::PADDED); for (int x = 0; x < image_size.width; ++x) { @@ -172,41 +183,41 @@ VideoWaveformPlot::create_waveform () _waveform = _waveform->scale ( dcp::Size (GetSize().GetWidth() - _x_axis_width, waveform_height), - dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, false, false + dcp::YUVToRGB::REC709, AV_PIX_FMT_RGB24, Image::Alignment::COMPACT, false ); } -static void -note () -{ - -} void -VideoWaveformPlot::set_image (weak_ptr image) +VideoWaveformPlot::set_image (shared_ptr image) { if (!_enabled) { return; } - shared_ptr pv = image.lock (); - _image = DCPVideo::convert_to_xyz (pv, boost::bind (¬e)); + /* 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 (image->shallow_copy(), [](dcp::NoteType, string) {}); _dirty = true; Refresh (); } + void VideoWaveformPlot::sized (wxSizeEvent &) { _dirty = true; } + void VideoWaveformPlot::set_enabled (bool e) { _enabled = e; } + void VideoWaveformPlot::set_component (int c) { @@ -215,6 +226,7 @@ VideoWaveformPlot::set_component (int c) Refresh (); } + /** Set `contrast', i.e. a fudge multiplication factor to make low-level signals easier to see, * between 0 and 256. */ @@ -226,6 +238,7 @@ VideoWaveformPlot::set_contrast (int b) Refresh (); } + void VideoWaveformPlot::mouse_moved (wxMouseEvent& ev) { @@ -238,18 +251,18 @@ VideoWaveformPlot::mouse_moved (wxMouseEvent& ev) _dirty = false; } - shared_ptr film = _film.lock (); + auto film = _film.lock (); if (!film) { return; } - dcp::Size const full = film->frame_size (); + auto const full = film->frame_size (); - double const xs = static_cast (full.width) / _waveform->size().width; + auto 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; + auto 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)));