Speculative 4K support.
authorCarl Hetherington <cth@carlh.net>
Thu, 18 Jul 2013 11:40:38 +0000 (12:40 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 18 Jul 2013 11:40:38 +0000 (12:40 +0100)
src/lib/film.cc
src/lib/film.h
src/lib/types.cc
src/lib/types.h
src/wx/film_editor.cc
src/wx/film_editor.h

index e76030efdd17234fbc1273ed455a47e67681d127..3ee8a416ff30d4dfb03ca2199f4a497a7c67d3ca 100644 (file)
@@ -88,6 +88,7 @@ Film::Film (string d)
        , _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 ())
@@ -131,6 +132,7 @@ Film::video_identifier () const
 
        stringstream s;
        s << container()->id()
+         << "_" << resolution_to_string (_resolution)
          << "_" << _playlist->video_identifier()
          << "_" << _dcp_video_frame_rate
          << "_" << scaler()->id()
@@ -314,6 +316,7 @@ Film::write_metadata () const
                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));
@@ -358,6 +361,7 @@ Film::read_metadata ()
                }
        }
 
+       _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");
@@ -452,7 +456,7 @@ Film::dci_name (bool if_created_now) const
                }
        }
 
-       d << "_51_2K";
+       d << "_51_" << resolution_to_string (_resolution);
 
        if (!dm.studio.empty ()) {
                d << "_" << dm.studio;
@@ -535,6 +539,16 @@ Film::set_container (Ratio const * c)
        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)
 {
@@ -821,5 +835,13 @@ Film::set_sequence_video (bool 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 ();
 }
index f4065757b2f1bc61a2e53f0e4a6b7fc1ce64a2da..bd9dcc88dc068812cd258b407aabc3ad628b60bc 100644 (file)
@@ -47,7 +47,7 @@ class Player;
  *  @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
 {
@@ -129,6 +129,7 @@ public:
                LOOP,
                DCP_CONTENT_TYPE,
                CONTAINER,
+               RESOLUTION,
                SCALER,
                WITH_SUBTITLES,
                J2K_BANDWIDTH,
@@ -165,6 +166,11 @@ public:
                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;
@@ -206,6 +212,7 @@ public:
        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);
@@ -251,6 +258,8 @@ private:
        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 */
index 035c8363db10a1d8ba67c40134811fa9467b4611..bc4f5f8d9d425d0d9305f1015c124ee92590dcb7 100644 (file)
@@ -21,6 +21,7 @@
 
 using std::max;
 using std::min;
+using std::string;
 
 bool operator== (Crop const & a, Crop const & b)
 {
@@ -32,3 +33,35 @@ 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;
+}
index fcf45ffa04ccb17cc7fc144f9eca01e4efe5d615..aeaa82ec6225cfd90b77d46f02ce98a819b37e0d 100644 (file)
@@ -53,4 +53,12 @@ struct Crop
 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
index 90bf79741fdfa98a9196d7994614569a3ce05de8..669be844b90637a8535138317a44f5c1cb3b10bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    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
@@ -139,7 +139,7 @@ FilmEditor::make_dcp_panel ()
        ++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);
@@ -149,11 +149,16 @@ FilmEditor::make_dcp_panel ()
        }
        ++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);
@@ -191,6 +196,9 @@ FilmEditor::make_dcp_panel ()
 
        _dcp_audio_channels->SetRange (0, MAX_AUDIO_CHANNELS);
        _j2k_bandwidth->SetRange (50, 250);
+
+       _dcp_resolution->Append (_("2K"));
+       _dcp_resolution->Append (_("4K"));
 }
 
 void
@@ -230,6 +238,8 @@ FilmEditor::connect_to_widgets ()
        _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));
@@ -578,6 +588,16 @@ FilmEditor::dcp_audio_channels_changed (wxCommandEvent &)
        _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.
@@ -626,6 +646,10 @@ FilmEditor::film_changed (Film::Property p)
                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;
@@ -860,6 +884,7 @@ FilmEditor::set_film (shared_ptr<Film> f)
        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);
index f2c6745dedc6733e4cb692b2009055ce74a79cfc..c965a7aff546d4766c0e69609e5980c45716a093 100644 (file)
@@ -97,6 +97,7 @@ private:
        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);
@@ -173,6 +174,7 @@ private:
        AudioMappingView* _audio_mapping;
        Timecode* _start;
        Timecode* _length;
+       wxChoice* _dcp_resolution;
 
        std::vector<Ratio const *> _ratios;