/*
- Copyright (C) 2010 Paul Davis
+ Copyright (C) 2010,2013 Paul Davis
Author: Robin Gareus <robin@gareus.org>
This program is free software; you can redistribute it and/or modify
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifdef WITH_VIDEOTIMELINE
-
#include <cstdio>
#include <string>
#include <sstream>
#include <fcntl.h>
#include <sigc++/bind.h>
-#include <libgen.h>
+
+#include <gtkmm/filechooserdialog.h>
+#include <gtkmm/stock.h>
+
+#include "pbd/gstdio_compat.h"
#include "pbd/error.h"
#include "pbd/convert.h"
#include "ardour_ui.h"
#include "gui_thread.h"
-#include "utils.h"
#include "opts.h"
#include "transcode_video_dialog.h"
-#include "video_copy_dialog.h"
#include "utils_videotl.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace Gtk;
using namespace std;
using namespace PBD;
using namespace ARDOUR;
+using namespace VideoUtils;
TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
: ArdourDialog (_("Transcode/Import Video File "))
, infn (infile)
, path_label (_("Output File:"), Gtk::ALIGN_LEFT)
, browse_button (_("Browse"))
- , transcode_button (_("Transcode Video\n And Import"))
- , copy_button (_("Copy Video\nFile Only"))
- , audio_button (_("Extract and\nImport Audio Only"))
+ , transcode_button (_("OK"))
, abort_button (_("Abort"))
, progress_label ()
, 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, 100, 10000, 10, 100, 0)
+ , bitrate_adjustment (2000, 500, 10000, 10, 100, 0)
, bitrate_spinner (bitrate_adjustment)
#if 1 /* tentative debug mode */
- , debug_checkbox (_("Debug Mode: Print ffmpeg Command and Output to stdout."))
+ , debug_checkbox (_("Debug Mode: Print ffmpeg command and output to stdout."))
#endif
{
set_session (s);
transcoder = new TranscodeFfmpeg(infile);
audiofile = "";
pending_audio_extract = false;
- pending_copy_file = false;
+ aborted = false;
set_name ("TranscodeVideoDialog");
- set_position (Gtk::WIN_POS_MOUSE);
set_modal (true);
set_skip_taskbar_hint (true);
set_resizable (false);
int w = 0, h = 0;
m_aspect = 4.0/3.0;
- AudioStreams as; as.clear();
+ TranscodeFfmpeg::FFAudioStreams as; as.clear();
path_hbox->pack_start (path_label, false, false, 3);
path_hbox->pack_start (path_entry, true, true, 3);
path_hbox->pack_start (browse_button, false, false, 3);
- browse_button.set_name ("PaddedButton");
path_entry.set_width_chars(38);
height_spinner.set_sensitive(false);
bitrate_spinner.set_sensitive(false);
- std::string dstdir = video_dest_dir(_session->session_directory().video_path(), Config->get_video_server_docroot());
+ std::string dstdir = video_dest_dir(_session->session_directory().video_path(), video_get_docroot(Config));
std::string dstfn = video_dest_file(dstdir, infile);
path_entry.set_text (dstfn);
- l = manage (new Label (_("<b>Info</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+ l = manage (new Label (_("<b>File Information</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
l->set_use_markup ();
options_box->pack_start (*l, false, true, 4);
-
+ bool ffok = false;
if (!transcoder->ffexec_ok()) {
- l = manage (new Label (_("No ffprobe or ffmpeg executables could be found on this system. Transcoding is not possible until you install those tools."), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+ l = manage (new Label (_("ffmpeg installation was not found. Video Import is not possible. See the Log window for more information."), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
l->set_line_wrap();
options_box->pack_start (*l, false, true, 4);
- transcode_button.set_sensitive(false);
aspect_checkbox.set_sensitive(false);
bitrate_checkbox.set_sensitive(false);
}
else if (!transcoder->probe_ok()) {
- l = manage (new Label (string_compose(_("Video file-info could not be read. Most likely '%1' is not a valid video-file. It could also be a rare unsupported video codec or format."), infn), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+ l = manage (new Label (string_compose(_("File-info can not be read. Most likely '%1' is not a valid video-file or an unsupported video codec or format."), infn), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
options_box->pack_start (*l, false, true, 4);
- transcode_button.set_sensitive(false);
aspect_checkbox.set_sensitive(false);
bitrate_checkbox.set_sensitive(false);
} else {
as = transcoder->get_audio();
m_aspect = transcoder->get_aspect();
+ if (w > 0 && h > 0 && transcoder->get_fps() > 0 && transcoder->get_duration() > 0) {
+ ffok = true;
+ }
+
Table* t = manage (new Table (4, 2));
t->set_spacings (4);
options_box->pack_start (*t, true, true, 4);
t->attach (*l, 1, 2, 1, 2);
}
- l = manage (new Label (_("<b>Options</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
+ l = manage (new Label (_("<b>Import Settings</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
l->set_use_markup ();
options_box->pack_start (*l, false, true, 4);
- Table* t = manage (new Table (4, 3));
+ if (ffok) {
+ video_combo.append_text(_("Reference from Current Location (Previously Transcoded Files Only)"));
+ video_combo.append_text(_("Import/Transcode Video to Session"));
+ video_combo.set_active(1);
+ if (as.size() > 0) {
+ video_combo.append_text(_("Do Not Import Video (Audio Import Only)"));
+ audio_combo.set_sensitive(true);
+ } else {
+ audio_combo.set_sensitive(false);
+ }
+ video_combo.set_sensitive(true);
+ transcode_button.set_sensitive(true);
+ path_entry.set_sensitive (true);
+ browse_button.set_sensitive (true);
+ } else if (as.size() > 0) {
+ video_combo.append_text(_("Do Not Import Video (Audio Import Only)"));
+ video_combo.set_active(0);
+ path_entry.set_text ("");
+
+ video_combo.set_sensitive(false);
+ audio_combo.set_sensitive(true);
+ transcode_button.set_sensitive(true);
+ path_entry.set_sensitive (false);
+ browse_button.set_sensitive (false);
+ } else {
+ video_combo.append_text(_("Do Not Import Video"));
+ video_combo.set_active(0);
+ path_entry.set_text ("");
+ video_combo.set_sensitive(false);
+ audio_combo.set_sensitive(false);
+ transcode_button.set_sensitive(false);
+ path_entry.set_sensitive (false);
+ browse_button.set_sensitive (false);
+ }
+
+ options_box->pack_start (video_combo, false, false, 4);
+
+ Table* t = manage (new Table (4, 4));
t->set_spacings (4);
options_box->pack_start (*t, true, true, 4);
l = manage (new Label (_("Scale Video: Width = "), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
t->attach (*l, 0, 1, 0, 1);
- scale_combo.set_name ("PaddedButton");
t->attach (scale_combo, 1, 2, 0, 1);
t->attach (aspect_checkbox, 2, 3, 0, 1);
t->attach (height_spinner, 3, 4, 0, 1);
l = manage (new Label (_("Extract Audio:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
t->attach (*l, 0, 1, 2, 3);
- audio_combo.set_name ("PaddedButton");
t->attach (audio_combo, 1, 4, 2, 3);
- audio_combo.append_text("No audio");
- if (as.size() > 0) {
- for (AudioStreams::iterator it = as.begin(); it < as.end(); ++it) {
+ 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);
+ } else {
+ audio_combo.append_text(_("Do Not Extract Audio"));
+ for (TranscodeFfmpeg::FFAudioStreams::iterator it = as.begin(); it < as.end(); ++it) {
audio_combo.append_text((*it).name);
}
}
audio_combo.set_active(0);
+ ltc_detect.set_sensitive (false);
#if 1 /* tentative debug mode */
options_box->pack_start (debug_checkbox, false, true, 4);
get_vbox()->pack_start (*vbox, false, false);
progress_box = manage (new VBox);
+ progress_box->set_spacing(6);
progress_box->pack_start (progress_label, false, false);
progress_box->pack_start (pbar, false, false);
progress_box->pack_start (abort_button, false, false);
get_vbox()->pack_start (*progress_box, false, false);
browse_button.signal_clicked().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::open_browse_dialog));
- copy_button.signal_clicked().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::prepare_copy));
- audio_button.signal_clicked().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::launch_audioonly));
transcode_button.signal_clicked().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::launch_transcode));
abort_button.signal_clicked().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::abort_clicked));
+ video_combo.signal_changed().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::video_combo_changed));
audio_combo.signal_changed().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::audio_combo_changed));
scale_combo.signal_changed().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::scale_combo_changed));
aspect_checkbox.signal_toggled().connect (sigc::mem_fun (*this, &TranscodeVideoDialog::aspect_checkbox_toggled));
update_bitrate();
- audio_button.set_sensitive(false);
-
cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
- get_action_area()->pack_start (audio_button, false, false);
- get_action_area()->pack_start (copy_button, false, false);
get_action_area()->pack_start (transcode_button, false, false);
show_all_children ();
progress_box->hide();
}
void
-TranscodeVideoDialog::update_progress (framecnt_t c, framecnt_t a)
+TranscodeVideoDialog::update_progress (samplecnt_t c, samplecnt_t a)
{
if (a == 0 || c > a) {
pbar.set_pulse_step(.5);
TranscodeVideoDialog::finished ()
{
if (aborted) {
- unlink(path_entry.get_text().c_str());
+ ::g_unlink(path_entry.get_text().c_str());
if (!audiofile.empty()) {
- unlink(audiofile.c_str());
+ ::g_unlink(audiofile.c_str());
}
Gtk::Dialog::response(RESPONSE_CANCEL);
} else {
- if (pending_audio_extract || pending_copy_file) {
+ if (pending_audio_extract) {
StartNextStage();
} else {
Gtk::Dialog::response(RESPONSE_ACCEPT);
}
void
-TranscodeVideoDialog::prepare_copy ()
+TranscodeVideoDialog::launch_audioonly ()
{
- dialog_progress_mode();
-#if 1 /* tentative debug mode */
- if (debug_checkbox.get_active()) {
- transcoder->set_debug(true);
- }
-#endif
-
if (audio_combo.get_active_row_number() == 0) {
- launch_copy();
- } else {
- aborted = false;
- pending_copy_file = true;
- StartNextStage.connect(*this, invalidator (*this), boost::bind (&TranscodeVideoDialog::launch_copy , this), gui_context());
- transcoder->Progress.connect(*this, invalidator (*this), boost::bind (&TranscodeVideoDialog::update_progress , this, _1, _2), gui_context());
- transcoder->Finished.connect(*this, invalidator (*this), boost::bind (&TranscodeVideoDialog::finished, this), gui_context());
- launch_extract();
+ finished();
+ return;
}
-}
-
-void
-TranscodeVideoDialog::launch_audioonly ()
-{
dialog_progress_mode();
- path_entry.set_text("");
#if 1 /* tentative debug mode */
if (debug_checkbox.get_active()) {
transcoder->set_debug(true);
}
#endif
- if (audio_combo.get_active_row_number() == 0) {
- return;
- }
transcoder->Progress.connect(*this, invalidator (*this), boost::bind (&TranscodeVideoDialog::update_progress , this, _1, _2), gui_context());
transcoder->Finished.connect(*this, invalidator (*this), boost::bind (&TranscodeVideoDialog::finished, this), gui_context());
launch_extract();
}
-void
-TranscodeVideoDialog::launch_copy ()
-{
- hide();
- VideoCopyDialog *video_copy_dialog;
- video_copy_dialog = new VideoCopyDialog(_session, infn);
- video_copy_dialog->setup_non_interactive_copy(path_entry.get_text());
- ResponseType r = (ResponseType) video_copy_dialog->run ();
- video_copy_dialog->hide();
- delete video_copy_dialog;
- Gtk::Dialog::response(r);
-}
-
void
TranscodeVideoDialog::launch_extract ()
{
- audiofile= path_entry.get_text() + ".wav"; /* TODO: mktemp & check if file exists in audiofiles */
- /* think: do_embed() vs do_import() - editor_videotimeline.cc
- * directly use _session->session_directory().sound_path() ?!
- */
+ audiofile= path_entry.get_text() + ".wav"; /* TODO: mktemp */
int audio_stream;
pending_audio_extract = false;
aborted = false;
audio_stream = audio_combo.get_active_row_number() -1;
progress_label.set_text (_("Extracting Audio.."));
- if (!transcoder->extract_audio(audiofile, _session->nominal_frame_rate(), audio_stream)) {
+ if (!transcoder->extract_audio(audiofile, _session->nominal_sample_rate(), audio_stream)) {
ARDOUR_UI::instance()->popup_error(_("Audio Extraction Failed."));
audiofile="";
Gtk::Dialog::response(RESPONSE_CANCEL);
{
vbox->hide();
cancel_button->hide();
- copy_button.hide();
transcode_button.hide();
pbar.set_size_request(300,-1);
progress_box->show();
void
TranscodeVideoDialog::launch_transcode ()
{
+ if (video_combo.get_active_row_number() != 1) {
+ launch_audioonly();
+ return;
+ }
std::string outfn = path_entry.get_text();
- if (!confirm_video_outfn(outfn, Config->get_video_server_docroot())) return;
+ if (!confirm_video_outfn(*this, outfn, video_get_docroot(Config))) return;
progress_label.set_text (_("Transcoding Video.."));
dialog_progress_mode();
#if 1 /* tentative debug mode */
if (scale_combo.get_active_row_number() == 0 ) {
scale_width =0;
} else {
- scale_width = atoi(scale_combo.get_active_text().c_str());
+ scale_width = atoi(scale_combo.get_active_text());
}
if (!aspect_checkbox.get_active()) {
scale_height = 0;
}
}
+void
+TranscodeVideoDialog::video_combo_changed ()
+{
+ const int i = video_combo.get_active_row_number();
+ if (i != 1) {
+ scale_combo.set_sensitive(false);
+ aspect_checkbox.set_sensitive(false);
+ height_spinner.set_sensitive(false);
+ bitrate_checkbox.set_sensitive(false);
+ bitrate_spinner.set_sensitive(false);
+ } else {
+ scale_combo.set_sensitive(true);
+ aspect_checkbox.set_sensitive(true);
+ height_spinner.set_sensitive(true);
+ bitrate_checkbox.set_sensitive(true);
+ bitrate_spinner.set_sensitive(true);
+ }
+ if (i == 2 && audio_combo.get_active_row_number() == 0) {
+ audio_combo.set_active(1);
+ } else {
+ //update LTC option sensitivity
+ audio_combo_changed ();
+ }
+}
+
void
TranscodeVideoDialog::audio_combo_changed ()
{
- bool use_audio = audio_combo.get_active_row_number() != 0;
- audio_button.set_sensitive(use_audio);
- if (use_audio) {
- copy_button.set_label(_("Copy File And\nExtract Audio"));
+ if (video_combo.get_active_row_number() == 2
+ && 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 {
- copy_button.set_label(_("Copy Video\nFile Only"));
+ ltc_detect.set_sensitive (false);
+ ltc_detect.set_active (false);
}
}
void
TranscodeVideoDialog::scale_combo_changed ()
{
- update_bitrate();
if (!aspect_checkbox.get_active()) {
int h;
if (scale_combo.get_active_row_number() == 0 ) {
h = transcoder->get_height();
} else {
- h = floor(atof(scale_combo.get_active_text().c_str()) / m_aspect);
+ h = floor(atof(scale_combo.get_active_text()) / m_aspect);
}
height_spinner.set_value(h);
}
+ update_bitrate();
}
void
if (bitrate_checkbox.get_active() || !transcoder->probe_ok()) { return; }
br *= transcoder->get_fps();
br *= height_spinner.get_value();
+
if (scale_combo.get_active_row_number() == 0 ) {
- br *= transcoder->get_height();
+ br *= transcoder->get_width();
} else {
- br *= atof(scale_combo.get_active_text().c_str());
+ br *= atof(scale_combo.get_active_text());
+ }
+ if (br != 0) {
+ bitrate_spinner.set_value(floor(br/10000.0)*10);
}
- bitrate_spinner.set_value(floor(br/10000.0)*10);
}
void
}
}
-#endif /* WITH_VIDEOTIMELINE */
+enum VtlTranscodeOption
+TranscodeVideoDialog::import_option() {
+ int i = video_combo.get_active_row_number();
+ return static_cast<VtlTranscodeOption>(i);
+}