From: Carl Hetherington Date: Tue, 1 Apr 2014 21:51:54 +0000 (+0100) Subject: Merge master. X-Git-Tag: v2.0.48~881 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=854f2e5bbb7ffb9758b823af87034033033f3cb8 Merge master. --- 854f2e5bbb7ffb9758b823af87034033033f3cb8 diff --cc ChangeLog index 065a10ae3,22fddbeb1..1d3ee28fa --- a/ChangeLog +++ b/ChangeLog @@@ -1,7 -1,56 +1,61 @@@ +2014-03-07 Carl Hetherington + + * Add subtitle view. + + 2014-04-01 Carl Hetherington + + * Basic support for separate left/right-eye files or directories + for 3D. + + 2014-03-30 Carl Hetherington + + * Version 1.66.9 released. + + 2014-03-30 Carl Hetherington + + * Version 1.66.8 released. + + * nl_NL translation from Theo Kooijmans. + + 2014-03-27 Carl Hetherington + + * Auto-save film metadata before starting DCP encode. + + 2014-03-25 Carl Hetherington + + * Add support for downloading Doremi server certificates. + + 2014-03-24 Carl Hetherington + + * Version 1.66.7 released. + + 2014-03-24 Carl Hetherington + + * Fix error on creating DCPs without audio. + + 2014-03-23 Carl Hetherington + + * Version 1.66.6 released. + + 2014-03-23 Carl Hetherington + + * Attempt to fix format string specifier error on Windows. + + * Version 1.66.5 released. + + 2014-03-22 Carl Hetherington + + * Version 1.66.4 released. + + 2014-03-22 Carl Hetherington + + * Allow specification of the video frame rate that a sound file + was prepared for. + + * Another attempt to fix colour conversion dialog strange behaviour + on OS X. ++>>>>>>> master + 2014-03-18 Carl Hetherington * Version 1.66.3 released. diff --cc src/lib/config.h index 68aae7414,a40e3680a..ee11dcadb --- a/src/lib/config.h +++ b/src/lib/config.h @@@ -262,12 -268,12 +268,12 @@@ public void set_default_dcp_content_type (DCPContentType const * t) { _default_dcp_content_type = t; - write (); + changed (); } - void set_dcp_metadata (libdcp::XMLMetadata m) { + void set_dcp_metadata (dcp::XMLMetadata m) { _dcp_metadata = m; - write (); + changed (); } void set_default_j2k_bandwidth (int b) { diff --cc src/lib/playlist.cc index c46e65d8b,a2bec83bb..1e8a3319c --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@@ -81,14 -81,21 +81,21 @@@ Playlist::maybe_sequence_video ( _sequencing_video = true; ContentList cl = _content; - DCPTime next; - Time next_left = 0; - Time next_right = 0; ++ DCPTime next_left; ++ DCPTime next_right; for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { - if (!dynamic_pointer_cast (*i)) { + shared_ptr vc = dynamic_pointer_cast (*i); + if (!vc) { continue; } - + - (*i)->set_position (next); - next = (*i)->end() + DCPTime::delta (); + if (vc->video_frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { + vc->set_position (next_right); - next_right = vc->end() + 1; ++ next_right = vc->end() + DCPTime::delta (); + } else { + vc->set_position (next_left); - next_left = vc->end() + 1; ++ next_left = vc->end() + DCPTime::delta (); + } } /* This won't change order, so it does not need a sort */ diff --cc src/lib/sndfile_content.cc index 71b549d51,a8388ab77..2d7fa1c1c --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@@ -1,5 -1,5 +1,5 @@@ /* -- Copyright (C) 2013 Carl Hetherington ++ Copyright (C) 2013-2014 Carl Hetherington 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 @@@ -165,3 -177,18 +165,4 @@@ SndfileContent::set_audio_mapping (Audi signal_changed (AudioContentProperty::AUDIO_MAPPING); } + -float -SndfileContent::video_frame_rate () const -{ - { - boost::mutex::scoped_lock lm (_mutex); - if (_video_frame_rate) { - return _video_frame_rate.get (); - } - } - - shared_ptr film = _film.lock (); - assert (film); - return film->video_frame_rate (); -} diff --cc src/lib/util.cc index 1339be73d,7a19790eb..40e9d9c2e --- a/src/lib/util.cc +++ b/src/lib/util.cc @@@ -1,5 -1,5 +1,5 @@@ /* -- Copyright (C) 2012 Carl Hetherington ++ Copyright (C) 2012-2014 Carl Hetherington Copyright (C) 2000-2007 Paul Davis This program is free software; you can redistribute it and/or modify @@@ -940,20 -1031,37 +940,55 @@@ divide_with_round (int64_t a, int64_t b } } +/** Return a user-readable string summarising the versions of our dependencies */ +string +dependency_version_summary () +{ + stringstream s; + s << N_("libopenjpeg ") << opj_version () << N_(", ") + << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ") + << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ") + << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ") + << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ") + << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ") + << MagickVersion << N_(", ") + << N_("libssh ") << ssh_version (0) << N_(", ") + << N_("libdcp ") << dcp::version << N_(" git ") << dcp::git_commit; + + return s.str (); +} ++ + ScopedTemporary::ScopedTemporary () + : _open (0) + { + _file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path (); + } + + ScopedTemporary::~ScopedTemporary () + { + close (); + boost::system::error_code ec; + boost::filesystem::remove (_file, ec); + } + + char const * + ScopedTemporary::c_str () const + { + return _file.string().c_str (); + } + + FILE* + ScopedTemporary::open (char const * params) + { + _open = fopen (c_str(), params); + return _open; + } + + void + ScopedTemporary::close () + { + if (_open) { + fclose (_open); + _open = 0; + } + } diff --cc src/lib/video_content.cc index 5864342a2,b704b6447..9edbc104a --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@@ -333,11 -330,13 +333,13 @@@ VideoContent::video_size_after_3d_spli switch (video_frame_type ()) { case VIDEO_FRAME_TYPE_2D: case VIDEO_FRAME_TYPE_3D_ALTERNATE: + case VIDEO_FRAME_TYPE_3D_LEFT: + case VIDEO_FRAME_TYPE_3D_RIGHT: return s; case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT: - return libdcp::Size (s.width / 2, s.height); + return dcp::Size (s.width / 2, s.height); case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM: - return libdcp::Size (s.width, s.height / 2); + return dcp::Size (s.width, s.height / 2); } assert (false); diff --cc src/lib/video_decoder.cc index 34299bd3c,2a33a8c3a..6a7a62b74 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@@ -114,18 -53,18 +114,24 @@@ VideoDecoder::video (shared_ptrsize().height / 2; - Video (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, same, frame); - Video (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, same, frame); + _decoded_video.push_back (ContentVideo (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, frame)); + _decoded_video.push_back (ContentVideo (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, frame)); break; } + case VIDEO_FRAME_TYPE_3D_LEFT: - Video (image, EYES_LEFT, same, frame); ++ _decoded_video.push_back (ContentVideo (image, EYES_LEFT, frame)); + break; + case VIDEO_FRAME_TYPE_3D_RIGHT: - Video (image, EYES_RIGHT, same, frame); ++ _decoded_video.push_back (ContentVideo (image, EYES_RIGHT, frame)); + break; + default: + assert (false); } - - _video_position = frame + 1; +} + +void +VideoDecoder::seek (ContentTime, bool) +{ + _decoded_video.clear (); } diff --cc src/lib/writer.cc index 202ec9a0f,639685149..8508a0716 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@@ -88,33 -83,37 +88,35 @@@ Writer::Writer (shared_ptr */ if (_film->three_d ()) { - _picture_asset.reset (new libdcp::StereoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ())); + _picture_mxf.reset (new dcp::StereoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1))); } else { - _picture_asset.reset (new libdcp::MonoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ())); + _picture_mxf.reset (new dcp::MonoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1))); } - _picture_asset->set_edit_rate (_film->video_frame_rate ()); - _picture_asset->set_size (_film->frame_size ()); - _picture_asset->set_interop (_film->interop ()); + _picture_mxf->set_size (_film->frame_size ()); if (_film->encrypted ()) { - _picture_asset->set_key (_film->key ()); + _picture_mxf->set_key (_film->key ()); } - _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); + _picture_mxf_writer = _picture_mxf->start_write ( + _film->internal_video_mxf_dir() / _film->internal_video_mxf_filename(), + _film->interop() ? dcp::INTEROP : dcp::SMPTE, + _first_nonexistant_frame > 0 + ); - _sound_mxf.reset (new dcp::SoundMXF (dcp::Fraction (_film->video_frame_rate(), 1), _film->audio_frame_rate (), _film->audio_channels ())); + if (_film->audio_channels ()) { - _sound_asset.reset (new libdcp::SoundAsset (_film->directory (), _film->audio_mxf_filename ())); - _sound_asset->set_edit_rate (_film->video_frame_rate ()); - _sound_asset->set_channels (_film->audio_channels ()); - _sound_asset->set_sampling_rate (_film->audio_frame_rate ()); - _sound_asset->set_interop (_film->interop ()); ++ _sound_mxf.reset (new dcp::SoundMXF (dcp::Fraction (_film->video_frame_rate(), 1), _film->audio_frame_rate (), _film->audio_channels ())); - if (_film->encrypted ()) { - _sound_mxf->set_key (_film->key ()); - } + if (_film->encrypted ()) { - _sound_asset->set_key (_film->key ()); ++ _sound_mxf->set_key (_film->key ()); + } - - /* Write the sound asset into the film directory so that we leave the creation + - /* Write the sound MXF into the film directory so that we leave the creation - of the DCP directory until the last minute. - */ - _sound_mxf_writer = _sound_mxf->start_write (_film->directory() / _film->audio_mxf_filename(), _film->interop() ? dcp::INTEROP : dcp::SMPTE); ++ /* Write the sound MXF into the film directory so that we leave the creation + of the DCP directory until the last minute. + */ - _sound_asset_writer = _sound_asset->start_write (); ++ _sound_mxf_writer = _sound_mxf->start_write (_film->directory() / _film->audio_mxf_filename(), _film->interop() ? dcp::INTEROP : dcp::SMPTE); + } _thread = new boost::thread (boost::bind (&Writer::thread, this)); @@@ -191,7 -190,9 +193,9 @@@ Writer::fake_write (int frame, Eyes eye void Writer::write (shared_ptr audio) { - _sound_mxf_writer->write (audio->data(), audio->frames()); - if (_sound_asset) { - _sound_asset_writer->write (audio->data(), audio->frames()); ++ if (_sound_mxf_writer) { ++ _sound_mxf_writer->write (audio->data(), audio->frames()); + } } /** This must be called from Writer::thread() with an appropriate lock held */ @@@ -367,9 -380,15 +371,11 @@@ Writer::finish ( terminate_thread (true); - _picture_asset_writer->finalize (); - if (_sound_asset_writer) { - _sound_asset_writer->finalize (); + _picture_mxf_writer->finalize (); - _sound_mxf_writer->finalize (); ++ if (_sound_mxf_writer) { ++ _sound_mxf_writer->finalize (); + } - int const frames = _last_written_frame + 1; - - _picture_asset->set_duration (frames); - /* Hard-link the video MXF into the DCP */ boost::filesystem::path video_from; video_from /= _film->internal_video_mxf_dir(); @@@ -387,25 -406,38 +393,27 @@@ _film->log()->log ("Hard-link failed; fell back to copying"); } - /* And update the asset */ - - _picture_asset->set_directory (_film->dir (_film->dcp_name ())); - _picture_asset->set_file_name (_film->video_mxf_filename ()); - /* Move the audio MXF into the DCP */ - boost::filesystem::path audio_to; - audio_to /= _film->dir (_film->dcp_name ()); - audio_to /= _film->audio_mxf_filename (); - - boost::filesystem::rename (_film->file (_film->audio_mxf_filename ()), audio_to, ec); - if (ec) { - throw FileError ( - String::compose (_("could not move audio MXF into the DCP (%1)"), ec.value ()), _film->file (_film->audio_mxf_filename ()) - ); - if (_sound_asset) { ++ if (_sound_mxf) { + boost::filesystem::path audio_to; + audio_to /= _film->dir (_film->dcp_name ()); + audio_to /= _film->audio_mxf_filename (); + + boost::filesystem::rename (_film->file (_film->audio_mxf_filename ()), audio_to, ec); + if (ec) { + throw FileError ( + String::compose (_("could not move audio MXF into the DCP (%1)"), ec.value ()), _film->file (_film->audio_mxf_filename ()) + ); + } - - _sound_asset->set_directory (_film->dir (_film->dcp_name ())); - _sound_asset->set_duration (frames); } - - libdcp::DCP dcp (_film->dir (_film->dcp_name())); - shared_ptr cpl ( - new libdcp::CPL ( - _film->dir (_film->dcp_name()), + dcp::DCP dcp (_film->dir (_film->dcp_name())); + + shared_ptr cpl ( + new dcp::CPL ( _film->dcp_name(), - _film->dcp_content_type()->libdcp_kind (), - frames, - _film->video_frame_rate () + _film->dcp_content_type()->libdcp_kind () ) ); @@@ -431,17 -454,19 +439,19 @@@ assert (job); job->sub (_("Computing image digest")); - _picture_asset->compute_digest (boost::bind (&Job::set_progress, job.get(), _1, false)); + _picture_mxf->hash (boost::bind (&Job::set_progress, job.get(), _1, false)); - job->sub (_("Computing audio digest")); - _sound_mxf->hash (boost::bind (&Job::set_progress, job.get(), _1, false)); - if (_sound_asset) { ++ if (_sound_mxf) { + job->sub (_("Computing audio digest")); - _sound_asset->compute_digest (boost::bind (&Job::set_progress, job.get(), _1, false)); ++ _sound_mxf->hash (boost::bind (&Job::set_progress, job.get(), _1, false)); + } - libdcp::XMLMetadata meta = Config::instance()->dcp_metadata (); + dcp::XMLMetadata meta = Config::instance()->dcp_metadata (); meta.set_issue_date_now (); - dcp.write_xml (_film->interop (), meta, _film->is_signed() ? make_signer () : shared_ptr ()); + dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, _film->is_signed() ? make_signer () : shared_ptr ()); _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) + String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 pushed to disk"), _full_written, _fake_written, _pushed_to_disk) ); } diff --cc src/lib/writer.h index af535c004,7af79a417..e817b1ca2 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@@ -55,8 -51,8 +55,6 @@@ public state but we use the data that is already on disk. */ FAKE, -- /** this is a repeat of the last frame to be written */ -- REPEAT } type; /** encoded data for FULL */ diff --cc src/lib/wscript index 00ed171a3,a50216f6d..433f50b3f --- a/src/lib/wscript +++ b/src/lib/wscript @@@ -32,7 -30,7 +32,8 @@@ sources = "" ffmpeg_examiner.cc film.cc filter.cc + frame_rate_change.cc + internet.cc image.cc image_content.cc image_decoder.cc diff --cc src/wx/properties_dialog.cc index 8c976f53a,28247bc33..801996efa --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@@ -33,25 -33,20 +33,19 @@@ using boost::shared_ptr using boost::lexical_cast; PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr film) - : wxDialog (parent, wxID_ANY, _("Film Properties"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) + : TableDialog (parent, _("Film Properties"), 2, false) , _film (film) { - _table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + add (_("Frames"), true); + _frames = add (new wxStaticText (this, wxID_ANY, wxT (""))); - add_label_to_sizer (_table, this, _("Frames"), true); - _frames = new wxStaticText (this, wxID_ANY, wxT ("")); - _table->Add (_frames, 1, wxALIGN_CENTER_VERTICAL); + add (_("Disk space required"), true); + _disk = add (new wxStaticText (this, wxID_ANY, wxT (""))); - add_label_to_sizer (_table, this, _("Disk space required"), true); - _disk = new wxStaticText (this, wxID_ANY, wxT ("")); - _table->Add (_disk, 1, wxALIGN_CENTER_VERTICAL); - - add_label_to_sizer (_table, this, _("Frames already encoded"), true); - _encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)); + add (_("Frames already encoded"), true); + _encoded = add (new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this))); _encoded->Finished.connect (boost::bind (&PropertiesDialog::layout, this)); - _table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL); - - - _frames->SetLabel (std_to_wx (lexical_cast (_film->time_to_video_frames (_film->length())))); + _frames->SetLabel (std_to_wx (lexical_cast (_film->length().frames (_film->video_frame_rate ())))); double const disk = double (_film->required_disk_space()) / 1073741824.0f; stringstream s; s << fixed << setprecision (1) << disk << wx_to_std (_("Gb")); diff --cc src/wx/screen_dialog.cc index 89249645a,b702ae0ad..0d46a46ec --- a/src/wx/screen_dialog.cc +++ b/src/wx/screen_dialog.cc @@@ -19,31 -19,37 +19,37 @@@ #include #include -#include +#include #include "lib/compose.hpp" + #include "lib/util.h" #include "screen_dialog.h" #include "wx_util.h" + #include "doremi_certificate_dialog.h" + #include "dolby_certificate_dialog.h" using std::string; using std::cout; using boost::shared_ptr; -ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, shared_ptr certificate) +ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, shared_ptr certificate) - : wxDialog (parent, wxID_ANY, std_to_wx (title)) + : TableDialog (parent, std_to_wx (title), 2, true) , _certificate (certificate) { - wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6); - table->AddGrowableCol (1, 1); + add ("Name", true); + _name = add (new wxTextCtrl (this, wxID_ANY, std_to_wx (name), wxDefaultPosition, wxSize (320, -1))); - add_label_to_sizer (table, this, "Name", true); - _name = new wxTextCtrl (this, wxID_ANY, std_to_wx (name), wxDefaultPosition, wxSize (320, -1)); - table->Add (_name, 1, wxEXPAND); + add ("Server manufacturer", true); + _manufacturer = add (new wxChoice (this, wxID_ANY)); - add_label_to_sizer (table, this, "Certificate", true); - _certificate_load = new wxButton (this, wxID_ANY, wxT ("Load from file...")); - table->Add (_certificate_load, 1, wxEXPAND); + add (_("Certificate"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _load_certificate = new wxButton (this, wxID_ANY, _("Load from file...")); + _download_certificate = new wxButton (this, wxID_ANY, _("Download")); + s->Add (_load_certificate, 1, wxEXPAND); + s->Add (_download_certificate, 1, wxEXPAND); + add (s); - table->AddSpacer (0); + add_spacer (); _certificate_text = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, wxSize (320, 256), wxTE_MULTILINE | wxTE_READONLY); if (certificate) { _certificate_text->SetValue (certificate->certificate ()); @@@ -83,19 -86,23 +86,23 @@@ ScreenDialog::certificate () cons } void - ScreenDialog::load_certificate () + ScreenDialog::load_certificate (boost::filesystem::path file) { - wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File")); + try { - _certificate.reset (new libdcp::Certificate (file)); ++ _certificate.reset (new dcp::Certificate (file)); + _certificate_text->SetValue (_certificate->certificate ()); - } catch (libdcp::MiscError& e) { ++ } catch (dcp::MiscError& e) { + error_dialog (this, String::compose ("Could not read certificate file (%1)", e.what())); + } + } + void + ScreenDialog::select_certificate () + { + wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File")); if (d->ShowModal () == wxID_OK) { - try { - _certificate.reset (new dcp::Certificate (boost::filesystem::path (wx_to_std (d->GetPath ())))); - _certificate_text->SetValue (_certificate->certificate ()); - } catch (dcp::MiscError& e) { - error_dialog (this, String::compose ("Could not read certificate file (%1)", e.what())); - } + load_certificate (boost::filesystem::path (wx_to_std (d->GetPath ()))); } - d->Destroy (); setup_sensitivity (); @@@ -105,5 -128,10 +128,10 @@@ voi ScreenDialog::setup_sensitivity () { wxButton* ok = dynamic_cast (FindWindowById (wxID_OK, this)); - ok->Enable (_certificate); + ok->Enable (_certificate.get ()); + + _download_certificate->Enable ( + _manufacturer->GetStringSelection() == _("Doremi") || + _manufacturer->GetStringSelection() == _("Dolby") + ); } diff --cc src/wx/screen_dialog.h index 0cd7d3c49,3601a8f6c..5c6d964b8 --- a/src/wx/screen_dialog.h +++ b/src/wx/screen_dialog.h @@@ -19,23 -19,30 +19,30 @@@ #include #include -#include +#include + #include "table_dialog.h" - class ScreenDialog : public wxDialog + class Progress; + + class ScreenDialog : public TableDialog { public: - ScreenDialog (wxWindow *, std::string, std::string name = "", boost::shared_ptr c = boost::shared_ptr ()); + ScreenDialog (wxWindow *, std::string, std::string name = "", boost::shared_ptr c = boost::shared_ptr ()); std::string name () const; - boost::shared_ptr certificate () const; + boost::shared_ptr certificate () const; private: - void load_certificate (); + void select_certificate (); + void load_certificate (boost::filesystem::path); + void download_certificate (); void setup_sensitivity (); wxTextCtrl* _name; - wxButton* _certificate_load; + wxChoice* _manufacturer; + wxButton* _load_certificate; + wxButton* _download_certificate; wxTextCtrl* _certificate_text; - boost::shared_ptr _certificate; + boost::shared_ptr _certificate; }; diff --cc src/wx/timecode.cc index 634a15625,ee5b5604b..1ab4b590b --- a/src/wx/timecode.cc +++ b/src/wx/timecode.cc @@@ -102,21 -102,21 +102,21 @@@ Timecode::set (DCPTime t, int fps checked_set (_seconds, lexical_cast (s)); checked_set (_frames, lexical_cast (f)); - _fixed->SetLabel (wxString::Format ("%02d:%02d:%02d.%02ld", h, m, s, f)); + _fixed->SetLabel (wxString::Format ("%02d:%02d:%02d.%02" wxLongLongFmtSpec "d", h, m, s, f)); } -Time +DCPTime Timecode::get (int fps) const { - Time t = 0; + DCPTime t; string const h = wx_to_std (_hours->GetValue ()); - t += lexical_cast (h.empty() ? "0" : h) * 3600 * TIME_HZ; + t += DCPTime::from_seconds (lexical_cast (h.empty() ? "0" : h) * 3600); string const m = wx_to_std (_minutes->GetValue()); - t += lexical_cast (m.empty() ? "0" : m) * 60 * TIME_HZ; + t += DCPTime::from_seconds (lexical_cast (m.empty() ? "0" : m) * 60); string const s = wx_to_std (_seconds->GetValue()); - t += lexical_cast (s.empty() ? "0" : s) * TIME_HZ; + t += DCPTime::from_seconds (lexical_cast (s.empty() ? "0" : s)); string const f = wx_to_std (_frames->GetValue()); - t += lexical_cast (f.empty() ? "0" : f) * TIME_HZ / fps; + t += DCPTime::from_seconds (lexical_cast (f.empty() ? "0" : f) / fps); return t; } diff --cc src/wx/timeline.cc index e1b507383,1858afee7..185abefeb --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@@ -99,8 -100,8 +100,8 @@@ public return dcpomatic::Rect ( time_x (content->position ()) - 8, - y_pos (_track) - 8, + y_pos (_track.get()) - 8, - content->length_after_trim () * _timeline.pixels_per_time_unit() + 16, + content->length_after_trim().seconds() * _timeline.pixels_per_second() + 16, _timeline.track_height() + 16 ); } @@@ -169,8 -172,8 +172,8 @@@ private wxDouble name_leading; gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading); - gc->Clip (wxRegion (time_x (position), y_pos (_track), len.seconds() * _timeline.pixels_per_second(), _timeline.track_height())); - gc->DrawText (name, time_x (position) + 12, y_pos (_track + 1) - name_height - 4); - gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len * _timeline.pixels_per_time_unit(), _timeline.track_height())); ++ gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second(), _timeline.track_height())); + gc->DrawText (name, time_x (position) + 12, y_pos (_track.get() + 1) - name_height - 4); gc->ResetClip (); } @@@ -431,55 -411,30 +434,30 @@@ Timeline::playlist_changed ( void Timeline::assign_tracks () { - list > video; - list > audio; - list > subtitle; - for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) { - shared_ptr v = dynamic_pointer_cast (*i); - if (v) { - video.push_back (v); - } - - shared_ptr a = dynamic_pointer_cast (*i); - if (a) { - audio.push_back (a); - } - - shared_ptr s = dynamic_pointer_cast (*i); - if (s) { - subtitle.push_back (s); - } - } - - _tracks = 0; - if (!video.empty ()) { - for (list >::iterator i = video.begin(); i != video.end(); ++i) { - (*i)->set_track (_tracks); + shared_ptr cv = dynamic_pointer_cast (*i); + if (!cv) { + continue; } - ++_tracks; - } -- - if (!subtitle.empty ()) { - for (list >::iterator i = subtitle.begin(); i != subtitle.end(); ++i) { - (*i)->set_track (_tracks); - } - ++_tracks; - } + - int const audio_start = _tracks; + shared_ptr content = cv->content(); - for (list >::iterator i = audio.begin(); i != audio.end(); ++i) { - shared_ptr acv_content = (*i)->content(); - - int t = audio_start; - while (1) { - list >::iterator j = audio.begin (); - while (j != audio.end()) { - if ((*j)->track() == t) { + int t = 0; - while (1) { ++ while (true) { + ViewList::iterator j = _views.begin(); + while (j != _views.end()) { + shared_ptr test = dynamic_pointer_cast (*j); + if (!test) { + ++j; + continue; + } + + shared_ptr test_content = test->content(); + + if (test && test->track() && test->track().get() == t) { bool const no_overlap = - (acv_content->position() < (*j)->content()->position() && acv_content->end() < (*j)->content()->position()) || - (acv_content->position() > (*j)->content()->end() && acv_content->end() > (*j)->content()->end()); + (content->position() < test_content->position() && content->end() < test_content->position()) || + (content->position() > test_content->end() && content->end() > test_content->end()); if (!no_overlap) { /* we have an overlap on track `t' */ diff --cc src/wx/timing_panel.cc index 3fcb9b175,5cefe318a..f33e052a1 --- a/src/wx/timing_panel.cc +++ b/src/wx/timing_panel.cc @@@ -83,37 -86,38 +86,37 @@@ TimingPanel::film_content_changed (int if (property == ContentProperty::POSITION) { if (content) { - _position->set (content->position (), _editor->film()->video_frame_rate ()); + _position->set (content->position (), film_video_frame_rate); } else { - _position->set (0, 24); + _position->set (DCPTime () , 24); } } else if ( property == ContentProperty::LENGTH || property == VideoContentProperty::VIDEO_FRAME_RATE || - property == VideoContentProperty::VIDEO_FRAME_TYPE || - property == SndfileContentProperty::VIDEO_FRAME_RATE + property == VideoContentProperty::VIDEO_FRAME_TYPE ) { if (content) { - _full_length->set (content->full_length (), _editor->film()->video_frame_rate ()); - _play_length->set (content->length_after_trim (), _editor->film()->video_frame_rate ()); + _full_length->set (content->full_length (), film_video_frame_rate); + _play_length->set (content->length_after_trim (), film_video_frame_rate); } else { - _full_length->set (0, 24); - _play_length->set (0, 24); + _full_length->set (DCPTime (), 24); + _play_length->set (DCPTime (), 24); } } else if (property == ContentProperty::TRIM_START) { if (content) { - _trim_start->set (content->trim_start (), _editor->film()->video_frame_rate ()); - _play_length->set (content->length_after_trim (), _editor->film()->video_frame_rate ()); + _trim_start->set (content->trim_start (), film_video_frame_rate); + _play_length->set (content->length_after_trim (), film_video_frame_rate); } else { - _trim_start->set (0, 24); - _play_length->set (0, 24); + _trim_start->set (DCPTime (), 24); + _play_length->set (DCPTime (), 24); } } else if (property == ContentProperty::TRIM_END) { if (content) { - _trim_end->set (content->trim_end (), _editor->film()->video_frame_rate ()); - _play_length->set (content->length_after_trim (), _editor->film()->video_frame_rate ()); + _trim_end->set (content->trim_end (), film_video_frame_rate); + _play_length->set (content->length_after_trim (), film_video_frame_rate); } else { - _trim_end->set (0, 24); - _play_length->set (0, 24); + _trim_end->set (DCPTime (), 24); + _play_length->set (DCPTime (), 24); } } @@@ -201,8 -208,12 +205,8 @@@ TimingPanel::set_video_frame_rate ( shared_ptr ic = dynamic_pointer_cast (c.front ()); if (ic) { ic->set_video_frame_rate (lexical_cast (wx_to_std (_video_frame_rate->GetValue ()))); - _set_video_frame_rate->Enable (false); } - shared_ptr sc = dynamic_pointer_cast (c.front ()); - if (sc) { - sc->set_video_frame_rate (lexical_cast (wx_to_std (_video_frame_rate->GetValue ()))); - } + _set_video_frame_rate->Enable (false); } } diff --cc src/wx/wscript index 45a5bc96d,a04df2d41..cd78f0649 --- a/src/wx/wscript +++ b/src/wx/wscript @@@ -35,7 -38,7 +38,8 @@@ sources = "" server_dialog.cc servers_list_dialog.cc subtitle_panel.cc + subtitle_view.cc + table_dialog.cc timecode.cc timeline.cc timeline_dialog.cc