More choose-dcp-rate stuff.
authorCarl Hetherington <cth@carlh.net>
Fri, 1 Mar 2013 23:21:30 +0000 (23:21 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 1 Mar 2013 23:21:30 +0000 (23:21 +0000)
src/lib/config.cc
src/lib/film.cc
src/wx/film_editor.cc
src/wx/film_editor.h
test/test.cc

index 82a31b3cf0a98d23d191f4906776457abff32903..f5273b8753977449fc3334af769e35cf491a8ef1 100644 (file)
@@ -49,6 +49,9 @@ Config::Config ()
        _allowed_dcp_frame_rates.push_back (24);
        _allowed_dcp_frame_rates.push_back (25);
        _allowed_dcp_frame_rates.push_back (30);
+       _allowed_dcp_frame_rates.push_back (48);
+       _allowed_dcp_frame_rates.push_back (50);
+       _allowed_dcp_frame_rates.push_back (60);
        
        ifstream f (file().c_str ());
        string line;
index a661adcc6c5c3d72a1fce142f7dcdfba279f21a0..1c4a8108d9a7008cbc4b32c0e47be4f8d6c81ad3 100644 (file)
@@ -275,6 +275,7 @@ Film::make_dcp ()
                log()->log (String::compose (N_("Content length %1"), length().get()));
        }
        log()->log (String::compose (N_("Content digest %1"), content_digest()));
+       log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate()));
        log()->log (String::compose (N_("%1 threads"), Config::instance()->num_local_encoding_threads()));
        log()->log (String::compose (N_("J2K bandwidth %1"), j2k_bandwidth()));
 #ifdef DVDOMATIC_DEBUG
@@ -602,8 +603,12 @@ Film::read_metadata ()
                        _external_audio_stream = audio_stream_factory (v, version);
                } else if (k == N_("subtitle_stream")) {
                        _subtitle_streams.push_back (subtitle_stream_factory (v, version));
-               } else if (k == N_("source_frame_rate") || (version < 4 && k == "frames_per_second")) {
+               } else if (k == N_("source_frame_rate")) {
                        _source_frame_rate = atof (v.c_str ());
+               } else if (version < 4 && k == "frames_per_second") {
+                       _source_frame_rate = atof (v.c_str ());
+                       /* Fill in what would have been used for DCP frame rate by the older version */
+                       _dcp_frame_rate = best_dcp_frame_rate (_source_frame_rate);
                }
        }
 
@@ -905,6 +910,7 @@ Film::set_content (string c)
                
                set_size (d.video->native_size ());
                set_source_frame_rate (d.video->frames_per_second ());
+               set_dcp_frame_rate (best_dcp_frame_rate (source_frame_rate ()));
                set_subtitle_streams (d.video->subtitle_streams ());
                if (d.audio) {
                        set_content_audio_streams (d.audio->audio_streams ());
index 0a6a352738c94be298bdf8368fcdd7c762c330f1..7453d175a3ce06471522fd224787c0f7ee82f9e2 100644 (file)
@@ -129,6 +129,16 @@ FilmEditor::make_film_panel ()
        video_control (add_label_to_sizer (grid, _film_panel, _("Original Frame Rate")));
        _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT (""));
        grid->Add (video_control (_source_frame_rate), 1, wxALIGN_CENTER_VERTICAL);
+
+       {
+               add_label_to_sizer (grid, _film_panel, _("DCP Frame Rate"));
+               wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+               _dcp_frame_rate = new wxChoice (_film_panel, wxID_ANY);
+               s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL);
+               _best_dcp_frame_rate = new wxButton (_film_panel, wxID_ANY, _("Use best"));
+               s->Add (_best_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 6);
+               grid->Add (s, 1);
+       }
        
        video_control (add_label_to_sizer (grid, _film_panel, _("Original Size")));
        _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT (""));
@@ -173,6 +183,11 @@ FilmEditor::make_film_panel ()
        for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) {
                _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ()));
        }
+
+       list<int> const dfr = Config::instance()->allowed_dcp_frame_rates ();
+       for (list<int>::const_iterator i = dfr.begin(); i != dfr.end(); ++i) {
+               _dcp_frame_rate->Append (std_to_wx (boost::lexical_cast<string> (*i)));
+       }
 }
 
 void
@@ -191,6 +206,8 @@ FilmEditor::connect_to_widgets ()
        _filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_filters_clicked), 0, this);
        _scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::scaler_changed), 0, this);
        _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this);
+       _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this);
+       _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this);
        _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this);
        _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this);
        _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this);
@@ -520,7 +537,21 @@ FilmEditor::j2k_bandwidth_changed (wxCommandEvent &)
        }
        
        _film->set_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1e6);
