Interop support.
authorCarl Hetherington <cth@carlh.net>
Sun, 25 Aug 2013 16:21:12 +0000 (17:21 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 25 Aug 2013 16:21:12 +0000 (17:21 +0100)
src/lib/film.cc
src/lib/film.h
src/lib/still_image_decoder.cc
src/lib/writer.cc
src/wx/film_editor.cc
src/wx/film_editor.h

index 5dc808c02bbde2da9a8baf70f1125f76d1af18f7..e6bf3bd5e17766e4a50e0e7d63eeac3dd7e576a2 100644 (file)
@@ -97,6 +97,7 @@ Film::Film (boost::filesystem::path dir)
        , _audio_channels (MAX_AUDIO_CHANNELS)
        , _three_d (false)
        , _sequence_video (true)
+       , _interop (false)
        , _dirty (false)
 {
        set_dci_date_today ();
@@ -142,6 +143,12 @@ Film::video_identifier () const
          << "_" << scaler()->id()
          << "_" << j2k_bandwidth();
 
+       if (_interop) {
+               s << "_I";
+       } else {
+               s << "_S";
+       }
+
        if (_three_d) {
                s << "_3D";
        }
@@ -331,6 +338,7 @@ Film::write_metadata () const
        root->add_child("AudioChannels")->add_child_text (lexical_cast<string> (_audio_channels));
        root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0");
        root->add_child("SequenceVideo")->add_child_text (_sequence_video ? "1" : "0");
+       root->add_child("Interop")->add_child_text (_interop ? "1" : "0");
        _playlist->as_xml (root->add_child ("Playlist"));
 
        doc.write_to_file_formatted (file ("metadata.xml"));
@@ -377,6 +385,7 @@ Film::read_metadata ()
        _audio_channels = f.number_child<int> ("AudioChannels");
        _sequence_video = f.bool_child ("SequenceVideo");
        _three_d = f.bool_child ("ThreeD");
+       _interop = f.bool_child ("Interop");
 
        _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"));
 
@@ -614,6 +623,13 @@ Film::set_three_d (bool t)
        signal_changed (THREE_D);
 }
 
+void
+Film::set_interop (bool i)
+{
+       _interop = i;
+       signal_changed (INTEROP);
+}
+
 void
 Film::signal_changed (Property p)
 {
index df26a3ae54fbd0d9f370041e2f70aa0ad1b58d3e..f5b29466afe44574d033ae504d605f43bd6d49ba 100644 (file)
@@ -134,6 +134,7 @@ public:
                /** The setting of _three_d has been changed */
                THREE_D,
                SEQUENCE_VIDEO,
+               INTEROP,
        };
 
 
@@ -195,6 +196,10 @@ public:
        bool sequence_video () const {
                return _sequence_video;
        }
+
+       bool interop () const {
+               return _interop;
+       }
        
 
        /* SET */
@@ -217,6 +222,7 @@ public:
        void set_three_d (bool);
        void set_dci_date_today ();
        void set_sequence_video (bool);
+       void set_interop (bool);
 
        /** Emitted when some property has of the Film has changed */
        mutable boost::signals2::signal<void (Property)> Changed;
@@ -274,6 +280,7 @@ private:
        */
        bool _three_d;
        bool _sequence_video;
+       bool _interop;
 
        /** true if our state has changed since we last saved it */
        mutable bool _dirty;
index 1dd68463947f36c142dd1d6b81edf2d281302071..6e82f9a55730b1e6bee5e0e3f4179e9bac513ea0 100644 (file)
@@ -55,18 +55,20 @@ StillImageDecoder::pass ()
        Magick::Image* magick_image = new Magick::Image (_still_image_content->path().string ());
        _video_size = libdcp::Size (magick_image->columns(), magick_image->rows());
        
-       _image.reset (new Image (PIX_FMT_RGB24, _video_size.get(), false));
+       _image.reset (new Image (PIX_FMT_RGB24, _video_size.get(), true));
 
        using namespace MagickCore;
        
        uint8_t* p = _image->data()[0];
        for (int y = 0; y < _video_size->height; ++y) {
+               uint8_t* q = p;
                for (int x = 0; x < _video_size->width; ++x) {
                        Magick::Color c = magick_image->pixelColor (x, y);
-                       *p++ = c.redQuantum() * 255 / QuantumRange;
-                       *p++ = c.greenQuantum() * 255 / QuantumRange;
-                       *p++ = c.blueQuantum() * 255 / QuantumRange;
+                       *q++ = c.redQuantum() * 255 / QuantumRange;
+                       *q++ = c.greenQuantum() * 255 / QuantumRange;
+                       *q++ = c.blueQuantum() * 255 / QuantumRange;
                }
+               p += _image->stride()[0];
        }
 
        delete magick_image;
index 0d66df3e3cf088190186c26d0d054179600aa61a..2e0ffd8336ddc2583bba40b687d23f17e60576a4 100644 (file)
@@ -95,7 +95,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
 
        }
 
