From 6c53ebc4c10e73450571710dc5be6add43f78c1d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 20 Sep 2015 18:37:39 +0200 Subject: basic GUI support to auto-align video by LTC. --- gtk2_ardour/ardour_ui.cc | 49 +++++++++++++++++++++++++++++++++-- gtk2_ardour/transcode_video_dialog.cc | 19 +++++++++++++- gtk2_ardour/transcode_video_dialog.h | 2 ++ 3 files changed, 67 insertions(+), 3 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index d13a3a2ad5..3424a105ae 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -77,6 +77,7 @@ #include "ardour/diskstream.h" #include "ardour/filename_extensions.h" #include "ardour/filesystem_paths.h" +#include "ardour/ltc_file_reader.h" #include "ardour/port.h" #include "ardour/plugin_manager.h" #include "ardour/process_thread.h" @@ -3958,6 +3959,9 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) return; } + std::string audio_from_video; + bool detect_ltc = false; + switch (add_video_dialog->import_option()) { case VTL_IMPORT_TRANSCODE: { @@ -3969,9 +3973,15 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) delete transcode_video_dialog; return; } - if (!transcode_video_dialog->get_audiofile().empty()) { + + audio_from_video = transcode_video_dialog->get_audiofile(); + + if (!audio_from_video.empty() && transcode_video_dialog->detect_ltc()) { + detect_ltc = true; + } + else if (!audio_from_video.empty()) { editor->embed_audio_from_video( - transcode_video_dialog->get_audiofile(), + audio_from_video, video_timeline->get_offset(), (transcode_video_dialog->import_option() != VTL_IMPORT_NO_VIDEO) ); @@ -4004,6 +4014,7 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) } video_timeline->set_update_session_fps(auto_set_session_fps); + if (video_timeline->video_file_info(path, local_file)) { XMLNode* node = new XMLNode(X_("Videotimeline")); node->add_property (X_("Filename"), path); @@ -4017,6 +4028,40 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) _session->add_extra_xml (*node); _session->set_dirty (); + if (!audio_from_video.empty() && detect_ltc) { + std::vector ltc_seq; + + try { + /* TODO ask user about TV standard (LTC alignment if any) */ + LTCFileReader ltcr (audio_from_video, video_timeline->get_video_file_fps()); + /* TODO ASK user which channel: 0 .. ltcr->channels() - 1 */ + + ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC frames to decode*/ 15); + + /* TODO seek near end of file, and read LTC until end. + * if it fails to find any LTC frames, scan complete file + * + * calculate drift of LTC compared to video-duration, + * ask user for reference (timecode from start/mid/end) + */ + } catch (...) { + // LTCFileReader will have written error messages + } + + ::g_unlink(audio_from_video.c_str()); + + if (ltc_seq.size() == 0) { + PBD::error << _("No LTC detected, video will not be aligned.") << endmsg; + } else { + /* the very first TC in the file is somteimes not aligned properly */ + int i = ltc_seq.size() -1; + ARDOUR::frameoffset_t video_start_offset = + _session->nominal_frame_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec); + PBD::info << string_compose (_("Align video-start to %1 [samples]"), video_start_offset) << endmsg; + video_timeline->set_offset(video_start_offset); + } + } + _session->maybe_update_session_range( std::max(video_timeline->get_offset(), (ARDOUR::frameoffset_t) 0), std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::frameoffset_t) 0)); diff --git a/gtk2_ardour/transcode_video_dialog.cc b/gtk2_ardour/transcode_video_dialog.cc index ac3d4808fc..3aa35a5c1b 100644 --- a/gtk2_ardour/transcode_video_dialog.cc +++ b/gtk2_ardour/transcode_video_dialog.cc @@ -63,6 +63,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile) , aspect_checkbox (_("Height = ")) , height_adjustment (128, 0, 1920, 1, 16, 0) , height_spinner (height_adjustment) + , ltc_detect (_("Extract LTC from audio and align video")) , bitrate_checkbox (_("Manual Override")) , bitrate_adjustment (2000, 500, 10000, 10, 100, 0) , bitrate_spinner (bitrate_adjustment) @@ -219,7 +220,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile) options_box->pack_start (video_combo, false, false, 4); - Table* t = manage (new Table (4, 3)); + Table* t = manage (new Table (4, 4)); t->set_spacings (4); options_box->pack_start (*t, true, true, 4); @@ -254,6 +255,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile) t->attach (*l, 0, 1, 2, 3); audio_combo.set_name ("PaddedButton"); t->attach (audio_combo, 1, 4, 2, 3); + t->attach (ltc_detect, 1, 4, 3, 4); if (as.size() == 0) { audio_combo.append_text(_("No Audio Track Present")); audio_combo.set_sensitive(false); @@ -264,6 +266,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile) } } audio_combo.set_active(0); + ltc_detect.set_sensitive (false); #if 1 /* tentative debug mode */ options_box->pack_start (debug_checkbox, false, true, 4); @@ -461,6 +464,9 @@ TranscodeVideoDialog::video_combo_changed () } if (i == 2 && audio_combo.get_active_row_number() == 0) { audio_combo.set_active(1); + } else { + //update LTC option sensitivity + audio_combo_changed (); } } @@ -471,6 +477,17 @@ TranscodeVideoDialog::audio_combo_changed () && audio_combo.get_active_row_number() == 0) { audio_combo.set_active(1); + ltc_detect.set_sensitive (false); + ltc_detect.set_active (false); + } + + if (video_combo.get_active_row_number() != 2 + && audio_combo.get_active_row_number() > 0) + { + ltc_detect.set_sensitive (true); + } else { + ltc_detect.set_sensitive (false); + ltc_detect.set_active (false); } } diff --git a/gtk2_ardour/transcode_video_dialog.h b/gtk2_ardour/transcode_video_dialog.h index 835b32d82c..9acd1284a5 100644 --- a/gtk2_ardour/transcode_video_dialog.h +++ b/gtk2_ardour/transcode_video_dialog.h @@ -48,6 +48,7 @@ class TranscodeVideoDialog : public ArdourDialog , public PBD::ScopedConnectionL std::string get_filename () { return path_entry.get_text(); } std::string get_audiofile () { return audiofile; } VtlTranscodeOption import_option (); + bool detect_ltc () { return ltc_detect.get_active (); } private: void on_show (); @@ -94,6 +95,7 @@ class TranscodeVideoDialog : public ArdourDialog , public PBD::ScopedConnectionL Gtk::Adjustment height_adjustment; Gtk::SpinButton height_spinner; Gtk::ComboBoxText audio_combo; + Gtk::CheckButton ltc_detect; Gtk::CheckButton bitrate_checkbox; Gtk::Adjustment bitrate_adjustment; Gtk::SpinButton bitrate_spinner; -- cgit v1.2.3