From 70b72b53eab0f247eb4dc605a2d669d4adb4e469 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 3 Oct 2021 20:53:44 +0200 Subject: [PATCH] Differentiate requested and actual crop. This is so we limit cropping to what is possible considering chroma subsampling. --- src/lib/pixel_quanta.cc | 14 ++++++++++++++ src/lib/pixel_quanta.h | 3 +++ src/lib/player.cc | 2 +- src/lib/player_video.cc | 2 +- src/lib/video_content.cc | 34 +++++++++++++++++++++++++--------- src/lib/video_content.h | 12 +++++++----- src/tools/dcpomatic_cli.cc | 8 ++++---- src/wx/video_panel.cc | 17 ++++++++--------- 8 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/lib/pixel_quanta.cc b/src/lib/pixel_quanta.cc index 12eea5031..09e684064 100644 --- a/src/lib/pixel_quanta.cc +++ b/src/lib/pixel_quanta.cc @@ -39,6 +39,20 @@ PixelQuanta::as_xml (xmlpp::Element* node) const } +int +PixelQuanta::round_x (int x_) const +{ + return x_ - (x_ % x); +} + + +int +PixelQuanta::round_y (int y_) const +{ + return y_ - (y_ % y); +} + + PixelQuanta max (PixelQuanta const& a, PixelQuanta const& b) { diff --git a/src/lib/pixel_quanta.h b/src/lib/pixel_quanta.h index e4a03c9d2..c37ba189b 100644 --- a/src/lib/pixel_quanta.h +++ b/src/lib/pixel_quanta.h @@ -52,6 +52,9 @@ public: void as_xml (xmlpp::Element* node) const; + int round_x (int x_) const; + int round_y (int y_) const; + int x; int y; }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 7951926e6..285126ced 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -922,7 +922,7 @@ Player::video (weak_ptr wp, ContentVideo video) _last_video[wp] = std::make_shared( video.image, - piece->content->video->crop (), + piece->content->video->actual_crop(), piece->content->video->fade (_film, video.frame), scale_for_display(piece->content->video->scaled_size(_film->frame_size()), _video_container_size, _film->frame_size()), _video_container_size, diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc index 7c36af31b..c9bc2dcde 100644 --- a/src/lib/player_video.cc +++ b/src/lib/player_video.cc @@ -343,7 +343,7 @@ PlayerVideo::reset_metadata (shared_ptr film, dcp::Size player_video return false; } - _crop = content->video->crop(); + _crop = content->video->actual_crop(); _fade = content->video->fade(film, _video_frame.get()); _inter_size = scale_for_display(content->video->scaled_size(film->frame_size()), player_video_container_size, film->frame_size()); _out_size = player_video_container_size; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index bffe2e322..0ef102116 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -218,7 +218,7 @@ VideoContent::VideoContent (Content* parent, vector > c) throw JoinError (_("Content to be joined must have the same video frame type.")); } - if (c[i]->video->crop() != ref->crop()) { + if (c[i]->video->requested_crop() != ref->requested_crop()) { throw JoinError (_("Content to be joined must have the same crop.")); } @@ -254,7 +254,7 @@ VideoContent::VideoContent (Content* parent, vector > c) _use = ref->use (); _size = ref->size (); _frame_type = ref->frame_type (); - _crop = ref->crop (); + _crop = ref->requested_crop (); _custom_ratio = ref->custom_ratio (); _colour_conversion = ref->colour_conversion (); _fade_in = ref->fade_in (); @@ -334,13 +334,14 @@ string VideoContent::identifier () const { char buffer[256]; + auto const crop = actual_crop(); snprintf ( buffer, sizeof(buffer), "%d_%d_%d_%d_%d_%f_%d_%d%" PRId64 "_%" PRId64 "_%d", (_use ? 1 : 0), - crop().left, - crop().right, - crop().top, - crop().bottom, + crop.left, + crop.right, + crop.top, + crop.bottom, _custom_ratio.get_value_or(0), _custom_size ? _custom_size->width : 0, _custom_size ? _custom_size->height : 0, @@ -399,7 +400,7 @@ VideoContent::size_after_3d_split () const dcp::Size VideoContent::size_after_crop () const { - return crop().apply (size_after_3d_split ()); + return actual_crop().apply(size_after_3d_split()); } @@ -452,8 +453,10 @@ VideoContent::processing_description (shared_ptr film) d += buffer; } - if ((crop().left || crop().right || crop().top || crop().bottom) && size() != dcp::Size (0, 0)) { - dcp::Size cropped = size_after_crop (); + auto const crop = actual_crop(); + + if ((crop.left || crop.right || crop.top || crop.bottom) && size() != dcp::Size(0, 0)) { + auto const cropped = size_after_crop (); d += String::compose ( _("\nCropped to %1x%2"), cropped.width, cropped.height @@ -668,3 +671,16 @@ VideoContent::set_custom_size (optional size) { maybe_set (_custom_size, size, VideoContentProperty::CUSTOM_SIZE); } + + +Crop +VideoContent::actual_crop () const +{ + return Crop( + _pixel_quanta.round_x(_crop.left), + _pixel_quanta.round_x(_crop.right), + _pixel_quanta.round_y(_crop.top), + _pixel_quanta.round_y(_crop.bottom) + ); +} + diff --git a/src/lib/video_content.h b/src/lib/video_content.h index de151e145..ce645bb41 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -113,27 +113,29 @@ public: return _frame_type; } - Crop crop () const { + Crop actual_crop () const; + + Crop requested_crop () const { boost::mutex::scoped_lock lm (_mutex); return _crop; } - int left_crop () const { + int requested_left_crop () const { boost::mutex::scoped_lock lm (_mutex); return _crop.left; } - int right_crop () const { + int requested_right_crop () const { boost::mutex::scoped_lock lm (_mutex); return _crop.right; } - int top_crop () const { + int requested_top_crop () const { boost::mutex::scoped_lock lm (_mutex); return _crop.top; } - int bottom_crop () const { + int requested_bottom_crop () const { boost::mutex::scoped_lock lm (_mutex); return _crop.bottom; } diff --git a/src/tools/dcpomatic_cli.cc b/src/tools/dcpomatic_cli.cc index 59d85d4c4..75f57fa89 100644 --- a/src/tools/dcpomatic_cli.cc +++ b/src/tools/dcpomatic_cli.cc @@ -92,10 +92,10 @@ print_dump (shared_ptr film) if (c->video) { cout << "\t" << c->video->size().width << "x" << c->video->size().height << "\n" << "\t" << c->active_video_frame_rate(film) << "fps\n" - << "\tcrop left " << c->video->left_crop() - << " right " << c->video->right_crop() - << " top " << c->video->top_crop() - << " bottom " << c->video->bottom_crop() << "\n"; + << "\tcrop left " << c->video->requested_left_crop() + << " right " << c->video->requested_right_crop() + << " top " << c->video->requested_top_crop() + << " bottom " << c->video->requested_bottom_crop() << "\n"; if (c->video->custom_ratio()) { cout << "\tscale to custom ratio " << *c->video->custom_ratio() << ":1\n"; } diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index 33961ea1d..52c3b9229 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -118,7 +118,7 @@ VideoPanel::create () new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(crop_width, -1)), VideoContentProperty::CROP, &Content::video, - boost::mem_fn (&VideoContent::left_crop), + boost::mem_fn (&VideoContent::requested_left_crop), boost::mem_fn (&VideoContent::set_left_crop), boost::bind (&VideoPanel::left_crop_changed, this) ); @@ -132,7 +132,7 @@ VideoPanel::create () new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(crop_width, -1)), VideoContentProperty::CROP, &Content::video, - boost::mem_fn (&VideoContent::right_crop), + boost::mem_fn (&VideoContent::requested_right_crop), boost::mem_fn (&VideoContent::set_right_crop), boost::bind (&VideoPanel::right_crop_changed, this) ); @@ -143,7 +143,7 @@ VideoPanel::create () new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(crop_width, -1)), VideoContentProperty::CROP, &Content::video, - boost::mem_fn (&VideoContent::top_crop), + boost::mem_fn (&VideoContent::requested_top_crop), boost::mem_fn (&VideoContent::set_top_crop), boost::bind (&VideoPanel::top_crop_changed, this) ); @@ -157,7 +157,7 @@ VideoPanel::create () new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(crop_width, -1)), VideoContentProperty::CROP, &Content::video, - boost::mem_fn (&VideoContent::bottom_crop), + boost::mem_fn (&VideoContent::requested_bottom_crop), boost::mem_fn (&VideoContent::set_bottom_crop), boost::bind (&VideoPanel::bottom_crop_changed, this) ); @@ -759,7 +759,7 @@ VideoPanel::left_crop_changed () _left_changed_last = true; if (_left_right_link->GetValue()) { for (auto i: _parent->selected_video()) { - i->video->set_right_crop (i->video->left_crop()); + i->video->set_right_crop (i->video->requested_left_crop()); } } } @@ -771,7 +771,7 @@ VideoPanel::right_crop_changed () _left_changed_last = false; if (_left_right_link->GetValue()) { for (auto i: _parent->selected_video()) { - i->video->set_left_crop (i->video->right_crop()); + i->video->set_left_crop (i->video->requested_right_crop()); } } } @@ -783,7 +783,7 @@ VideoPanel::top_crop_changed () _top_changed_last = true; if (_top_bottom_link->GetValue()) { for (auto i: _parent->selected_video()) { - i->video->set_bottom_crop (i->video->top_crop()); + i->video->set_bottom_crop (i->video->requested_top_crop()); } } } @@ -795,10 +795,9 @@ VideoPanel::bottom_crop_changed () _top_changed_last = false; if (_top_bottom_link->GetValue()) { for (auto i: _parent->selected_video()) { - i->video->set_top_crop (i->video->bottom_crop()); + i->video->set_top_crop (i->video->requested_bottom_crop()); } } } - -- 2.30.2