-       _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0);
+       _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0, _film->interop ());
        
        _sound_asset.reset (
                new libdcp::SoundAsset (
@@ -107,7 +107,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
                        )
                );
        
-       _sound_asset_writer = _sound_asset->start_write ();
+       _sound_asset_writer = _sound_asset->start_write (_film->interop ());
 
        _thread = new boost::thread (boost::bind (&Writer::thread, this));
 }
@@ -391,7 +391,7 @@ Writer::finish ()
 
        libdcp::XMLMetadata meta = Config::instance()->dcp_metadata ();
        meta.set_issue_date_now ();
-       dcp.write_xml (meta);
+       dcp.write_xml (_film->interop (), meta);
 
        _film->log()->log (String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk));
 }
index 28c315a969b61d126b89d4cbe49f4f26ffb13951..4be5c541faac385a44ab8fce39a17dca87df14a4 100644 (file)
@@ -172,6 +172,11 @@ FilmEditor::make_dcp_panel ()
        }
        ++r;
 
+       add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Standard"), true, wxGBPosition (r, 0));
+       _standard = new wxChoice (_dcp_panel, wxID_ANY);
+       grid->Add (_standard, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+       ++r;
+
        add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Scaler"), true, wxGBPosition (r, 0));
        _scaler = new wxChoice (_dcp_panel, wxID_ANY);
        grid->Add (_scaler, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
@@ -202,6 +207,9 @@ FilmEditor::make_dcp_panel ()
 
        _resolution->Append (_("2K"));
        _resolution->Append (_("4K"));
+
+       _standard->Append (_("SMPTE"));
+       _standard->Append (_("Interop"));
 }
 
 void
@@ -227,6 +235,7 @@ FilmEditor::connect_to_widgets ()
        _resolution->Bind       (wxEVT_COMMAND_CHOICE_SELECTED,       boost::bind (&FilmEditor::resolution_changed, this));
        _sequence_video->Bind   (wxEVT_COMMAND_CHECKBOX_CLICKED,      boost::bind (&FilmEditor::sequence_video_changed, this));
        _three_d->Bind          (wxEVT_COMMAND_CHECKBOX_CLICKED,      boost::bind (&FilmEditor::three_d_changed, this));
+       _standard->Bind         (wxEVT_COMMAND_CHOICE_SELECTED,       boost::bind (&FilmEditor::standard_changed, this));
 }
 
 void
@@ -331,6 +340,15 @@ FilmEditor::resolution_changed ()
        _film->set_resolution (_resolution->GetSelection() == 0 ? RESOLUTION_2K : RESOLUTION_4K);
 }
 
+void
+FilmEditor::standard_changed ()
+{
+       if (!_film) {
+               return;
+       }
+
+       _film->set_interop (_standard->GetSelection() == 1);
+}
 
 /** Called when the metadata stored in the Film object has changed;
  *  so that we can update the GUI.
@@ -417,6 +435,9 @@ FilmEditor::film_changed (Film::Property p)
                checked_set (_three_d, _film->three_d ());
                setup_dcp_name ();
                break;
+       case Film::INTEROP:
+               checked_set (_standard, _film->interop() ? 1 : 0);
+               break;
        }
 }
 
@@ -533,6 +554,7 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::AUDIO_CHANNELS);
        film_changed (Film::SEQUENCE_VIDEO);
        film_changed (Film::THREE_D);
+       film_changed (Film::INTEROP);
 
        if (!_film->content().empty ()) {
                set_selection (_film->content().front ());
@@ -565,6 +587,7 @@ FilmEditor::set_general_sensitivity (bool s)
        _resolution->Enable (s);
        _scaler->Enable (s);
        _three_d->Enable (s);
+       _standard->Enable (s);
 
        /* Set the panels in the content notebook */
        for (list<FilmEditorPanel*>::iterator i = _panels.begin(); i != _panels.end(); ++i) {
index 30b4bd73e8f634b2472ffe2c7a797c3d2a31fcd8..8ecec3ec76801b6612d1a196a6a9465bde774a91 100644 (file)
@@ -92,6 +92,7 @@ private:
        void sequence_video_changed ();
        void content_right_click (wxListEvent &);
        void three_d_changed ();
+       void standard_changed ();
 
        /* Handle changes to the model */
        void film_changed (Film::Property);
@@ -141,6 +142,7 @@ private:
        wxButton* _best_frame_rate;
        wxCheckBox* _three_d;
        wxChoice* _resolution;
+       wxChoice* _standard;
 
        ContentMenu _menu;