-}      
+}
+
+void
+FilmEditor::dcp_frame_rate_changed (wxCommandEvent &)
+{
+       if (!_film) {
+               return;
+       }
+
+       _film->set_dcp_frame_rate (
+               boost::lexical_cast<int> (
+                       wx_to_std (_dcp_frame_rate->GetString (_dcp_frame_rate->GetSelection ()))
+                       )
+               );
+}
 
 
 /** Called when the metadata stored in the Film object has changed;
@@ -700,6 +731,15 @@ FilmEditor::film_changed (Film::Property p)
                setup_audio_details ();
                break;
        }
+       case Film::DCP_FRAME_RATE:
+               for (unsigned int i = 0; i < _dcp_frame_rate->GetCount(); ++i) {
+                       if (wx_to_std (_dcp_frame_rate->GetString(i)) == boost::lexical_cast<string> (_film->dcp_frame_rate())) {
+                               if (_dcp_frame_rate->GetSelection() != int(i)) {
+                                       _dcp_frame_rate->SetSelection (i);
+                                       break;
+                               }
+                       }
+               }
        }
 }
 
@@ -783,6 +823,7 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::CONTENT_AUDIO_STREAMS);
        film_changed (Film::SUBTITLE_STREAMS);
        film_changed (Film::SOURCE_FRAME_RATE);
+       film_changed (Film::DCP_FRAME_RATE);
 }
 
 /** Updates the sensitivity of lots of widgets to a given value.
@@ -807,6 +848,7 @@ FilmEditor::set_things_sensitive (bool s)
        _scaler->Enable (s);
        _audio_stream->Enable (s);
        _dcp_content_type->Enable (s);
+       _dcp_frame_rate->Enable (s);
        _trim_start->Enable (s);
        _trim_end->Enable (s);
        _dcp_ab->Enable (s);
@@ -1186,3 +1228,13 @@ FilmEditor::show_audio_clicked (wxCommandEvent &)
        _audio_dialog->Show ();
        _audio_dialog->set_film (_film);
 }
+
+void
+FilmEditor::best_dcp_frame_rate_clicked (wxCommandEvent &)
+{
+       if (!_film) {
+               return;
+       }
+       
+       _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ()));
+}
index da9bb0301e46023868bd5d77efb8a1616351ea26..4adea2bc9fab6a994e5eb1a7b4729ce4dc62f9f7 100644 (file)
@@ -82,6 +82,8 @@ private:
        void subtitle_stream_changed (wxCommandEvent &);
        void use_audio_changed (wxCommandEvent &);
        void external_audio_changed (wxCommandEvent &);
+       void dcp_frame_rate_changed (wxCommandEvent &);
+       void best_dcp_frame_rate_clicked (wxCommandEvent &);
 
        /* Handle changes to the model */
        void film_changed (Film::Property);
@@ -159,6 +161,8 @@ private:
        wxChoice* _dcp_content_type;
        /** The Film's source frame rate */
        wxStaticText* _source_frame_rate;
+       wxChoice* _dcp_frame_rate;
+       wxButton* _best_dcp_frame_rate;
        /** The Film's original size */
        wxStaticText* _original_size;
        /** The Film's length */
index b4a459fe7d934da5d8ba3385edbe6ee27b5b1f9a..15c34ca78dc23206f0efaa9f83e512701db202de 100644 (file)
@@ -617,10 +617,36 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
        BOOST_CHECK_EQUAL (frc.skip, false);
        BOOST_CHECK_EQUAL (frc.repeat, false);
        BOOST_CHECK_EQUAL (frc.change_speed, false);
+
+       /* Check some out-there conversions (not the best) */
+       
+       frc = FrameRateConversion (14.99, 24);
+       BOOST_CHECK_EQUAL (frc.skip, false);
+       BOOST_CHECK_EQUAL (frc.repeat, true);
+       BOOST_CHECK_EQUAL (frc.change_speed, true);
+
+       /* Check some conversions with limited DCP targets */
+
+       afr.clear ();
+       afr.push_back (24);
+       Config::instance()->set_allowed_dcp_frame_rates (afr);
+
+       best = best_dcp_frame_rate (25);
+       frc = FrameRateConversion (25, best);
+       BOOST_CHECK_EQUAL (best, 24);
+       BOOST_CHECK_EQUAL (frc.skip, false);
+       BOOST_CHECK_EQUAL (frc.repeat, false);
+       BOOST_CHECK_EQUAL (frc.change_speed, true);
 }
 
 BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
 {
+       std::list<int> afr;
+       afr.push_back (24);
+       afr.push_back (25);
+       afr.push_back (30);
+       Config::instance()->set_allowed_dcp_frame_rates (afr);
+
        shared_ptr<Film> f = new_test_film ("audio_sampling_rate_test");
        f->set_source_frame_rate (24);
        f->set_dcp_frame_rate (24);
@@ -641,8 +667,29 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
 
        f->set_source_frame_rate (29.97);
        f->set_dcp_frame_rate (best_dcp_frame_rate (29.97));
+       BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30);
        f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
        BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952);
+
+       f->set_source_frame_rate (25);
+       f->set_dcp_frame_rate (24);
+       f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
+       BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
+
+       f->set_source_frame_rate (25);
+       f->set_dcp_frame_rate (24);
+       f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
+       BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
+
+       /* Check some out-there conversions (not the best) */
+       
+       f->set_source_frame_rate (14.99);
+       f->set_dcp_frame_rate (25);
+       f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
+       /* The FrameRateConversion within target_audio_sample_rate should choose to double-up
+          the 14.99 fps video to 30 and then run it slow at 25.
+       */
+       BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), rint (48000 * 2 * 14.99 / 25));
 }
 
 class TestJob : public Job