From: Carl Hetherington Date: Wed, 10 Apr 2013 18:43:01 +0000 (+0100) Subject: Merge master. X-Git-Tag: v2.0.48~1337^2~458 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=9bdd8cc51942a13e360dde4efc04b3ca417c8b94;hp=-c Merge master. --- 9bdd8cc51942a13e360dde4efc04b3ca417c8b94 diff --combined src/lib/format.cc index 5eda9eb88,faadcd797..cce8762bd --- a/src/lib/format.cc +++ b/src/lib/format.cc @@@ -29,7 -29,6 +29,7 @@@ #include #include "format.h" #include "film.h" +#include "playlist.h" #include "i18n.h" @@@ -200,14 -199,14 +200,14 @@@ FixedFormat::FixedFormat (int r, libdcp int Format::dcp_padding (shared_ptr f) const { - int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0); - int p = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_float(f))) / 2.0); ++ int p = rint ((_dcp_size.width - (_dcp_size.height * ratio(f))) / 2.0); /* This comes out -ve for Scope; bodge it */ - if (pad < 0) { - pad = 0; + if (p < 0) { + p = 0; } - return pad; + return p; } float @@@ -231,7 -230,8 +231,8 @@@ VariableFormat::ratio_as_integer (share float VariableFormat::ratio_as_float (shared_ptr f) const { - return float (f->video_size().width) / f->video_size().height; - libdcp::Size const c = f->cropped_size (f->size ()); ++ libdcp::Size const c = f->cropped_size (f->video_size ()); + return float (c.width) / c.height; } /** @return A name to be presented to the user */ diff --combined src/tools/dvdomatic.cc index 239b4a517,212d4848e..3fc19a91c --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@@ -59,7 -59,6 +59,7 @@@ static FilmViewer* film_viewer = 0 static shared_ptr film; static std::string log_level; static std::string film_to_load; +static std::string film_to_create; static wxMenu* jobs_menu = 0; static wxLocale* locale = 0; @@@ -72,7 -71,7 +72,7 @@@ public { _dialog = new wxMessageDialog ( 0, - std_to_wx (String::compose (wx_to_std (_("Save changes to film \"%1\" before closing?")), film->name())), + wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (film->name ()).data()), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION ); @@@ -237,6 -236,9 +237,6 @@@ public set_menu_sensitivity (); - /* XXX: calling these here is a bit of a hack */ - film_editor->setup_visibility (); - film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1)); if (film) { file_changed (film->directory ()); @@@ -440,15 -442,13 +440,15 @@@ private #if wxMINOR_VERSION == 9 static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, "l", "log", "set log level (silent, verbose or timing)", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, "film to load", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } }; #else static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, wxT("l"), wxT("log"), wxT("set log level (silent, verbose or timing)"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, wxT("film to load"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, wxT("n"), wxT("new"), wxT("create new film"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, wxT("film to load or create"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, wxT(""), wxT(""), wxT(""), wxCmdLineParamType (0), 0 } }; #endif @@@ -528,12 -528,6 +528,12 @@@ class App : public wxAp } } + if (!film_to_create.empty ()) { + film.reset (new Film (film_to_create, false)); + film->log()->set_level (log_level); + film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ()); + } + Frame* f = new Frame (_("DVD-o-matic")); SetTopWindow (f); f->Maximize (); @@@ -554,15 -548,11 +554,15 @@@ bool OnCmdLineParsed (wxCmdLineParser& parser) { if (parser.GetParamCount() > 0) { - film_to_load = wx_to_std (parser.GetParam(0)); + if (parser.FoundSwitch (wxT ("new"))) { + film_to_create = wx_to_std (parser.GetParam (0)); + } else { + film_to_load = wx_to_std (parser.GetParam(0)); + } } wxString log; - if (parser.Found(wxT("log"), &log)) { + if (parser.Found (wxT ("log"), &log)) { log_level = wx_to_std (log); } diff --combined src/wx/film_editor.cc index 9cd10ad61,62eecb70c..c03a13bfe --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@@ -25,7 -25,6 +25,7 @@@ #include #include #include +#include #include #include #include @@@ -38,9 -37,6 +38,9 @@@ #include "lib/filter.h" #include "lib/config.h" #include "lib/ffmpeg_decoder.h" +#include "lib/imagemagick_content.h" +#include "lib/sndfile_content.h" +#include "lib/dcp_content_type.h" #include "filter_dialog.h" #include "wx_util.h" #include "film_editor.h" @@@ -49,8 -45,6 +49,8 @@@ #include "dci_metadata_dialog.h" #include "scaler.h" #include "audio_dialog.h" +#include "imagemagick_content_dialog.h" +#include "audio_mapping_view.h" using std::string; using std::cout; @@@ -61,24 -55,22 +61,24 @@@ using std::setprecision using std::list; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; +using boost::lexical_cast; /** @param f Film to edit */ FilmEditor::FilmEditor (shared_ptr f, wxWindow* parent) : wxPanel (parent) - , _film (f) , _generally_sensitive (true) , _audio_dialog (0) { wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - SetSizer (s); _notebook = new wxNotebook (this, wxID_ANY); s->Add (_notebook, 1); make_film_panel (); _notebook->AddPage (_film_panel, _("Film"), true); + make_content_panel (); + _notebook->AddPage (_content_panel, _("Content"), false); make_video_panel (); _notebook->AddPage (_video_panel, _("Video"), false); make_audio_panel (); @@@ -86,16 -78,15 +86,16 @@@ make_subtitle_panel (); _notebook->AddPage (_subtitle_panel, _("Subtitles"), false); - set_film (_film); + set_film (f); connect_to_widgets (); JobManager::instance()->ActiveJobsChanged.connect ( bind (&FilmEditor::active_jobs_changed, this, _1) ); - setup_visibility (); setup_formats (); + + SetSizerAndFit (s); } void @@@ -126,8 -117,14 +126,8 @@@ FilmEditor::make_film_panel ( grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan); ++r; - add_label_to_grid_bag_sizer (grid, _film_panel, _("Content"), wxGBPosition (r, 0)); - _content = new wxFilePickerCtrl (_film_panel, wxID_ANY, wxT (""), _("Select Content File"), wxT("*.*")); - grid->Add (_content, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); - ++r; - - _trust_content_header = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); - video_control (_trust_content_header); - grid->Add (_trust_content_header, wxGBPosition (r, 0), wxGBSpan(1, 2)); + _trust_content_headers = new wxCheckBox (_film_panel, wxID_ANY, _("Trust content's header")); + grid->Add (_trust_content_headers, wxGBPosition (r, 0), wxGBSpan(1, 2)); ++r; add_label_to_grid_bag_sizer (grid, _film_panel, _("Content Type"), wxGBPosition (r, 0)); @@@ -135,6 -132,11 +135,6 @@@ grid->Add (_dcp_content_type, wxGBPosition (r, 1)); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Frame Rate"), wxGBPosition (r, 0))); - _source_frame_rate = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_source_frame_rate), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - { add_label_to_grid_bag_sizer (grid, _film_panel, _("DCP Frame Rate"), wxGBPosition (r, 0)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); @@@ -146,36 -148,55 +146,36 @@@ } ++r; - _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT (" \n \n "), wxDefaultPosition, wxDefaultSize); + _frame_rate_description = new wxStaticText (_film_panel, wxID_ANY, wxT ("\n \n "), wxDefaultPosition, wxDefaultSize); - grid->Add (video_control (_frame_rate_description), wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); + grid->Add (_frame_rate_description, wxGBPosition (r, 0), wxGBSpan (1, 2), wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 6); wxFont font = _frame_rate_description->GetFont(); font.SetStyle(wxFONTSTYLE_ITALIC); font.SetPointSize(font.GetPointSize() - 1); _frame_rate_description->SetFont(font); ++r; - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Original Size"), wxGBPosition (r, 0))); - _original_size = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_original_size), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Length"), wxGBPosition (r, 0)); _length = new wxStaticText (_film_panel, wxID_ANY, wxT ("")); - grid->Add (video_control (_length), wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + grid->Add (_length, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; { - video_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim frames"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _film_panel, _("Trim frames"), wxGBPosition (r, 0)); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - video_control (add_label_to_sizer (s, _film_panel, _("Start"))); + add_label_to_sizer (s, _film_panel, _("Start")); _trim_start = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_trim_start)); - video_control (add_label_to_sizer (s, _film_panel, _("End"))); + s->Add (_trim_start); + add_label_to_sizer (s, _film_panel, _("End")); _trim_end = new wxSpinCtrl (_film_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)); - s->Add (video_control (_trim_end)); + s->Add (_trim_end); grid->Add (s, wxGBPosition (r, 1)); } ++r; - _dcp_ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); - video_control (_dcp_ab); - grid->Add (_dcp_ab, wxGBPosition (r, 0)); - ++r; - - /* STILL-only stuff */ - { - still_control (add_label_to_grid_bag_sizer (grid, _film_panel, _("Duration"), wxGBPosition (r, 0))); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _still_duration = new wxSpinCtrl (_film_panel); - still_control (_still_duration); - s->Add (_still_duration, 1, wxEXPAND); - /// TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time - still_control (add_label_to_sizer (s, _film_panel, _("s"))); - grid->Add (s, wxGBPosition (r, 1)); - } + _ab = new wxCheckBox (_film_panel, wxID_ANY, _("A/B")); + grid->Add (_ab, wxGBPosition (r, 0)); ++r; vector const ct = DCPContentType::all (); @@@ -196,15 -217,8 +196,15 @@@ FilmEditor::connect_to_widgets ( _use_dci_name->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::use_dci_name_toggled), 0, this); _edit_dci_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::edit_dci_button_clicked), 0, this); _format->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::format_changed), 0, this); - _content->Connect (wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::content_changed), 0, this); - _trust_content_header->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_header_changed), 0, this); + _trust_content_headers->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::trust_content_headers_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler (FilmEditor::content_selection_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler (FilmEditor::content_selection_changed), 0, this); + _content->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler (FilmEditor::content_activated), 0, this); + _content_add->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_add_clicked), 0, this); + _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); + _content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this); + _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); + _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@@ -214,7 -228,8 +214,7 @@@ _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); + _ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::ab_toggled), 0, this); _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); _trim_end->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_end_changed), 0, this); _with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this); @@@ -222,14 -237,21 +222,14 @@@ _subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this); _colour_lut->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::colour_lut_changed), 0, this); _j2k_bandwidth->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::j2k_bandwidth_changed), 0, this); - _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::subtitle_stream_changed), 0, this); - _audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::audio_stream_changed), 0, this); + _ffmpeg_subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_subtitle_stream_changed), 0, this); + _ffmpeg_audio_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::ffmpeg_audio_stream_changed), 0, this); _audio_gain->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_gain_changed), 0, this); _audio_gain_calculate_button->Connect ( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::audio_gain_calculate_button_clicked), 0, this ); _show_audio->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::show_audio_clicked), 0, this); _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this); - _use_content_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); - _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this); - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - _external_audio[i]->Connect ( - wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::external_audio_changed), 0, this - ); - } } void @@@ -278,19 -300,21 +278,19 @@@ FilmEditor::make_video_panel ( /* VIDEO-only stuff */ { - video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0)); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); _filters = new wxStaticText (_video_panel, wxID_ANY, _("None")); - video_control (_filters); s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); _filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit...")); - video_control (_filters_button); s->Add (_filters_button, 0); grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); } ++r; - video_control (add_label_to_grid_bag_sizer (grid, _video_panel, _("Scaler"), wxGBPosition (r, 0))); + add_label_to_grid_bag_sizer (grid, _video_panel, _("Scaler"), wxGBPosition (r, 0)); _scaler = new wxChoice (_video_panel, wxID_ANY); - grid->Add (video_control (_scaler), wxGBPosition (r, 1)); + grid->Add (_scaler, wxGBPosition (r, 1)); ++r; vector const sc = Scaler::all (); @@@ -321,48 -345,12 +321,48 @@@ _top_crop->SetRange (0, 1024); _right_crop->SetRange (0, 1024); _bottom_crop->SetRange (0, 1024); - _still_duration->SetRange (1, 60 * 60); _trim_start->SetRange (0, 100); _trim_end->SetRange (0, 100); _j2k_bandwidth->SetRange (50, 250); } +void +FilmEditor::make_content_panel () +{ + _content_panel = new wxPanel (_notebook); + _content_sizer = new wxBoxSizer (wxVERTICAL); + _content_panel->SetSizer (_content_sizer); + + { + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + + _content = new wxListCtrl (_content_panel, wxID_ANY, wxDefaultPosition, wxSize (320, 160), wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL); + s->Add (_content, 1, wxEXPAND | wxTOP | wxBOTTOM, 6); + + _content->InsertColumn (0, wxT("")); + _content->SetColumnWidth (0, 512); + + wxBoxSizer* b = new wxBoxSizer (wxVERTICAL); + _content_add = new wxButton (_content_panel, wxID_ANY, _("Add...")); + b->Add (_content_add); + _content_remove = new wxButton (_content_panel, wxID_ANY, _("Remove")); + b->Add (_content_remove); + _content_edit = new wxButton (_content_panel, wxID_ANY, _("Edit...")); + b->Add (_content_edit); + _content_earlier = new wxButton (_content_panel, wxID_ANY, _("Earlier")); + b->Add (_content_earlier); + _content_later = new wxButton (_content_panel, wxID_ANY, _("Later")); + b->Add (_content_later); + + s->Add (b, 0, wxALL, 4); + + _content_sizer->Add (s, 1, wxEXPAND | wxALL, 6); + } + + _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); + _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); +} + void FilmEditor::make_audio_panel () { @@@ -378,39 -366,48 +378,39 @@@ grid->AddSpacer (0); { - video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Gain"))); + add_label_to_sizer (grid, _audio_panel, _("Audio Gain")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_gain = new wxSpinCtrl (_audio_panel); - s->Add (video_control (_audio_gain), 1); - video_control (add_label_to_sizer (s, _audio_panel, _("dB"))); + s->Add (_audio_gain, 1); + add_label_to_sizer (s, _audio_panel, _("dB")); _audio_gain_calculate_button = new wxButton (_audio_panel, wxID_ANY, _("Calculate...")); - video_control (_audio_gain_calculate_button); s->Add (_audio_gain_calculate_button, 1, wxEXPAND); grid->Add (s); } { - video_control (add_label_to_sizer (grid, _audio_panel, _("Audio Delay"))); + add_label_to_sizer (grid, _audio_panel, _("Audio Delay")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _audio_delay = new wxSpinCtrl (_audio_panel); - s->Add (video_control (_audio_delay), 1); + s->Add (_audio_delay, 1); /// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time - video_control (add_label_to_sizer (s, _audio_panel, _("ms"))); + add_label_to_sizer (s, _audio_panel, _("ms")); grid->Add (s); } - { - _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); - grid->Add (video_control (_use_content_audio)); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _audio_stream = new wxChoice (_audio_panel, wxID_ANY); - s->Add (video_control (_audio_stream), 1); - _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); - s->Add (video_control (_audio), 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); - grid->Add (s, 1, wxEXPAND); - } - - _use_external_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use external audio")); - grid->Add (_use_external_audio); - grid->AddSpacer (0); - - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - add_label_to_sizer (grid, _audio_panel, std_to_wx (audio_channel_name (i))); - _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), _("Select Audio File"), wxT ("*.wav")); - grid->Add (_external_audio[i], 1, wxEXPAND); - } + { + add_label_to_sizer (grid, _audio_panel, _("Audio Stream")); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _ffmpeg_audio_stream = new wxChoice (_audio_panel, wxID_ANY); + s->Add (_ffmpeg_audio_stream, 1); + _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT ("")); + s->Add (_audio, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8); + grid->Add (s, 1, wxEXPAND); + } + _audio_mapping = new AudioMappingView (_audio_panel); + _audio_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6); + _audio_gain->SetRange (-60, 60); _audio_delay->SetRange (-1000, 1000); } @@@ -425,26 -422,27 +425,26 @@@ FilmEditor::make_subtitle_panel ( _subtitle_sizer->Add (grid, 0, wxALL, 8); _with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles")); - video_control (_with_subtitles); grid->Add (_with_subtitles, 1); - _subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); - grid->Add (video_control (_subtitle_stream)); + _ffmpeg_subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY); + grid->Add (_ffmpeg_subtitle_stream); { - video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"))); + add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _subtitle_offset = new wxSpinCtrl (_subtitle_panel); s->Add (_subtitle_offset); - video_control (add_label_to_sizer (s, _subtitle_panel, _("pixels"))); + add_label_to_sizer (s, _subtitle_panel, _("pixels")); grid->Add (s); } { - video_control (add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"))); + add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale")); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _subtitle_scale = new wxSpinCtrl (_subtitle_panel); - s->Add (video_control (_subtitle_scale)); - video_control (add_label_to_sizer (s, _subtitle_panel, _("%"))); + s->Add (_subtitle_scale); + add_label_to_sizer (s, _subtitle_panel, _("%")); grid->Add (s); } @@@ -496,25 -494,41 +496,25 @@@ FilmEditor::bottom_crop_changed (wxComm _film->set_bottom_crop (_bottom_crop->GetValue ()); } -/** Called when the content filename has been changed */ -void -FilmEditor::content_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - try { - _film->set_content (wx_to_std (_content->GetPath ())); - } catch (std::exception& e) { - _content->SetPath (std_to_wx (_film->directory ())); - error_dialog (this, wxString::Format (_("Could not set content: %s"), std_to_wx (e.what()).data())); - } -} - void -FilmEditor::trust_content_header_changed (wxCommandEvent &) +FilmEditor::trust_content_headers_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_trust_content_header (_trust_content_header->GetValue ()); + _film->set_trust_content_headers (_trust_content_headers->GetValue ()); } /** Called when the DCP A/B switch has been toggled */ void -FilmEditor::dcp_ab_toggled (wxCommandEvent &) +FilmEditor::ab_toggled (wxCommandEvent &) { if (!_film) { return; } - _film->set_dcp_ab (_dcp_ab->GetValue ()); + _film->set_ab (_ab->GetValue ()); } /** Called when the name widget has been changed */ @@@ -602,19 -616,43 +602,19 @@@ FilmEditor::film_changed (Film::Propert case Film::NONE: break; case Film::CONTENT: - checked_set (_content, _film->content ()); - setup_visibility (); + setup_content (); setup_formats (); + setup_format (); setup_subtitle_control_sensitivity (); setup_streams (); setup_show_audio_sensitivity (); - setup_frame_rate_description (); break; - case Film::TRUST_CONTENT_HEADER: - checked_set (_trust_content_header, _film->trust_content_header ()); - break; - case Film::SUBTITLE_STREAMS: - setup_subtitle_control_sensitivity (); - setup_streams (); - break; - case Film::CONTENT_AUDIO_STREAMS: - setup_streams (); - setup_show_audio_sensitivity (); - setup_frame_rate_description (); + case Film::TRUST_CONTENT_HEADERS: + checked_set (_trust_content_headers, _film->trust_content_headers ()); break; case Film::FORMAT: - { - int n = 0; - vector::iterator i = _formats.begin (); - while (i != _formats.end() && *i != _film->format ()) { - ++i; - ++n; - } - if (i == _formats.end()) { - checked_set (_format, -1); - } else { - checked_set (_format, n); - } - setup_dcp_name (); - setup_scaling_description (); + setup_format (); break; - } case Film::CROP: checked_set (_left_crop, _film->crop().left); checked_set (_right_crop, _film->crop().right); @@@ -638,12 -676,40 +638,12 @@@ checked_set (_name, _film->name()); setup_dcp_name (); break; - case Film::SOURCE_FRAME_RATE: - s << fixed << setprecision(2) << _film->source_frame_rate(); - _source_frame_rate->SetLabel (std_to_wx (s.str ())); - setup_frame_rate_description (); - break; - case Film::SIZE: - if (_film->size().width == 0 && _film->size().height == 0) { - _original_size->SetLabel (wxT ("")); - } else { - s << _film->size().width << " x " << _film->size().height; - _original_size->SetLabel (std_to_wx (s.str ())); - } - setup_scaling_description (); - break; - case Film::LENGTH: - if (_film->source_frame_rate() > 0 && _film->length()) { - s << _film->length().get() << " " - << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->length().get() / _film->source_frame_rate()); - } else if (_film->length()) { - s << _film->length().get() << " " - << wx_to_std (_("frames")); - } - _length->SetLabel (std_to_wx (s.str ())); - if (_film->length()) { - _trim_start->SetRange (0, _film->length().get()); - _trim_end->SetRange (0, _film->length().get()); - } - break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); setup_dcp_name (); break; - case Film::DCP_AB: - checked_set (_dcp_ab, _film->dcp_ab ()); + case Film::AB: + checked_set (_ab, _film->ab ()); break; case Film::SCALER: checked_set (_scaler, Scaler::as_index (_film->scaler ())); @@@ -660,6 -726,9 +660,6 @@@ case Film::AUDIO_DELAY: checked_set (_audio_delay, _film->audio_delay ()); break; - case Film::STILL_DURATION: - checked_set (_still_duration, _film->still_duration ()); - break; case Film::WITH_SUBTITLES: checked_set (_with_subtitles, _film->with_subtitles ()); setup_subtitle_control_sensitivity (); @@@ -684,6 -753,41 +684,6 @@@ case Film::DCI_METADATA: setup_dcp_name (); break; - case Film::CONTENT_AUDIO_STREAM: - if (_film->content_audio_stream()) { - checked_set (_audio_stream, _film->content_audio_stream()->to_string()); - } - setup_dcp_name (); - setup_audio_details (); - setup_audio_control_sensitivity (); - setup_show_audio_sensitivity (); - setup_frame_rate_description (); - break; - case Film::USE_CONTENT_AUDIO: - checked_set (_use_content_audio, _film->use_content_audio()); - checked_set (_use_external_audio, !_film->use_content_audio()); - setup_dcp_name (); - setup_audio_details (); - setup_audio_control_sensitivity (); - setup_show_audio_sensitivity (); - setup_frame_rate_description (); - break; - case Film::SUBTITLE_STREAM: - if (_film->subtitle_stream()) { - checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); - } - break; - case Film::EXTERNAL_AUDIO: - { - vector a = _film->external_audio (); - for (size_t i = 0; i < a.size() && i < MAX_AUDIO_CHANNELS; ++i) { - checked_set (_external_audio[i], a[i]); - } - setup_audio_details (); - setup_show_audio_sensitivity (); - setup_frame_rate_description (); - 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 (_film->dcp_frame_rate())) { @@@ -694,114 -798,41 +694,118 @@@ } } - if (_film->source_frame_rate()) { - _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->source_frame_rate ()) != _film->dcp_frame_rate ()); + if (_film->video_frame_rate()) { + _best_dcp_frame_rate->Enable (best_dcp_frame_rate (_film->video_frame_rate ()) != _film->dcp_frame_rate ()); } else { _best_dcp_frame_rate->Disable (); } - setup_frame_rate_description (); + break; + case Film::AUDIO_MAPPING: + _audio_mapping->set_mapping (_film->audio_mapping ()); + break; + } +} + +void +FilmEditor::film_content_changed (weak_ptr content, int property) +{ + if (!_film) { + /* We call this method ourselves (as well as using it as a signal handler) + so _film can be 0. + */ + return; + } + + if (property == FFmpegContentProperty::SUBTITLE_STREAMS) { + setup_subtitle_control_sensitivity (); + setup_streams (); + } else if (property == FFmpegContentProperty::AUDIO_STREAMS) { + setup_streams (); + setup_show_audio_sensitivity (); + } else if (property == VideoContentProperty::VIDEO_LENGTH) { + setup_length (); + boost::shared_ptr c = content.lock (); + if (c && c == selected_content()) { + setup_content_information (); + } + } else if (property == FFmpegContentProperty::AUDIO_STREAM) { + if (_film->ffmpeg_audio_stream()) { + checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); + } + setup_dcp_name (); + setup_audio_details (); + setup_show_audio_sensitivity (); + } else if (property == FFmpegContentProperty::SUBTITLE_STREAM) { + if (_film->ffmpeg_subtitle_stream()) { + checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); + } } } +void +FilmEditor::setup_format () +{ + int n = 0; + vector::iterator i = _formats.begin (); + while (i != _formats.end() && *i != _film->format ()) { + ++i; + ++n; + } + + if (i == _formats.end()) { + checked_set (_format, -1); + } else { + checked_set (_format, n); + } + + setup_dcp_name (); + setup_scaling_description (); +} + +void +FilmEditor::setup_length () +{ + stringstream s; + if (_film->video_frame_rate() > 0 && _film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")) << "; " << seconds_to_hms (_film->video_length() / _film->video_frame_rate()); + } else if (_film->video_length()) { + s << _film->video_length() << " " + << wx_to_std (_("frames")); + } + _length->SetLabel (std_to_wx (s.str ())); + if (_film->video_length()) { + _trim_start->SetRange (0, _film->video_length()); + _trim_end->SetRange (0, _film->video_length()); + } +} + void FilmEditor::setup_frame_rate_description () { wxString d; + int lines = 0; + - if (_film->source_frame_rate()) { - d << std_to_wx (FrameRateConversion (_film->source_frame_rate(), _film->dcp_frame_rate()).description); + if (_film->video_frame_rate()) { + d << std_to_wx (FrameRateConversion (_film->video_frame_rate(), _film->dcp_frame_rate()).description); + ++lines; #ifdef HAVE_SWRESAMPLE - if (_film->audio_stream() && _film->audio_stream()->sample_rate() != _film->target_audio_sample_rate ()) { + if (_film->audio_frame_rate() && _film->audio_frame_rate() != _film->target_audio_sample_rate ()) { d << wxString::Format ( _("Audio will be resampled from %dHz to %dHz\n"), - _film->audio_stream()->sample_rate(), + _film->audio_frame_rate(), _film->target_audio_sample_rate() ); - } else { - d << wxT ("\n"); + ++lines; } - #else - d << wxT ("\n"); #endif } + for (int i = lines; i < 2; ++i) { + d << wxT ("\n "); + } + _frame_rate_description->SetLabel (d); } @@@ -838,17 -869,12 +842,17 @@@ FilmEditor::dcp_content_type_changed (w void FilmEditor::set_film (shared_ptr f) { - _film = f; - set_things_sensitive (_film != 0); + if (_film == f) { + return; + } + + _film = f; + if (_film) { _film->Changed.connect (bind (&FilmEditor::film_changed, this, _1)); + _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1, _2)); } if (_film) { @@@ -864,7 -890,7 +868,7 @@@ film_changed (Film::NAME); film_changed (Film::USE_DCI_NAME); film_changed (Film::CONTENT); - film_changed (Film::TRUST_CONTENT_HEADER); + film_changed (Film::TRUST_CONTENT_HEADERS); film_changed (Film::DCP_CONTENT_TYPE); film_changed (Film::FORMAT); film_changed (Film::CROP); @@@ -872,22 -898,25 +876,22 @@@ film_changed (Film::SCALER); film_changed (Film::TRIM_START); film_changed (Film::TRIM_END); - film_changed (Film::DCP_AB); - film_changed (Film::CONTENT_AUDIO_STREAM); - film_changed (Film::EXTERNAL_AUDIO); - film_changed (Film::USE_CONTENT_AUDIO); + film_changed (Film::AB); film_changed (Film::AUDIO_GAIN); film_changed (Film::AUDIO_DELAY); - film_changed (Film::STILL_DURATION); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); film_changed (Film::COLOUR_LUT); film_changed (Film::J2K_BANDWIDTH); film_changed (Film::DCI_METADATA); - film_changed (Film::SIZE); - film_changed (Film::LENGTH); - film_changed (Film::CONTENT_AUDIO_STREAMS); - film_changed (Film::SUBTITLE_STREAMS); - film_changed (Film::SOURCE_FRAME_RATE); film_changed (Film::DCP_FRAME_RATE); + film_changed (Film::AUDIO_MAPPING); + + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAMS); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::SUBTITLE_STREAM); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAMS); + film_content_changed (boost::shared_ptr (), FFmpegContentProperty::AUDIO_STREAM); } /** Updates the sensitivity of lots of widgets to a given value. @@@ -903,30 -932,30 +907,30 @@@ FilmEditor::set_things_sensitive (bool _edit_dci_button->Enable (s); _format->Enable (s); _content->Enable (s); - _trust_content_header->Enable (s); + _trust_content_headers->Enable (s); + _content->Enable (s); _left_crop->Enable (s); _right_crop->Enable (s); _top_crop->Enable (s); _bottom_crop->Enable (s); _filters_button->Enable (s); _scaler->Enable (s); - _audio_stream->Enable (s); + _ffmpeg_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); + _ab->Enable (s); _colour_lut->Enable (s); _j2k_bandwidth->Enable (s); _audio_gain->Enable (s); _audio_gain_calculate_button->Enable (s); _show_audio->Enable (s); _audio_delay->Enable (s); - _still_duration->Enable (s); setup_subtitle_control_sensitivity (); - setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); + setup_content_button_sensitivity (); } /** Called when the `Edit filters' button has been clicked */ @@@ -973,6 -1002,40 +977,6 @@@ FilmEditor::audio_delay_changed (wxComm _film->set_audio_delay (_audio_delay->GetValue ()); } -wxControl * -FilmEditor::video_control (wxControl* c) -{ - _video_controls.push_back (c); - return c; -} - -wxControl * -FilmEditor::still_control (wxControl* c) -{ - _still_controls.push_back (c); - return c; -} - -void -FilmEditor::setup_visibility () -{ - ContentType c = VIDEO; - - if (_film) { - c = _film->content_type (); - } - - for (list::iterator i = _video_controls.begin(); i != _video_controls.end(); ++i) { - (*i)->Show (c == VIDEO); - } - - for (list::iterator i = _still_controls.begin(); i != _still_controls.end(); ++i) { - (*i)->Show (c == STILL); - } - - setup_notebook_size (); -} - void FilmEditor::setup_notebook_size () { @@@ -991,6 -1054,16 +995,6 @@@ Fit (); } -void -FilmEditor::still_duration_changed (wxCommandEvent &) -{ - if (!_film) { - return; - } - - _film->set_still_duration (_still_duration->GetValue ()); -} - void FilmEditor::trim_start_changed (wxCommandEvent &) { @@@ -1041,7 -1114,20 +1045,7 @@@ FilmEditor::audio_gain_calculate_button void FilmEditor::setup_formats () { - ContentType c = VIDEO; - - if (_film) { - c = _film->content_type (); - } - - _formats.clear (); - - vector fmt = Format::all (); - for (vector::iterator i = fmt.begin(); i != fmt.end(); ++i) { - if (c == VIDEO || (c == STILL && dynamic_cast (*i))) { - _formats.push_back (*i); - } - } + _formats = Format::all (); _format->Clear (); for (vector::iterator i = _formats.begin(); i != _formats.end(); ++i) { @@@ -1066,7 -1152,7 +1070,7 @@@ FilmEditor::setup_subtitle_control_sens { bool h = false; if (_generally_sensitive && _film) { - h = !_film->subtitle_streams().empty(); + h = !_film->ffmpeg_subtitle_streams().empty(); } _with_subtitles->Enable (h); @@@ -1076,11 -1162,26 +1080,11 @@@ j = _film->with_subtitles (); } - _subtitle_stream->Enable (j); + _ffmpeg_subtitle_stream->Enable (j); _subtitle_offset->Enable (j); _subtitle_scale->Enable (j); } -void -FilmEditor::setup_audio_control_sensitivity () -{ - _use_content_audio->Enable (_generally_sensitive && _film && !_film->content_audio_streams().empty()); - _use_external_audio->Enable (_generally_sensitive); - - bool const source = _generally_sensitive && _use_content_audio->GetValue(); - bool const external = _generally_sensitive && _use_external_audio->GetValue(); - - _audio_stream->Enable (source); - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - _external_audio[i]->Enable (external); - } -} - void FilmEditor::use_dci_name_toggled (wxCommandEvent &) { @@@ -1107,84 -1208,73 +1111,84 @@@ FilmEditor::edit_dci_button_clicked (wx void FilmEditor::setup_streams () { - _audio_stream->Clear (); - vector > a = _film->content_audio_streams (); - for (vector >::iterator i = a.begin(); i != a.end(); ++i) { - shared_ptr ffa = dynamic_pointer_cast (*i); - assert (ffa); - _audio_stream->Append (std_to_wx (ffa->name()), new wxStringClientData (std_to_wx (ffa->to_string ()))); + if (!_film) { + return; + } + + _ffmpeg_audio_stream->Clear (); + vector a = _film->ffmpeg_audio_streams (); + for (vector::iterator i = a.begin(); i != a.end(); ++i) { + _ffmpeg_audio_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); } - if (_film->use_content_audio() && _film->audio_stream()) { - checked_set (_audio_stream, _film->audio_stream()->to_string()); + if (_film->ffmpeg_audio_stream()) { + checked_set (_ffmpeg_audio_stream, boost::lexical_cast (_film->ffmpeg_audio_stream()->id)); } - _subtitle_stream->Clear (); - vector > s = _film->subtitle_streams (); - for (vector >::iterator i = s.begin(); i != s.end(); ++i) { - _subtitle_stream->Append (std_to_wx ((*i)->name()), new wxStringClientData (std_to_wx ((*i)->to_string ()))); + _ffmpeg_subtitle_stream->Clear (); + vector s = _film->ffmpeg_subtitle_streams (); + for (vector::iterator i = s.begin(); i != s.end(); ++i) { + _ffmpeg_subtitle_stream->Append (std_to_wx (i->name), new wxStringClientData (std_to_wx (boost::lexical_cast (i->id)))); } - if (_film->subtitle_stream()) { - checked_set (_subtitle_stream, _film->subtitle_stream()->to_string()); + + if (_film->ffmpeg_subtitle_stream()) { + checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast (_film->ffmpeg_subtitle_stream()->id)); } else { - _subtitle_stream->SetSelection (wxNOT_FOUND); + _ffmpeg_subtitle_stream->SetSelection (wxNOT_FOUND); } } void -FilmEditor::audio_stream_changed (wxCommandEvent &) +FilmEditor::ffmpeg_audio_stream_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_content_audio_stream ( - audio_stream_factory ( - string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ())), - Film::state_version - ) - ); + vector a = _film->ffmpeg_audio_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_ffmpeg_audio_stream->GetClientObject (_ffmpeg_audio_stream->GetSelection ())); + while (i != a.end() && lexical_cast (i->id) != s) { + ++i; + } + + if (i != a.end ()) { + _film->set_ffmpeg_audio_stream (*i); + } } void -FilmEditor::subtitle_stream_changed (wxCommandEvent &) +FilmEditor::ffmpeg_subtitle_stream_changed (wxCommandEvent &) { if (!_film) { return; } - _film->set_subtitle_stream ( - subtitle_stream_factory ( - string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ())), - Film::state_version - ) - ); + vector a = _film->ffmpeg_subtitle_streams (); + vector::iterator i = a.begin (); + string const s = string_client_data (_ffmpeg_subtitle_stream->GetClientObject (_ffmpeg_subtitle_stream->GetSelection ())); + while (i != a.end() && lexical_cast (i->id) != s) { + ++i; + } + + if (i != a.end ()) { + _film->set_ffmpeg_subtitle_stream (*i); + } } void FilmEditor::setup_audio_details () { - if (!_film->content_audio_stream()) { + if (!_film->ffmpeg_audio_stream()) { _audio->SetLabel (wxT ("")); } else { wxString s; - if (_film->audio_stream()->channels() == 1) { + if (_film->audio_channels() == 1) { s << _("1 channel"); } else { - s << _film->audio_stream()->channels () << wxT (" ") << _("channels"); + s << _film->audio_channels() << wxT (" ") << _("channels"); } - s << wxT (", ") << _film->audio_stream()->sample_rate() << _("Hz"); + s << wxT (", ") << _film->audio_frame_rate() << _("Hz"); _audio->SetLabel (s); } @@@ -1197,6 -1287,23 +1201,6 @@@ FilmEditor::active_jobs_changed (bool a set_things_sensitive (!a); } -void -FilmEditor::use_audio_changed (wxCommandEvent &) -{ - _film->set_use_content_audio (_use_content_audio->GetValue()); -} - -void -FilmEditor::external_audio_changed (wxCommandEvent &) -{ - vector a; - for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { - a.push_back (wx_to_std (_external_audio[i]->GetPath())); - } - - _film->set_external_audio (a); -} - void FilmEditor::setup_dcp_name () { @@@ -1229,7 -1336,7 +1233,7 @@@ FilmEditor::best_dcp_frame_rate_clicke return; } - _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->source_frame_rate ())); + _film->set_dcp_frame_rate (best_dcp_frame_rate (_film->video_frame_rate ())); } void @@@ -1238,163 -1345,6 +1242,163 @@@ FilmEditor::setup_show_audio_sensitivit _show_audio->Enable (_film && _film->has_audio ()); } +void +FilmEditor::setup_content () +{ + string selected_summary; + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s != -1) { + selected_summary = wx_to_std (_content->GetItemText (s)); + } + + _content->DeleteAllItems (); + + ContentList content = _film->content (); + for (ContentList::iterator i = content.begin(); i != content.end(); ++i) { + int const t = _content->GetItemCount (); + _content->InsertItem (t, std_to_wx ((*i)->summary ())); + if ((*i)->summary() == selected_summary) { + _content->SetItemState (t, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + } + + if (selected_summary.empty () && !content.empty ()) { + /* Select the first item of content if non was selected before */ + _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } +} + +void +FilmEditor::content_add_clicked (wxCommandEvent &) +{ + wxFileDialog* d = new wxFileDialog (this); + int const r = d->ShowModal (); + d->Destroy (); + + if (r != wxID_OK) { + return; + } + + boost::filesystem::path p (wx_to_std (d->GetPath())); + + if (ImageMagickContent::valid_file (p)) { + _film->add_content (shared_ptr (new ImageMagickContent (p))); + } else if (SndfileContent::valid_file (p)) { + _film->add_content (shared_ptr (new SndfileContent (p))); + } else { + _film->add_content (shared_ptr (new FFmpegContent (p))); + } + +} + +void +FilmEditor::content_remove_clicked (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (c) { + _film->remove_content (c); + } +} + +void +FilmEditor::content_activated (wxListEvent& ev) +{ + ContentList c = _film->content (); + assert (ev.GetIndex() >= 0 && size_t (ev.GetIndex()) < c.size ()); + + edit_content (c[ev.GetIndex()]); +} + +void +FilmEditor::content_edit_clicked (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (!c) { + return; + } + + edit_content (c); +} + +void +FilmEditor::edit_content (shared_ptr c) +{ + shared_ptr im = dynamic_pointer_cast (c); + if (im) { + ImageMagickContentDialog* d = new ImageMagickContentDialog (this, im); + d->ShowModal (); + d->Destroy (); + + im->set_video_length (d->video_length() * 24); + } +} + +void +FilmEditor::content_earlier_clicked (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (c) { + _film->move_content_earlier (c); + } +} + +void +FilmEditor::content_later_clicked (wxCommandEvent &) +{ + shared_ptr c = selected_content (); + if (c) { + _film->move_content_later (c); + } +} + +void +FilmEditor::content_selection_changed (wxListEvent &) +{ + setup_content_button_sensitivity (); + setup_content_information (); +} + +void +FilmEditor::setup_content_information () +{ + shared_ptr c = selected_content (); + if (!c) { + _content_information->SetValue (wxT ("")); + return; + } + + _content_information->SetValue (std_to_wx (c->information ())); +} + +void +FilmEditor::setup_content_button_sensitivity () +{ + _content_add->Enable (_generally_sensitive); + + shared_ptr selection = selected_content (); + + _content_edit->Enable (selection && _generally_sensitive && dynamic_pointer_cast (selection)); + _content_remove->Enable (selection && _generally_sensitive); + _content_earlier->Enable (selection && _generally_sensitive); + _content_later->Enable (selection && _generally_sensitive); +} + +shared_ptr +FilmEditor::selected_content () +{ + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return shared_ptr (); + } + + ContentList c = _film->content (); + if (s < 0 || size_t (s) >= c.size ()) { + return shared_ptr (); + } + + return c[s]; +} + void FilmEditor::setup_scaling_description () { @@@ -1402,17 -1352,18 +1406,18 @@@ int lines = 0; - d << wxString::Format ( - _("Original video is %dx%d (%.2f:1)\n"), - _film->video_size().width, _film->video_size().height, - float (_film->video_size().width) / _film->video_size().height - ); - - ++lines; - if (_film->size().width && _film->size().height) { ++ if (_film->video_size().width && _film->video_size().height) { + d << wxString::Format ( + _("Original video is %dx%d (%.2f:1)\n"), - _film->size().width, _film->size().height, - float (_film->size().width) / _film->size().height ++ _film->video_size().width, _film->video_size().height, ++ float (_film->video_size().width) / _film->video_size().height + ); + ++lines; + } Crop const crop = _film->crop (); if (crop.left || crop.right || crop.top || crop.bottom) { - libdcp::Size const cropped = _film->cropped_size (_film->size ()); + libdcp::Size const cropped = _film->cropped_size (_film->video_size ()); d << wxString::Format ( _("Cropped to %dx%d (%.2f:1)\n"), cropped.width, cropped.height, @@@ -1444,7 -1395,7 +1449,7 @@@ } for (int i = lines; i < 4; ++i) { - d << wxT (" \n"); + d << wxT ("\n "); } _scaling_description->SetLabel (d); diff --combined src/wx/film_viewer.cc index d18083694,dbbff3713..cba19c07c --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@@ -28,16 -28,13 +28,16 @@@ #include "lib/format.h" #include "lib/util.h" #include "lib/job_manager.h" -#include "lib/options.h" #include "lib/subtitle.h" #include "lib/image.h" #include "lib/scaler.h" #include "lib/exceptions.h" #include "lib/examine_content_job.h" #include "lib/filter.h" +#include "lib/player.h" +#include "lib/video_content.h" +#include "lib/ffmpeg_content.h" +#include "lib/imagemagick_content.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@@ -48,8 -45,6 +48,8 @@@ using std::max using std::cout; using std::list; using boost::shared_ptr; +using boost::dynamic_pointer_cast; +using boost::weak_ptr; using libdcp::Size; FilmViewer::FilmViewer (shared_ptr f, wxWindow* p) @@@ -101,23 -96,43 +101,23 @@@ FilmViewer::film_changed (Film::Propert break; case Film::CONTENT: { - DecodeOptions o; - o.decode_audio = false; - o.decode_subtitles = true; - o.video_sync = false; - - try { - _decoders = decoder_factory (_film, o); - } catch (StringError& e) { - error_dialog (this, wxString::Format (_("Could not open content file (%s)"), std_to_wx(e.what()).data())); - return; - } - - if (_decoders.video == 0) { - break; - } - _decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); - _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this)); - _decoders.video->set_subtitle_stream (_film->subtitle_stream()); calculate_sizes (); get_frame (); _panel->Refresh (); - _slider->Show (_film->content_type() == VIDEO); - _play_button->Show (_film->content_type() == VIDEO); _v_sizer->Layout (); break; } case Film::WITH_SUBTITLES: case Film::SUBTITLE_OFFSET: case Film::SUBTITLE_SCALE: + raw_to_display (); + _panel->Refresh (); + _panel->Update (); + break; case Film::SCALER: case Film::FILTERS: - update_from_raw (); - break; - case Film::SUBTITLE_STREAM: - if (_decoders.video) { - _decoders.video->set_subtitle_stream (_film->subtitle_stream ()); - } + case Film::CROP: + update_from_decoder (); break; default: break; @@@ -130,36 -145,32 +130,41 @@@ FilmViewer::set_film (shared_ptr if (_film == f) { return; } - + _film = f; + _raw_frame.reset (); + _display_frame.reset (); + _panel->Refresh (); + _panel->Update (); + if (!_film) { return; } + _player = f->player (); + _player->disable_audio (); + _player->disable_video_sync (); + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); + _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1, _2)); film_changed (Film::CONTENT); film_changed (Film::FORMAT); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); - film_changed (Film::SUBTITLE_STREAM); } void -FilmViewer::decoder_changed () +FilmViewer::update_from_decoder () { - if (_decoders.video == 0 || _decoders.video->seek_to_last ()) { + if (!_player || _player->seek (_player->last_video_time ())) { return; } @@@ -171,7 -182,7 +176,7 @@@ void FilmViewer::timer (wxTimerEvent &) { - if (!_film || !_decoders.video) { + if (!_player) { return; } @@@ -180,8 -191,8 +185,8 @@@ get_frame (); - if (_film->length()) { - int const new_slider_position = 4096 * _decoders.video->last_source_time() / (_film->length().get() / _film->source_frame_rate()); + if (_film->video_length()) { + int const new_slider_position = 4096 * _player->last_video_time() / (_film->video_length() / _film->video_frame_rate()); if (new_slider_position != _slider->GetValue()) { _slider->SetValue (new_slider_position); } @@@ -216,20 -227,20 +221,20 @@@ FilmViewer::paint_panel (wxPaintEvent & dc.DrawBitmap (sub_bitmap, _display_sub_position.x, _display_sub_position.y); } - if (_film_size.width < _panel_size.width) { + if (_out_size.width < _panel_size.width) { wxPen p (GetBackgroundColour ()); wxBrush b (GetBackgroundColour ()); dc.SetPen (p); dc.SetBrush (b); - dc.DrawRectangle (_film_size.width, 0, _panel_size.width - _film_size.width, _panel_size.height); + dc.DrawRectangle (_out_size.width, 0, _panel_size.width - _out_size.width, _panel_size.height); } - if (_film_size.height < _panel_size.height) { + if (_out_size.height < _panel_size.height) { wxPen p (GetBackgroundColour ()); wxBrush b (GetBackgroundColour ()); dc.SetPen (p); dc.SetBrush (b); - dc.DrawRectangle (0, _film_size.height, _panel_size.width, _panel_size.height - _film_size.height); + dc.DrawRectangle (0, _out_size.height, _panel_size.width, _panel_size.height - _out_size.height); } } @@@ -237,11 -248,11 +242,11 @@@ void FilmViewer::slider_moved (wxScrollEvent &) { - if (!_film || !_film->length() || !_decoders.video) { + if (!_film || !_player) { return; } - - if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / (4096 * _film->source_frame_rate()))) { + + if (_player->seek (_slider->GetValue() * _film->video_length() / (4096 * _film->video_frame_rate()))) { return; } @@@ -279,7 -290,7 +284,7 @@@ FilmViewer::raw_to_display ( return; } - boost::shared_ptr input = _raw_frame; + shared_ptr input = _raw_frame; pair const s = Filter::ffmpeg_strings (_film->filters()); if (!s.second.empty ()) { @@@ -295,7 -306,7 +300,7 @@@ when working out the scale that we are applying. */ - Size const cropped_size = _film->cropped_size (_film->size ()); + Size const cropped_size = _film->cropped_size (_film->video_size ()); Rect tx = subtitle_transformed_area ( float (_film_size.width) / cropped_size.width, @@@ -314,7 -325,7 +319,7 @@@ void FilmViewer::calculate_sizes () { - if (!_film) { + if (!_film || !_player) { return; } @@@ -364,7 -375,7 +369,7 @@@ FilmViewer::check_play_state ( } if (_play_button->GetValue()) { - _timer.Start (1000 / _film->source_frame_rate()); + _timer.Start (1000 / _film->video_frame_rate()); } else { _timer.Stop (); } @@@ -381,24 -392,21 +386,24 @@@ FilmViewer::process_video (shared_ptrpass ()) { + if (_player->pass ()) { /* We didn't get a frame before the decoder gave up, so clear our display frame. */ @@@ -433,12 -441,3 +438,12 @@@ FilmViewer::active_jobs_changed (bool a _play_button->Enable (!a); } +void +FilmViewer::film_content_changed (weak_ptr, int p) +{ + if (p == VideoContentProperty::VIDEO_LENGTH) { + /* Force an update to our frame */ + wxScrollEvent ev; + slider_moved (ev); + } +} diff --combined src/wx/film_viewer.h index 0ce8a526e,784434f6b..c81c65acd --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@@ -23,6 -23,7 +23,6 @@@ #include #include "lib/film.h" -#include "lib/decoder_factory.h" class wxToggleButton; class FFmpegPlayer; @@@ -32,25 -33,6 +32,25 @@@ class Subtitle /** @class FilmViewer * @brief A wx widget to view a preview of a Film. + * + * The film takes the following path through the viewer: + * + * 1. get_frame() asks our _player to decode some data. If it does, process_video() + * will be called. + * + * 2. process_video() takes the image and subtitle from the decoder (_raw_frame and _raw_sub) + * and calls raw_to_display(). + * + * 3. raw_to_display() copies _raw_frame to _display_frame, processing it and scaling it. + * + * 4. calling _panel->Refresh() and _panel->Update() results in paint_panel() being called; + * this creates frame_bitmap from _display_frame and blits it to the display. It also + * blits the subtitle, if required. + * + * update_from_decoder() asks the player to re-emit its current frame on the next pass(), and then + * starts from step #1. + * + * update_from_raw() starts at step #3, then calls _panel->Refresh and _panel->Update. */ class FilmViewer : public wxPanel { @@@ -61,7 -43,6 +61,7 @@@ public private: void film_changed (Film::Property); + void film_content_changed (boost::weak_ptr, int); void paint_panel (wxPaintEvent &); void panel_sized (wxSizeEvent &); void slider_moved (wxScrollEvent &); @@@ -71,13 -52,12 +71,13 @@@ void calculate_sizes (); void check_play_state (); void update_from_raw (); - void decoder_changed (); + void update_from_decoder (); void raw_to_display (); void get_frame (); void active_jobs_changed (bool); boost::shared_ptr _film; + boost::shared_ptr _player; wxSizer* _v_sizer; wxPanel* _panel; @@@ -85,9 -65,13 +85,12 @@@ wxToggleButton* _play_button; wxTimer _timer; - Decoders _decoders; boost::shared_ptr _raw_frame; boost::shared_ptr _raw_sub; boost::shared_ptr _display_frame; + /* The x offset at which we display the actual film content; this corresponds + to the film's padding converted to our coordinates. + */ int _display_frame_x; boost::shared_ptr _display_sub; Position _display_sub_position; diff --combined test/test.cc index 592bad836,d1bb400f9..4d25d50f8 --- a/test/test.cc +++ b/test/test.cc @@@ -40,7 -40,6 +40,7 @@@ #include "scaler.h" #include "ffmpeg_decoder.h" #include "sndfile_decoder.h" +#include "dcp_content_type.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include @@@ -143,7 -142,7 +143,7 @@@ BOOST_AUTO_TEST_CASE (film_metadata_tes BOOST_CHECK (f->filters ().empty()); f->set_name ("fred"); - BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); +// BOOST_CHECK_THROW (f->set_content ("jim"), OpenFileError); f->set_dcp_content_type (DCPContentType::from_pretty_name ("Short")); f->set_format (Format::from_nickname ("Flat")); f->set_left_crop (1); @@@ -156,7 -155,7 +156,7 @@@ f->set_filters (f_filters); f->set_trim_start (42); f->set_trim_end (99); - f->set_dcp_ab (true); + f->set_ab (true); f->write_metadata (); stringstream s; @@@ -178,25 -177,84 +178,51 @@@ BOOST_CHECK_EQUAL (g_filters.back(), Filter::from_id ("unsharp")); BOOST_CHECK_EQUAL (g->trim_start(), 42); BOOST_CHECK_EQUAL (g->trim_end(), 99); - BOOST_CHECK_EQUAL (g->dcp_ab(), true); + BOOST_CHECK_EQUAL (g->ab(), true); g->write_metadata (); BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0); } -BOOST_AUTO_TEST_CASE (stream_test) -{ - FFmpegAudioStream a ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - BOOST_CHECK_EQUAL (a.id(), 4); - BOOST_CHECK_EQUAL (a.sample_rate(), 44100); - BOOST_CHECK_EQUAL (a.channel_layout(), 1); - BOOST_CHECK_EQUAL (a.name(), "hello there world"); - BOOST_CHECK_EQUAL (a.to_string(), "ffmpeg 4 44100 1 hello there world"); - - SndfileStream e ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (e.sample_rate(), 44100); - BOOST_CHECK_EQUAL (e.channel_layout(), 1); - BOOST_CHECK_EQUAL (e.to_string(), "external 44100 1"); - - SubtitleStream s ("5 a b c", boost::optional (1)); - BOOST_CHECK_EQUAL (s.id(), 5); - BOOST_CHECK_EQUAL (s.name(), "a b c"); - - shared_ptr ff = audio_stream_factory ("ffmpeg 4 44100 1 hello there world", boost::optional (1)); - shared_ptr cff = dynamic_pointer_cast (ff); - BOOST_CHECK (cff); - BOOST_CHECK_EQUAL (cff->id(), 4); - BOOST_CHECK_EQUAL (cff->sample_rate(), 44100); - BOOST_CHECK_EQUAL (cff->channel_layout(), 1); - BOOST_CHECK_EQUAL (cff->name(), "hello there world"); - BOOST_CHECK_EQUAL (cff->to_string(), "ffmpeg 4 44100 1 hello there world"); - - shared_ptr fe = audio_stream_factory ("external 44100 1", boost::optional (1)); - BOOST_CHECK_EQUAL (fe->sample_rate(), 44100); - BOOST_CHECK_EQUAL (fe->channel_layout(), 1); - BOOST_CHECK_EQUAL (fe->to_string(), "external 44100 1"); -} - BOOST_AUTO_TEST_CASE (format_test) { Format::setup_formats (); Format const * f = Format::from_nickname ("Flat"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 185); +// BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 185); f = Format::from_nickname ("Scope"); BOOST_CHECK (f); - BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); +// BOOST_CHECK_EQUAL (f->ratio_as_integer(shared_ptr ()), 239); } + /* Test VariableFormat-based scaling of content */ + BOOST_AUTO_TEST_CASE (scaling_test) + { + shared_ptr film (new Film (test_film_dir ("scaling_test").string(), false)); + + /* 4:3 ratio */ + film->set_size (libdcp::Size (320, 240)); + + /* This format should preserve aspect ratio of the source */ + Format const * format = Format::from_id ("var-185"); + + /* We should have enough padding that the result is 4:3, + which would be 1440 pixels. + */ + BOOST_CHECK_EQUAL (format->dcp_padding (film), (1998 - 1440) / 2); + + /* This crops it to 1.291666667 */ + film->set_left_crop (5); + film->set_right_crop (5); + + /* We should now have enough padding that the result is 1.29166667, + which would be 1395 pixels. + */ + BOOST_CHECK_EQUAL (format->dcp_padding (film), rint ((1998 - 1395) / 2.0)); + } + BOOST_AUTO_TEST_CASE (util_test) { string t = "Hello this is a string \"with quotes\" and indeed without them"; @@@ -323,6 -381,17 +349,6 @@@ BOOST_AUTO_TEST_CASE (md5_digest_test BOOST_CHECK_THROW (md5_digest ("foobar"), OpenFileError); } -BOOST_AUTO_TEST_CASE (paths_test) -{ - shared_ptr f = new_test_film ("paths_test"); - f->set_directory ("build/test/a/b/c/d/e"); - - f->_content = "/foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "/foo/bar/baz"); - f->_content = "foo/bar/baz"; - BOOST_CHECK_EQUAL (f->content_path(), "build/test/a/b/c/d/e/foo/bar/baz"); -} - void do_remote_encode (shared_ptr frame, ServerDescription* description, shared_ptr locally_encoded) { @@@ -414,7 -483,7 +440,7 @@@ BOOST_AUTO_TEST_CASE (make_dcp_test { shared_ptr film = new_test_film ("make_dcp_test"); film->set_name ("test_film2"); - film->set_content ("../../../test/test.mp4"); +// film->set_content ("../../../test/test.mp4"); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->make_dcp (); @@@ -444,8 -513,8 +470,8 @@@ BOOST_AUTO_TEST_CASE (make_dcp_with_ran { shared_ptr film = new_test_film ("make_dcp_with_range_test"); film->set_name ("test_film3"); - film->set_content ("../../../test/test.mp4"); - film->examine_content (); +// film->set_content ("../../../test/test.mp4"); +// film->examine_content (); film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->set_trim_end (42); @@@ -606,44 -675,44 +632,44 @@@ BOOST_AUTO_TEST_CASE (audio_sampling_ra Config::instance()->set_allowed_dcp_frame_rates (afr); shared_ptr f = new_test_film ("audio_sampling_rate_test"); - f->set_source_frame_rate (24); +// f->set_source_frame_rate (24); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000); - f->set_source_frame_rate (23.976); +// f->set_source_frame_rate (23.976); f->set_dcp_frame_rate (best_dcp_frame_rate (23.976)); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - f->set_source_frame_rate (29.97); +// 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 (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952); - f->set_source_frame_rate (25); +// f->set_source_frame_rate (25); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); +// f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000); - f->set_source_frame_rate (25); +// f->set_source_frame_rate (25); f->set_dcp_frame_rate (24); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); +// f->set_content_audio_stream (shared_ptr (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_source_frame_rate (14.99); f->set_dcp_frame_rate (25); - f->set_content_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); +// f->set_content_audio_stream (shared_ptr (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. */ diff --combined wscript index 60b53a199,10c06a74d..3f3ae2019 --- a/wscript +++ b/wscript @@@ -3,7 -3,7 +3,7 @@@ import o import sys APPNAME = 'dvdomatic' - VERSION = '0.82pre' + VERSION = '0.84pre' def options(opt): opt.load('compiler_cxx') @@@ -56,7 -56,6 +56,7 @@@ def configure(conf) if not conf.options.static: conf.check_cfg(package = 'libdcp', atleast_version = '0.41', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True) + conf.check_cfg(package = 'libcxml', atleast_version = '0.01', args = '--cflags --libs', uselib_store = 'CXML', mandatory = True) conf.check_cfg(package = 'libavformat', args = '--cflags --libs', uselib_store = 'AVFORMAT', mandatory = True) conf.check_cfg(package = 'libavfilter', args = '--cflags --libs', uselib_store = 'AVFILTER', mandatory = True) conf.check_cfg(package = 'libavcodec', args = '--cflags --libs', uselib_store = 'AVCODEC', mandatory = True) @@@ -73,8 -72,6 +73,8 @@@ conf.env.HAVE_DCP = 1 conf.env.STLIB_DCP = ['dcp', 'asdcp-libdcp', 'kumu-libdcp'] conf.env.LIB_DCP = ['glibmm-2.4', 'xml++-2.6', 'ssl', 'crypto', 'bz2'] + conf.env.HAVE_CXML = 1 + conf.env.STLIB_CXML = ['cxml'] conf.env.HAVE_AVFORMAT = 1 conf.env.STLIB_AVFORMAT = ['avformat'] conf.env.HAVE_AVFILTER = 1