summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2015-09-20 18:37:39 +0200
committerRobin Gareus <robin@gareus.org>2015-09-20 18:37:39 +0200
commit6c53ebc4c10e73450571710dc5be6add43f78c1d (patch)
tree39bbdc9fc739dd8f903b33d9a6785cf76f7bf292 /gtk2_ardour
parent8bee256e4f004488e8998b4418d919fd9803c021 (diff)
basic GUI support to auto-align video by LTC.
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/ardour_ui.cc49
-rw-r--r--gtk2_ardour/transcode_video_dialog.cc19
-rw-r--r--gtk2_ardour/transcode_video_dialog.h2
3 files changed, 67 insertions, 3 deletions
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<LTCFileReader::LTCMap> 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;