, _use_dci_name (true)
, _dcp_content_type (Config::instance()->default_dcp_content_type ())
, _container (Config::instance()->default_container ())
+ , _resolution (RESOLUTION_2K)
, _scaler (Scaler::from_id ("bicubic"))
, _with_subtitles (false)
, _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ())
stringstream s;
s << container()->id()
+ << "_" << resolution_to_string (_resolution)
<< "_" << _playlist->video_identifier()
<< "_" << _dcp_video_frame_rate
<< "_" << scaler()->id()
root->add_child("Container")->add_child_text (_container->id ());
}
+ root->add_child("Resolution")->add_child_text (resolution_to_string (_resolution));
root->add_child("Scaler")->add_child_text (_scaler->id ());
root->add_child("WithSubtitles")->add_child_text (_with_subtitles ? "1" : "0");
root->add_child("J2KBandwidth")->add_child_text (lexical_cast<string> (_j2k_bandwidth));
}
}
+ _resolution = string_to_resolution (f.string_child ("Resolution"));
_scaler = Scaler::from_id (f.string_child ("Scaler"));
_with_subtitles = f.bool_child ("WithSubtitles");
_j2k_bandwidth = f.number_child<int> ("J2KBandwidth");
}
}
- d << "_51_2K";
+ d << "_51_" << resolution_to_string (_resolution);
if (!dm.studio.empty ()) {
d << "_" << dm.studio;
signal_changed (CONTAINER);
}
+void
+Film::set_resolution (Resolution r)
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _resolution = r;
+ }
+ signal_changed (RESOLUTION);
+}
+
void
Film::set_scaler (Scaler const * s)
{
libdcp::Size
Film::full_frame () const
{
- return libdcp::Size (2048, 1080);
+ switch (_resolution) {
+ case RESOLUTION_2K:
+ return libdcp::Size (2048, 1080);
+ case RESOLUTION_4K:
+ return libdcp::Size (4096, 2160);
+ }
+
+ assert (false);
+ return libdcp::Size ();
}
* @brief A representation of some audio and video content, and details of
* how they should be presented in a DCP.
*
- * The content of a Film is held in a Playlist (created and managed by the Film)
+ * The content of a Film is held in a Playlist (created and managed by the Film).
*/
class Film : public boost::enable_shared_from_this<Film>, public boost::noncopyable
{
LOOP,
DCP_CONTENT_TYPE,
CONTAINER,
+ RESOLUTION,
SCALER,
WITH_SUBTITLES,
J2K_BANDWIDTH,
return _container;
}
+ Resolution resolution () const {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _resolution;
+ }
+
Scaler const * scaler () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _scaler;
void remove_content (boost::shared_ptr<Content>);
void set_dcp_content_type (DCPContentType const *);
void set_container (Ratio const *);
+ void set_resolution (Resolution);
void set_scaler (Scaler const *);
void set_with_subtitles (bool);
void set_j2k_bandwidth (int);
DCPContentType const * _dcp_content_type;
/** The container to put this Film in (flat, scope, etc.) */
Ratio const * _container;
+ /** DCP resolution (2K or 4K) */
+ Resolution _resolution;
/** Scaler algorithm to use */
Scaler const * _scaler;
/** True if subtitles should be shown for this film */
using std::max;
using std::min;
+using std::string;
bool operator== (Crop const & a, Crop const & b)
{
return !(a == b);
}
+/** @param r Resolution.
+ * @return Untranslated string representation.
+ */
+string
+resolution_to_string (Resolution r)
+{
+ switch (r) {
+ case RESOLUTION_2K:
+ return "2K";
+ case RESOLUTION_4K:
+ return "4K";
+ }
+
+ assert (false);
+ return "";
+}
+
+
+Resolution
+string_to_resolution (string s)
+{
+ if (s == "2K") {
+ return RESOLUTION_2K;
+ }
+
+ if (s == "4K") {
+ return RESOLUTION_4K;
+ }
+
+ assert (false);
+ return RESOLUTION_2K;
+}
extern bool operator== (Crop const & a, Crop const & b);
extern bool operator!= (Crop const & a, Crop const & b);
+enum Resolution {
+ RESOLUTION_2K,
+ RESOLUTION_4K
+};
+
+std::string resolution_to_string (Resolution);
+Resolution string_to_resolution (std::string);
+
#endif
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
++r;
{
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Frame Rate"), true, wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Frame Rate"), true, wxGBPosition (r, 0));
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_dcp_frame_rate = new wxChoice (_dcp_panel, wxID_ANY);
s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL);
}
++r;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP audio channels"), true, wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Audio channels"), true, wxGBPosition (r, 0));
_dcp_audio_channels = new wxSpinCtrl (_dcp_panel, wxID_ANY);
grid->Add (_dcp_audio_channels, wxGBPosition (r, 1));
++r;
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Resolution"), true, wxGBPosition (r, 0));
+ _dcp_resolution = new wxChoice (_dcp_panel, wxID_ANY);
+ grid->Add (_dcp_resolution, wxGBPosition (r, 1));
+ ++r;
+
{
add_label_to_grid_bag_sizer (grid, _dcp_panel, _("JPEG2000 bandwidth"), true, wxGBPosition (r, 0));
wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_dcp_audio_channels->SetRange (0, MAX_AUDIO_CHANNELS);
_j2k_bandwidth->SetRange (50, 250);
+
+ _dcp_resolution->Append (_("2K"));
+ _dcp_resolution->Append (_("4K"));
}
void
_audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this);
_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this);
_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this);
+ _dcp_resolution->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_resolution_changed), 0, this);
+
_audio_mapping->Changed.connect (boost::bind (&FilmEditor::audio_mapping_changed, this, _1));
_start->Changed.connect (boost::bind (&FilmEditor::start_changed, this));
_length->Changed.connect (boost::bind (&FilmEditor::length_changed, this));
_film->set_dcp_audio_channels (_dcp_audio_channels->GetValue ());
}
+void
+FilmEditor::dcp_resolution_changed (wxCommandEvent &)
+{
+ if (!_film) {
+ return;
+ }
+
+ _film->set_resolution (_dcp_resolution->GetSelection() == 0 ? RESOLUTION_2K : RESOLUTION_4K);
+}
+
/** Called when the metadata stored in the Film object has changed;
* so that we can update the GUI.
setup_subtitle_control_sensitivity ();
setup_dcp_name ();
break;
+ case Film::RESOLUTION:
+ checked_set (_dcp_resolution, _film->resolution() == RESOLUTION_2K ? 0 : 1);
+ setup_dcp_name ();
+ break;
case Film::J2K_BANDWIDTH:
checked_set (_j2k_bandwidth, double (_film->j2k_bandwidth()) / 1e6);
break;
film_changed (Film::LOOP);
film_changed (Film::DCP_CONTENT_TYPE);
film_changed (Film::CONTAINER);
+ film_changed (Film::RESOLUTION);
film_changed (Film::SCALER);
film_changed (Film::WITH_SUBTITLES);
film_changed (Film::J2K_BANDWIDTH);
void length_changed ();
void ratio_changed (wxCommandEvent &);
void dcp_audio_channels_changed (wxCommandEvent &);
+ void dcp_resolution_changed (wxCommandEvent &);
/* Handle changes to the model */
void film_changed (Film::Property);
AudioMappingView* _audio_mapping;
Timecode* _start;
Timecode* _length;
+ wxChoice* _dcp_resolution;
std::vector<Ratio const *> _ratios;