summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-07-22 16:32:37 +0100
committerCarl Hetherington <cth@carlh.net>2014-07-22 16:32:37 +0100
commit0f60e0f52c986f18764822de78b82b4163909f0c (patch)
tree9fd45bd68de68ee47551efcdcf955344ad1fc87a /src
parent7523c7f0ab64f075ca535071b780098f6c05fce6 (diff)
Option to draw a border around the content's image (#391).
Diffstat (limited to 'src')
-rw-r--r--src/lib/film.cc2
-rw-r--r--src/lib/player.cc2
-rw-r--r--src/lib/player_video.cc10
-rw-r--r--src/lib/player_video.h8
-rw-r--r--src/lib/util.cc17
-rw-r--r--src/lib/util.h3
-rw-r--r--src/lib/video_content.cc10
-rw-r--r--src/lib/video_content.h2
-rw-r--r--src/wx/film_viewer.cc33
-rw-r--r--src/wx/film_viewer.h4
-rw-r--r--src/wx/video_panel.cc2
11 files changed, 71 insertions, 22 deletions
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 0de6f2ded..0891838ff 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -1071,7 +1071,7 @@ Film::full_frame () const
dcp::Size
Film::frame_size () const
{
- return fit_ratio_within (container()->ratio(), full_frame ());
+ return fit_ratio_within (container()->ratio(), full_frame (), 1);
}
dcp::EncryptedKDM
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 06f9e1365..e46d539f8 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -342,7 +342,7 @@ Player::get_video (DCPTime time, bool accurate)
return pvf;
}
- dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size ());
+ dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size (), _approximate_size ? 4 : 1);
if (_approximate_size) {
image_size.width &= ~3;
image_size.height &= ~3;
diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc
index a44264ced..8fd966e5f 100644
--- a/src/lib/player_video.cc
+++ b/src/lib/player_video.cc
@@ -111,8 +111,6 @@ PlayerVideo::image (bool burn_subtitle) const
shared_ptr<Image> out = im->crop_scale_window (total_crop, _inter_size, _out_size, _scaler, PIX_FMT_RGB24, true);
- Position<int> const container_offset ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.width) / 2);
-
if (burn_subtitle && _subtitle.image) {
out->alpha_blend (_subtitle.image, _subtitle.position);
}
@@ -171,3 +169,11 @@ PlayerVideo::j2k () const
assert (j2k);
return j2k->j2k ();
}
+
+Position<int>
+PlayerVideo::inter_position () const
+{
+ return Position<int> ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.height) / 2);
+}
+
+
diff --git a/src/lib/player_video.h b/src/lib/player_video.h
index 4fe8712d4..74e05d1e9 100644
--- a/src/lib/player_video.h
+++ b/src/lib/player_video.h
@@ -62,6 +62,14 @@ public:
return _colour_conversion;
}
+ /** @return Position of the content within the overall image once it has been scaled up */
+ Position<int> inter_position () const;
+
+ /** @return Size of the content within the overall image once it has been scaled up */
+ dcp::Size inter_size () const {
+ return _inter_size;
+ }
+
private:
boost::shared_ptr<const ImageProxy> _in;
DCPTime _time;
diff --git a/src/lib/util.cc b/src/lib/util.cc
index cc8d59f21..60953b544 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -636,6 +636,17 @@ stride_round_up (int c, int const * stride, int t)
return a - (a % t);
}
+/** @param n A number.
+ * @param r Rounding `boundary' (must be a power of 2)
+ * @return n rounded to the nearest r
+ */
+int
+round_to (float n, int r)
+{
+ assert (r == 1 || r == 2 || r == 4);
+ return int (n + float(r) / 2) &~ (r - 1);
+}
+
/** Read a sequence of key / value pairs from a text stream;
* the keys are the first words on the line, and the values are
* the remainder of the line following the key. Lines beginning
@@ -837,13 +848,13 @@ split_get_request (string url)
}
dcp::Size
-fit_ratio_within (float ratio, dcp::Size full_frame)
+fit_ratio_within (float ratio, dcp::Size full_frame, int round)
{
if (ratio < full_frame.ratio ()) {
- return dcp::Size (rint (full_frame.height * ratio), full_frame.height);
+ return dcp::Size (round_to (full_frame.height * ratio, round), full_frame.height);
}
- return dcp::Size (full_frame.width, rint (full_frame.width / ratio));
+ return dcp::Size (full_frame.width, round_to (full_frame.width / ratio, round));
}
void *
diff --git a/src/lib/util.h b/src/lib/util.h
index b7dc978e3..1bbdfb2cf 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -66,11 +66,12 @@ extern bool valid_image_file (boost::filesystem::path);
extern boost::filesystem::path mo_path ();
#endif
extern std::string tidy_for_filename (std::string);
-extern dcp::Size fit_ratio_within (float ratio, dcp::Size);
+extern dcp::Size fit_ratio_within (float ratio, dcp::Size, int);
extern std::string entities_to_text (std::string e);
extern std::map<std::string, std::string> split_get_request (std::string url);
extern int dcp_audio_frame_rate (int);
extern int stride_round_up (int, int const *, int);
+extern int round_to (float n, int r);
extern std::multimap<std::string, std::string> read_key_value (std::istream& s);
extern int get_required_int (std::multimap<std::string, std::string> const & kv, std::string k);
extern float get_required_float (std::multimap<std::string, std::string> const & kv, std::string k);
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index 0d9a8fc45..0a3e378ee 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -508,25 +508,25 @@ VideoContentScale::name () const
* @param film_container The size of the film's image.
*/
dcp::Size
-VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container) const
+VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container, int round) const
{
if (_ratio) {
- return fit_ratio_within (_ratio->ratio (), display_container);
+ return fit_ratio_within (_ratio->ratio (), display_container, round);
}
dcp::Size const ac = c->video_size_after_crop ();
/* Force scale if the film_container is smaller than the content's image */
if (_scale || film_container.width < ac.width || film_container.height < ac.height) {
- return fit_ratio_within (ac.ratio (), display_container);
+ return fit_ratio_within (ac.ratio (), display_container, 1);
}
/* Scale the image so that it will be in the right place in film_container, even if display_container is a
different size.
*/
return dcp::Size (
- c->video_size().width * float(display_container.width) / film_container.width,
- c->video_size().height * float(display_container.height) / film_container.height
+ round_to (c->video_size().width * float(display_container.width) / film_container.width, round),
+ round_to (c->video_size().height * float(display_container.height) / film_container.height, round)
);
}
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 7d9cb4f8f..dc7de8d54 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -45,7 +45,7 @@ public:
VideoContentScale (bool);
VideoContentScale (cxml::NodePtr);
- dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size) const;
+ dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size, int round) const;
std::string id () const;
std::string name () const;
void as_xml (xmlpp::Node *) const;
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 80b12bf76..96e20a281 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -58,6 +58,7 @@ using dcp::Size;
FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
: wxPanel (p)
, _panel (new wxPanel (this))
+ , _outline_content (new wxCheckBox (this, wxID_ANY, _("Outline content")))
, _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096))
, _back_button (new wxButton (this, wxID_ANY, wxT("<")))
, _forward_button (new wxButton (this, wxID_ANY, wxT(">")))
@@ -77,6 +78,8 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
_v_sizer->Add (_panel, 1, wxEXPAND);
+ _v_sizer->Add (_outline_content, 0, wxALL, DCPOMATIC_SIZER_GAP);
+
wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL);
wxBoxSizer* time_sizer = new wxBoxSizer (wxVERTICAL);
@@ -97,6 +100,7 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
_panel->Bind (wxEVT_PAINT, boost::bind (&FilmViewer::paint_panel, this));
_panel->Bind (wxEVT_SIZE, boost::bind (&FilmViewer::panel_sized, this, _1));
+ _outline_content->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmViewer::refresh_panel, this));
_slider->Bind (wxEVT_SCROLL_THUMBTRACK, boost::bind (&FilmViewer::slider_moved, this));
_slider->Bind (wxEVT_SCROLL_PAGEUP, boost::bind (&FilmViewer::slider_moved, this));
_slider->Bind (wxEVT_SCROLL_PAGEDOWN, boost::bind (&FilmViewer::slider_moved, this));
@@ -146,6 +150,13 @@ FilmViewer::set_film (shared_ptr<Film> f)
}
void
+FilmViewer::refresh_panel ()
+{
+ _panel->Refresh ();
+ _panel->Update ();
+}
+
+void
FilmViewer::get (DCPTime p, bool accurate)
{
if (!_player) {
@@ -158,6 +169,8 @@ FilmViewer::get (DCPTime p, bool accurate)
_frame = pvf.front()->image (true);
_frame = _frame->scale (_frame->size(), Scaler::from_id ("fastbilinear"), PIX_FMT_RGB24, false);
_position = pvf.front()->time ();
+ _inter_position = pvf.front()->inter_position ();
+ _inter_size = pvf.front()->inter_size ();
} catch (dcp::DCPReadError& e) {
/* This can happen on the following sequence of events:
* - load encrypted DCP
@@ -178,8 +191,7 @@ FilmViewer::get (DCPTime p, bool accurate)
}
set_position_text ();
- _panel->Refresh ();
- _panel->Update ();
+ refresh_panel ();
_last_get_accurate = accurate;
}
@@ -228,9 +240,15 @@ FilmViewer::paint_panel ()
dc.SetPen (p);
dc.SetBrush (b);
dc.DrawRectangle (0, _out_size.height, _panel_size.width, _panel_size.height - _out_size.height);
- }
-}
+ }
+ if (_outline_content->GetValue ()) {
+ wxPen p (wxColour (255, 0, 0), 2);
+ dc.SetPen (p);
+ dc.SetBrush (*wxTRANSPARENT_BRUSH);
+ dc.DrawRectangle (_inter_position.x, _inter_position.y, _inter_size.width, _inter_size.height);
+ }
+}
void
FilmViewer::slider_moved ()
@@ -252,6 +270,7 @@ FilmViewer::panel_sized (wxSizeEvent& ev)
{
_panel_size.width = ev.GetSize().GetWidth();
_panel_size.height = ev.GetSize().GetHeight();
+
calculate_sizes ();
get (_position, _last_get_accurate);
}
@@ -271,18 +290,18 @@ FilmViewer::calculate_sizes ()
if (panel_ratio < film_ratio) {
/* panel is less widscreen than the film; clamp width */
_out_size.width = _panel_size.width;
- _out_size.height = _out_size.width / film_ratio;
+ _out_size.height = rint (_out_size.width / film_ratio);
} else {
/* panel is more widescreen than the film; clamp height */
_out_size.height = _panel_size.height;
- _out_size.width = _out_size.height * film_ratio;
+ _out_size.width = rint (_out_size.height * film_ratio);
}
/* Catch silly values */
_out_size.width = max (64, _out_size.width);
_out_size.height = max (64, _out_size.height);
- /* The player will round its image down to the nearest 4 pixels
+ /* The player will round its image size down to the next lowest 4 pixels
to speed up its scale, so do similar here to avoid black borders
around things. This is a bit of a hack.
*/
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index 189b379bf..930937596 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -54,12 +54,14 @@ private:
void player_changed (bool);
void set_position_text ();
void get (DCPTime, bool);
+ void refresh_panel ();
boost::shared_ptr<Film> _film;
boost::shared_ptr<Player> _player;
wxSizer* _v_sizer;
wxPanel* _panel;
+ wxCheckBox* _outline_content;
wxSlider* _slider;
wxButton* _back_button;
wxButton* _forward_button;
@@ -70,6 +72,8 @@ private:
boost::shared_ptr<const Image> _frame;
DCPTime _position;
+ Position<int> _inter_position;
+ dcp::Size _inter_size;
/** Size of our output (including padding if we have any) */
dcp::Size _out_size;
diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc
index d8fdf2d02..facd0f3d4 100644
--- a/src/wx/video_panel.cc
+++ b/src/wx/video_panel.cc
@@ -309,7 +309,7 @@ VideoPanel::setup_description ()
}
dcp::Size const container_size = _parent->film()->frame_size ();
- dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size);
+ dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size, 1);
if (scaled != vcs->video_size_after_crop ()) {
d << wxString::Format (