mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
Merge branch 'master' of git.ardour.org:ardour/ardour
This commit is contained in:
commit
810e59d61a
18 changed files with 225 additions and 582 deletions
|
|
@ -136,16 +136,8 @@ AddVideoDialog::AddVideoDialog (Session* s)
|
|||
chooser.add_filter (matchall_filter);
|
||||
chooser.set_select_multiple (false);
|
||||
|
||||
/* file import options */
|
||||
import_combo.set_name ("PaddedButton");
|
||||
import_combo.append_text(_("Reference From Current Location"));
|
||||
import_combo.append_text(_("Hardlink or Copy to Session"));
|
||||
import_combo.append_text(_("Transcode to Session"));
|
||||
import_combo.set_active(2);
|
||||
|
||||
VBox* vboxfb = manage (new VBox);
|
||||
vboxfb->pack_start (chooser, true, true, 0);
|
||||
vboxfb->pack_start (import_combo, false, true, 4);
|
||||
|
||||
if (video_get_docroot(Config).size() > 0 &&
|
||||
Config->get_video_advanced_setup()) {
|
||||
|
|
@ -336,8 +328,7 @@ AddVideoDialog::import_option ()
|
|||
{
|
||||
int n = notebook.get_current_page ();
|
||||
if (n == 0 && Config->get_video_advanced_setup()) { return VTL_IMPORT_NONE; }
|
||||
int i = import_combo.get_active_row_number();
|
||||
return static_cast<VtlImportOption>(i);
|
||||
return VTL_IMPORT_TRANSCODE;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@
|
|||
|
||||
enum VtlImportOption {
|
||||
VTL_IMPORT_NONE = 0,
|
||||
VTL_IMPORT_COPY = 1,
|
||||
VTL_IMPORT_TRANSCODE = 2,
|
||||
VTL_IMPORT_TRANSCODE = 1,
|
||||
};
|
||||
|
||||
class AddVideoDialog : public ArdourDialog
|
||||
|
|
@ -74,7 +73,6 @@ class AddVideoDialog : public ArdourDialog
|
|||
|
||||
Gtk::CheckButton xjadeo_checkbox;
|
||||
Gtk::CheckButton set_session_fps_checkbox;
|
||||
Gtk::ComboBoxText import_combo;
|
||||
Gtk::Notebook notebook;
|
||||
Gtk::Button *ok_button;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
<!--menuitem action='importFromSession'/-->
|
||||
#ifdef WITH_VIDEOTIMELINE
|
||||
<menuitem action='OpenVideo'/>
|
||||
<menuitem action='CloseVideo'/>
|
||||
<menu name='Video' action='Video'>
|
||||
<menuitem action='StartVideoServer'/>
|
||||
<menuitem action='StopVideoServer'/>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ typedef uint64_t microseconds_t;
|
|||
#include "video_server_dialog.h"
|
||||
#include "add_video_dialog.h"
|
||||
#include "transcode_video_dialog.h"
|
||||
#include "video_copy_dialog.h"
|
||||
#include "system_exec.h" /* to launch video-server */
|
||||
#endif
|
||||
|
||||
|
|
@ -3420,29 +3419,30 @@ ARDOUR_UI::add_video (Gtk::Window* float_window)
|
|||
}
|
||||
|
||||
switch (add_video_dialog->import_option()) {
|
||||
case VTL_IMPORT_COPY:
|
||||
{
|
||||
VideoCopyDialog *video_copy_dialog;
|
||||
video_copy_dialog = new VideoCopyDialog(_session, path);
|
||||
//video_copy_dialog->setup_non_interactive_copy();
|
||||
ResponseType r = (ResponseType) video_copy_dialog->run ();
|
||||
video_copy_dialog->hide();
|
||||
if (r != RESPONSE_ACCEPT) { return; }
|
||||
path = video_copy_dialog->get_filename();
|
||||
delete video_copy_dialog;
|
||||
}
|
||||
break;
|
||||
case VTL_IMPORT_TRANSCODE:
|
||||
{
|
||||
TranscodeVideoDialog *transcode_video_dialog;
|
||||
transcode_video_dialog = new TranscodeVideoDialog (_session, path);
|
||||
ResponseType r = (ResponseType) transcode_video_dialog->run ();
|
||||
transcode_video_dialog->hide();
|
||||
if (r != RESPONSE_ACCEPT) { return; }
|
||||
path = transcode_video_dialog->get_filename();
|
||||
if (r != RESPONSE_ACCEPT) {
|
||||
delete transcode_video_dialog;
|
||||
return;
|
||||
}
|
||||
if (!transcode_video_dialog->get_audiofile().empty()) {
|
||||
editor->embed_audio_from_video(transcode_video_dialog->get_audiofile());
|
||||
}
|
||||
switch (transcode_video_dialog->import_option()) {
|
||||
case VTL_IMPORT_TRANSCODED:
|
||||
path = transcode_video_dialog->get_filename();
|
||||
local_file = true;
|
||||
break;
|
||||
case VTL_IMPORT_REFERENCE:
|
||||
break;
|
||||
default:
|
||||
delete transcode_video_dialog;
|
||||
return;
|
||||
}
|
||||
delete transcode_video_dialog;
|
||||
}
|
||||
break;
|
||||
|
|
@ -3451,12 +3451,6 @@ ARDOUR_UI::add_video (Gtk::Window* float_window)
|
|||
break;
|
||||
}
|
||||
|
||||
if (path.empty()) {
|
||||
/* may have been overriden by 'audio only import'
|
||||
* in transcode_video_dialog */
|
||||
path = add_video_dialog->file_name(local_file);;
|
||||
}
|
||||
|
||||
/* strip _session->session_directory().video_path() from video file if possible */
|
||||
if (local_file && !path.compare(0, _session->session_directory().video_path().size(), _session->session_directory().video_path())) {
|
||||
path=path.substr(_session->session_directory().video_path().size());
|
||||
|
|
@ -3484,6 +3478,19 @@ ARDOUR_UI::add_video (Gtk::Window* float_window)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::remove_video ()
|
||||
{
|
||||
video_timeline->close_session();
|
||||
editor->toggle_ruler_video(false);
|
||||
|
||||
/* delete session state */
|
||||
XMLNode* node = new XMLNode(X_("Videotimeline"));
|
||||
_session->add_extra_xml(*node);
|
||||
node = new XMLNode(X_("Videomonitor"));
|
||||
_session->add_extra_xml(*node);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::flush_videotimeline_cache (bool localcacheonly)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
void add_routes_thread ();
|
||||
#ifdef WITH_VIDEOTIMELINE
|
||||
void add_video (Gtk::Window* float_window);
|
||||
void remove_video ();
|
||||
void start_video_server_menu (Gtk::Window* float_window);
|
||||
bool start_video_server (Gtk::Window* float_window, bool popup_msg);
|
||||
void stop_video_server (bool ask_confirm=false);
|
||||
|
|
|
|||
|
|
@ -136,6 +136,9 @@ ARDOUR_UI::install_actions ()
|
|||
act = ActionManager::register_action (main_actions, X_("OpenVideo"), _("Open Video"),
|
||||
sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::add_video), (Gtk::Window*) 0));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (main_actions, X_("CloseVideo"), _("Remove Video"),
|
||||
sigc::mem_fun (*this, &ARDOUR_UI::remove_video));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (main_actions, X_("ExportVideo"), _("Export To Video File"),
|
||||
sigc::mem_fun (*editor, &PublicEditor::export_video));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
|
|
|||
|
|
@ -1455,7 +1455,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
void toggle_video_timeline_locked ();
|
||||
void set_video_timeline_locked (const bool);
|
||||
void queue_visual_videotimeline_update ();
|
||||
void embed_audio_from_video (std::string);
|
||||
void embed_audio_from_video (std::string, framepos_t n = 0);
|
||||
#endif
|
||||
|
||||
bool canvas_imageframe_item_view_event(GdkEvent* event, ArdourCanvas::Item*,ImageFrameView*);
|
||||
|
|
|
|||
|
|
@ -90,10 +90,9 @@ Editor::toggle_video_timeline_locked ()
|
|||
}
|
||||
|
||||
void
|
||||
Editor::embed_audio_from_video (std::string path)
|
||||
Editor::embed_audio_from_video (std::string path, framepos_t n)
|
||||
{
|
||||
vector<std::string> paths;
|
||||
framepos_t n = 0; /* -1: use file's timestamp - but br0ken with ffmpeg wav extract */
|
||||
paths.push_back(path);
|
||||
#if 0
|
||||
do_embed (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, n);
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
|
|||
virtual void set_xjadeo_sensitive (bool onoff) = 0;
|
||||
virtual int get_videotl_bar_height () const = 0;
|
||||
virtual void set_video_timeline_height (const int h) = 0;
|
||||
virtual void embed_audio_from_video (std::string) = 0;
|
||||
virtual void embed_audio_from_video (std::string, framepos_t n = 0) = 0;
|
||||
virtual void export_video () = 0;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -306,7 +306,6 @@ SystemExec::output_interposer()
|
|||
ReadStdout(data, bytesRead);/* EMIT SIGNAL */
|
||||
}
|
||||
Terminated();/* EMIT SIGNAL */
|
||||
terminate();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -409,6 +408,7 @@ SystemExec::make_argp(std::string args) {
|
|||
void
|
||||
SystemExec::terminate ()
|
||||
{
|
||||
::pthread_mutex_lock(&write_lock);
|
||||
close_stdin();
|
||||
if (pid) {
|
||||
::usleep(100000);
|
||||
|
|
@ -428,6 +428,8 @@ SystemExec::terminate ()
|
|||
|
||||
wait();
|
||||
if (thread_active) pthread_join(thread_id_tt, NULL);
|
||||
thread_active = false;
|
||||
::pthread_mutex_unlock(&write_lock);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -615,7 +617,6 @@ SystemExec::output_interposer()
|
|||
ReadStdout(rv, r);/* EMIT SIGNAL */
|
||||
}
|
||||
Terminated();/* EMIT SIGNAL */
|
||||
terminate();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -626,6 +627,7 @@ SystemExec::close_stdin()
|
|||
::close(pin[1]);
|
||||
::close(pout[0]);
|
||||
::close(pout[1]);
|
||||
pin[1] = - 1; // mark as closed
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -655,6 +657,7 @@ SystemExec::write_to_stdin(std::string d, size_t len)
|
|||
}
|
||||
c += r;
|
||||
}
|
||||
fsync(pin[1]);
|
||||
::pthread_mutex_unlock(&write_lock);
|
||||
return c;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ TranscodeFfmpeg::probe ()
|
|||
char **argp;
|
||||
argp=(char**) calloc(7,sizeof(char*));
|
||||
argp[0] = strdup(ffprobe_exe.c_str());
|
||||
argp[1] = strdup("-print_format"); // "-of" ; new version and avprobe compat but avprobe does not yet support csv
|
||||
argp[2] = strdup("csv"); // TODO use "csv=nk=0" and parse key/value pairs -> ffprobe version agnostic or parse XML or JSON key/value
|
||||
argp[1] = strdup("-print_format");
|
||||
argp[2] = strdup("csv=nk=0");
|
||||
argp[3] = strdup("-show_format");
|
||||
argp[4] = strdup("-show_streams");
|
||||
argp[5] = strdup(infile.c_str());
|
||||
|
|
@ -123,113 +123,100 @@ TranscodeFfmpeg::probe ()
|
|||
m_codec.clear();
|
||||
m_audio.clear();
|
||||
|
||||
#define PARSE_FRACTIONAL_FPS \
|
||||
{ \
|
||||
std::string::size_type pos; \
|
||||
m_fps = atof(value.c_str()); \
|
||||
pos = value.find_first_of('/'); \
|
||||
if (pos != std::string::npos) { \
|
||||
m_fps = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str()); \
|
||||
} \
|
||||
}
|
||||
|
||||
for (std::vector<std::vector<std::string> >::iterator i = lines.begin(); i != lines.end(); ++i) {
|
||||
if (i->at(0) == X_("format")) {
|
||||
/* format,filename,#streams,format-name,format-long-name,start-time,duration,size,bitrate */
|
||||
} else
|
||||
if (i->at(0) == X_("stream")) {
|
||||
/*--------- Stream format
|
||||
* stream,index,codec-name,codec-name-long,PROFILE,
|
||||
* codec_time_base,codec_tag_string,codec_tag[hex],
|
||||
* VIDEO:
|
||||
* width,height,has_b_frames,sample_aspect_ratio,display_aspect_ratio
|
||||
* pix_fmt,level,
|
||||
* timecode
|
||||
* AUDIO:
|
||||
* sample_fmt,sample_rate,channels,bits_per_sample
|
||||
*
|
||||
* all cont'd;
|
||||
* r_frame_rate,avg_frame_rate,time_base,start_time,duration,
|
||||
* bit_rate,nb_frames,nb_read_frames,nb_read_packets
|
||||
*
|
||||
*---------- Example
|
||||
* stream,0,mpeg2video,MPEG-2 video,video,1/50,[0][0][0][0],0x0000,720,576,1,16:15,4:3,yuv420p,8,00:02:30:00,0x1e0,25/1,25/1,1/90000,0.360000,N/A,7000000,N/A,N/A,N/A
|
||||
* stream,1,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,6,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x80,0/0,0/0,1/90000,0.280000,312.992000,448000,N/A,N/A,N/A
|
||||
* stream,2,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,2,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x82,0/0,0/0,1/90000,0.280000,312.992000,384000,N/A,N/A,N/A
|
||||
* stream,3,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,2,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x81,0/0,0/0,1/90000,0.280000,312.992000,192000,N/A,N/A,N/A
|
||||
*/
|
||||
if (i->at(4) == X_("video") && m_width == 0) {
|
||||
std::string::size_type pos;
|
||||
if (i->at(5) == X_("codec_type=video") && m_width == 0) {
|
||||
|
||||
m_width = atoi(i->at(8).c_str());
|
||||
m_height = atoi(i->at(9).c_str());
|
||||
m_codec = i->at(3) + " -- " + i->at(2);
|
||||
m_fps = atof(i->at(17).c_str());
|
||||
|
||||
pos = i->at(17).find_first_of('/');
|
||||
if (pos != std::string::npos) {
|
||||
m_fps = atof(i->at(17).substr(0, pos).c_str()) / atof(i->at(17).substr(pos+1).c_str());
|
||||
}
|
||||
|
||||
pos = i->at(12).find_first_of(':');
|
||||
m_aspect = 0;
|
||||
if (pos != std::string::npos && atof(i->at(12).substr(pos+1).c_str()) != 0) {
|
||||
m_aspect = atof(i->at(12).substr(0, pos).c_str()) / atof(i->at(12).substr(pos+1).c_str());
|
||||
}
|
||||
if (m_aspect == 0) {
|
||||
m_aspect = (double)m_width / (double)m_height;
|
||||
}
|
||||
for (std::vector<std::string>::iterator kv = i->begin(); kv != i->end(); ++kv) {
|
||||
const size_t kvsep = kv->find('=');
|
||||
if(kvsep == std::string::npos) continue;
|
||||
std::string key = kv->substr(0, kvsep);
|
||||
std::string value = kv->substr(kvsep + 1);
|
||||
|
||||
if (key == X_("width")) {
|
||||
m_width = atoi(value.c_str());
|
||||
} else if (key == X_("height")) {
|
||||
m_height = atoi(value.c_str());
|
||||
} else if (key == X_("codec_name")) {
|
||||
if (!m_codec.empty()) m_codec += " ";
|
||||
m_codec += value;
|
||||
} else if (key == X_("codec_long_name")) {
|
||||
if (!m_codec.empty()) m_codec += " ";
|
||||
m_codec += "[" + value + "]";
|
||||
} else if (key == X_("codec_tag_string")) {
|
||||
if (!m_codec.empty()) m_codec += " ";
|
||||
m_codec += "(" + value + ")";
|
||||
} else if (key == X_("r_frame_rate")) {
|
||||
PARSE_FRACTIONAL_FPS
|
||||
} else if (key == X_("time_base") && m_fps == 0) {
|
||||
PARSE_FRACTIONAL_FPS
|
||||
} else if (key == X_("timecode") && m_duration == 0) {
|
||||
int h,m,s; char f[7];
|
||||
if (sscanf(i->at(15).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
|
||||
if (sscanf(i->at(16).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
|
||||
m_duration = (ARDOUR::framecnt_t) floor(m_fps * (
|
||||
h * 3600.0
|
||||
+ m * 60.0
|
||||
+ s * 1.0
|
||||
+ atoi(f) / pow(10, strlen(f))
|
||||
));
|
||||
} else {
|
||||
m_duration = atof(i->at(21).c_str()) * m_fps;
|
||||
}
|
||||
|
||||
} else if (i->at(4) == X_("audio")) {
|
||||
AudioStream as;
|
||||
as.name = i->at(3) + " " + i->at(2) + " " + i->at(8) + " " + i->at(9);
|
||||
as.stream_id = i->at(1);
|
||||
as.channels = atoi(i->at(10).c_str());
|
||||
m_audio.push_back(as);
|
||||
|
||||
} else if (i->at(5) == X_("video") && m_width == 0) { /* new ffprobe */
|
||||
} else if (key == X_("duration_ts")) {
|
||||
m_duration = atof(value.c_str());
|
||||
} else if (key == X_("duration") && m_duration == 0 && m_fps != 0) {
|
||||
m_duration = atof(value.c_str()) * m_fps;
|
||||
} else if (key == X_("display_aspect_ratio")) {
|
||||
std::string::size_type pos;
|
||||
|
||||
m_width = atoi(i->at(9).c_str());
|
||||
m_height = atoi(i->at(10).c_str());
|
||||
m_codec = i->at(3) + " -- " + i->at(2);
|
||||
m_fps = atof(i->at(18).c_str());
|
||||
|
||||
pos = i->at(18).find_first_of('/');
|
||||
if (pos != std::string::npos) {
|
||||
m_fps = atof(i->at(18).substr(0, pos).c_str()) / atof(i->at(18).substr(pos+1).c_str());
|
||||
pos = value.find_first_of(':');
|
||||
if (pos != std::string::npos && atof(value.substr(pos+1).c_str()) != 0) {
|
||||
m_aspect = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos = i->at(13).find_first_of(':');
|
||||
m_aspect = 0;
|
||||
if (pos != std::string::npos && atof(i->at(13).substr(pos+1).c_str()) != 0) {
|
||||
m_aspect = atof(i->at(13).substr(0, pos).c_str()) / atof(i->at(13).substr(pos+1).c_str());
|
||||
}
|
||||
if (m_aspect == 0) {
|
||||
m_aspect = (double)m_width / (double)m_height;
|
||||
}
|
||||
|
||||
int h,m,s; char f[7];
|
||||
if (sscanf(i->at(17).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
|
||||
m_duration = (ARDOUR::framecnt_t) floor(m_fps * (
|
||||
h * 3600.0
|
||||
+ m * 60.0
|
||||
+ s * 1.0
|
||||
+ atoi(f) / pow(10, strlen(f))
|
||||
));
|
||||
} else if (atof(i->at(23).c_str()) != 0) {
|
||||
m_duration = atof(i->at(23).c_str());
|
||||
} else {
|
||||
m_duration = atof(i->at(24).c_str()) * m_fps;
|
||||
} else if (i->at(5) == X_("codec_type=audio")) { /* new ffprobe */
|
||||
AudioStream as;
|
||||
for (std::vector<std::string>::iterator kv = i->begin(); kv != i->end(); ++kv) {
|
||||
const size_t kvsep = kv->find('=');
|
||||
if(kvsep == std::string::npos) continue;
|
||||
std::string key = kv->substr(0, kvsep);
|
||||
std::string value = kv->substr(kvsep + 1);
|
||||
|
||||
if (key == X_("channels")) {
|
||||
as.channels = atoi(value.c_str());
|
||||
} else if (key == X_("index")) {
|
||||
as.stream_id = value;
|
||||
} else if (key == X_("codec_long_name")) {
|
||||
if (!as.name.empty()) as.name += " ";
|
||||
as.name += value;
|
||||
} else if (key == X_("codec_name")) {
|
||||
if (!as.name.empty()) as.name += " ";
|
||||
as.name += value;
|
||||
} else if (key == X_("sample_fmt")) {
|
||||
if (!as.name.empty()) as.name += " ";
|
||||
as.name += "FMT:" + value;
|
||||
} else if (key == X_("sample_rate")) {
|
||||
if (!as.name.empty()) as.name += " ";
|
||||
as.name += "SR:" + value;
|
||||
}
|
||||
|
||||
} else if (i->at(5) == X_("audio")) { /* new ffprobe */
|
||||
AudioStream as;
|
||||
as.name = i->at(3) + " " + i->at(2) + " " + i->at(9) + " " + i->at(10);
|
||||
as.stream_id = i->at(1);
|
||||
as.channels = atoi(i->at(11).c_str());
|
||||
}
|
||||
m_audio.push_back(as);
|
||||
}
|
||||
}
|
||||
|
|
@ -241,7 +228,7 @@ TranscodeFfmpeg::probe ()
|
|||
while (ffcmd && --timeout) usleep (1000); // wait until 'ffprobe' terminated.
|
||||
if (timeout == 0) return false;
|
||||
|
||||
#if 0 /* DEBUG */
|
||||
#if 1 /* DEBUG */
|
||||
printf("FPS: %f\n", m_fps);
|
||||
printf("Duration: %lu frames\n",(unsigned long)m_duration);
|
||||
printf("W/H: %ix%i\n",m_width, m_height);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
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
|
||||
|
|
@ -45,7 +45,6 @@
|
|||
#include "utils.h"
|
||||
#include "opts.h"
|
||||
#include "transcode_video_dialog.h"
|
||||
#include "video_copy_dialog.h"
|
||||
#include "utils_videotl.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -59,16 +58,14 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
, 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)
|
||||
, 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."))
|
||||
|
|
@ -79,7 +76,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
transcoder = new TranscodeFfmpeg(infile);
|
||||
audiofile = "";
|
||||
pending_audio_extract = false;
|
||||
pending_copy_file = false;
|
||||
aborted = false;
|
||||
|
||||
set_name ("TranscodeVideoDialog");
|
||||
set_position (Gtk::WIN_POS_MOUSE);
|
||||
|
|
@ -114,21 +111,21 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
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. Video Import is not possible until you install those tools. See the Log widow 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(_("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 {
|
||||
ffok = true;
|
||||
w = transcoder->get_width();
|
||||
h = transcoder->get_height();
|
||||
as = transcoder->get_audio();
|
||||
|
|
@ -179,10 +176,24 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
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>Video</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l->set_use_markup ();
|
||||
options_box->pack_start (*l, false, true, 4);
|
||||
|
||||
video_combo.set_name ("PaddedButton");
|
||||
video_combo.append_text(_("Do Not Import Video"));
|
||||
video_combo.append_text(_("Reference From Current Location"));
|
||||
if (ffok) {
|
||||
video_combo.append_text(_("Import/Transcode Video to Session"));
|
||||
video_combo.set_active(2);
|
||||
} else {
|
||||
video_combo.set_active(1);
|
||||
video_combo.set_sensitive(false);
|
||||
audio_combo.set_sensitive(false);
|
||||
}
|
||||
|
||||
options_box->pack_start (video_combo, false, false, 4);
|
||||
|
||||
Table* t = manage (new Table (4, 3));
|
||||
t->set_spacings (4);
|
||||
options_box->pack_start (*t, true, true, 4);
|
||||
|
|
@ -243,11 +254,10 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
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));
|
||||
|
|
@ -256,11 +266,7 @@ TranscodeVideoDialog::TranscodeVideoDialog (Session* s, std::string infile)
|
|||
|
||||
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();
|
||||
|
|
@ -305,7 +311,7 @@ TranscodeVideoDialog::finished ()
|
|||
}
|
||||
Gtk::Dialog::response(RESPONSE_CANCEL);
|
||||
} else {
|
||||
if (pending_audio_extract || pending_copy_file) {
|
||||
if (pending_audio_extract) {
|
||||
StartNextStage();
|
||||
} else {
|
||||
Gtk::Dialog::response(RESPONSE_ACCEPT);
|
||||
|
|
@ -313,66 +319,28 @@ TranscodeVideoDialog::finished ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TranscodeVideoDialog::prepare_copy ()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TranscodeVideoDialog::launch_audioonly ()
|
||||
{
|
||||
if (audio_combo.get_active_row_number() == 0) {
|
||||
finished();
|
||||
return;
|
||||
}
|
||||
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;
|
||||
|
|
@ -392,7 +360,6 @@ TranscodeVideoDialog::dialog_progress_mode ()
|
|||
{
|
||||
vbox->hide();
|
||||
cancel_button->hide();
|
||||
copy_button.hide();
|
||||
transcode_button.hide();
|
||||
pbar.set_size_request(300,-1);
|
||||
progress_box->show();
|
||||
|
|
@ -401,6 +368,10 @@ TranscodeVideoDialog::dialog_progress_mode ()
|
|||
void
|
||||
TranscodeVideoDialog::launch_transcode ()
|
||||
{
|
||||
if (video_combo.get_active_row_number() != 2) {
|
||||
launch_audioonly();
|
||||
return;
|
||||
}
|
||||
std::string outfn = path_entry.get_text();
|
||||
if (!confirm_video_outfn(outfn, video_get_docroot(Config))) return;
|
||||
progress_label.set_text (_("Transcoding Video.."));
|
||||
|
|
@ -443,22 +414,34 @@ TranscodeVideoDialog::launch_transcode ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TranscodeVideoDialog::video_combo_changed ()
|
||||
{
|
||||
int i = video_combo.get_active_row_number();
|
||||
if (i != 2) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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"));
|
||||
} else {
|
||||
copy_button.set_label(_("Copy Video\nFile Only"));
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
TranscodeVideoDialog::scale_combo_changed ()
|
||||
{
|
||||
update_bitrate();
|
||||
if (!aspect_checkbox.get_active()) {
|
||||
int h;
|
||||
if (scale_combo.get_active_row_number() == 0 ) {
|
||||
|
|
@ -468,6 +451,7 @@ TranscodeVideoDialog::scale_combo_changed ()
|
|||
}
|
||||
height_spinner.set_value(h);
|
||||
}
|
||||
update_bitrate();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -493,13 +477,16 @@ TranscodeVideoDialog::update_bitrate ()
|
|||
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());
|
||||
}
|
||||
if (br != 0) {
|
||||
bitrate_spinner.set_value(floor(br/10000.0)*10);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TranscodeVideoDialog::open_browse_dialog ()
|
||||
|
|
@ -521,4 +508,10 @@ TranscodeVideoDialog::open_browse_dialog ()
|
|||
}
|
||||
}
|
||||
|
||||
enum VtlTranscodeOption
|
||||
TranscodeVideoDialog::import_option() {
|
||||
int i = video_combo.get_active_row_number();
|
||||
return static_cast<VtlTranscodeOption>(i);
|
||||
}
|
||||
|
||||
#endif /* WITH_VIDEOTIMELINE */
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@
|
|||
|
||||
#include "transcode_ffmpeg.h"
|
||||
|
||||
enum VtlTranscodeOption {
|
||||
VTL_IMPORT_NO_VIDEO = 0,
|
||||
VTL_IMPORT_REFERENCE = 1,
|
||||
VTL_IMPORT_TRANSCODED = 2
|
||||
};
|
||||
|
||||
/** @class TranscodeVideoDialog
|
||||
* @brief dialog-box and controller for importing video-files
|
||||
*/
|
||||
|
|
@ -43,6 +49,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 ();
|
||||
|
||||
private:
|
||||
void on_show ();
|
||||
|
|
@ -50,18 +57,16 @@ class TranscodeVideoDialog : public ArdourDialog , public PBD::ScopedConnectionL
|
|||
void abort_clicked ();
|
||||
void scale_combo_changed ();
|
||||
void audio_combo_changed ();
|
||||
void video_combo_changed ();
|
||||
void aspect_checkbox_toggled ();
|
||||
void bitrate_checkbox_toggled ();
|
||||
void update_bitrate ();
|
||||
void launch_audioonly ();
|
||||
void launch_transcode ();
|
||||
void launch_extract ();
|
||||
void prepare_copy ();
|
||||
void launch_copy ();
|
||||
void dialog_progress_mode ();
|
||||
bool aborted;
|
||||
bool pending_audio_extract;
|
||||
bool pending_copy_file;
|
||||
std::string audiofile;
|
||||
std::string infn;
|
||||
double m_aspect;
|
||||
|
|
@ -76,8 +81,6 @@ class TranscodeVideoDialog : public ArdourDialog , public PBD::ScopedConnectionL
|
|||
Gtk::Entry path_entry;
|
||||
Gtk::Button browse_button;
|
||||
Gtk::Button transcode_button;
|
||||
Gtk::Button copy_button;
|
||||
Gtk::Button audio_button;
|
||||
|
||||
Gtk::VBox* vbox;
|
||||
Gtk::Button *cancel_button;
|
||||
|
|
@ -87,6 +90,7 @@ class TranscodeVideoDialog : public ArdourDialog , public PBD::ScopedConnectionL
|
|||
Gtk::Label progress_label;
|
||||
Gtk::ProgressBar pbar;
|
||||
|
||||
Gtk::ComboBoxText video_combo;
|
||||
Gtk::ComboBoxText scale_combo;
|
||||
Gtk::CheckButton aspect_checkbox;
|
||||
Gtk::Adjustment height_adjustment;
|
||||
|
|
|
|||
|
|
@ -1,270 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2010 Paul Davis
|
||||
Author: Robin Gareus <robin@gareus.org>
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifdef WITH_VIDEOTIMELINE
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sigc++/bind.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/convert.h"
|
||||
#include "gtkmm2ext/utils.h"
|
||||
#include "ardour/session_directory.h"
|
||||
#include "ardour/profile.h"
|
||||
#include "ardour/template_utils.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "gui_thread.h"
|
||||
|
||||
#include "utils_videotl.h"
|
||||
#include "utils.h"
|
||||
#include "opts.h"
|
||||
#include "video_copy_dialog.h"
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
VideoCopyDialog::VideoCopyDialog (Session* s, std::string infile)
|
||||
: ArdourDialog (_("Import Video File "))
|
||||
, infn (infile)
|
||||
, path_label (_("Output File:"), Gtk::ALIGN_LEFT)
|
||||
, browse_button (_("Browse"))
|
||||
, copy_button (_("Copy/Embed"))
|
||||
, abort_button (_("Abort"))
|
||||
, progress_label ()
|
||||
{
|
||||
set_session (s);
|
||||
autostart = false;
|
||||
|
||||
set_name ("VideoCopyDialog");
|
||||
set_position (Gtk::WIN_POS_MOUSE);
|
||||
set_modal (true);
|
||||
set_skip_taskbar_hint (true);
|
||||
set_resizable (false);
|
||||
p_connection = sigc::connection();
|
||||
|
||||
std::string dstdir = video_dest_dir(_session->session_directory().video_path(), video_get_docroot(Config));
|
||||
std::string dstfn = dstdir + G_DIR_SEPARATOR + Glib::path_get_basename(infile);
|
||||
path_entry.set_text (dstfn);
|
||||
|
||||
path_hbox = manage (new HBox);
|
||||
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);
|
||||
|
||||
browse_button.signal_clicked().connect (sigc::mem_fun (*this, &VideoCopyDialog::open_browse_dialog));
|
||||
copy_button.signal_clicked().connect (sigc::mem_fun (*this, &VideoCopyDialog::launch_copy));
|
||||
abort_button.signal_clicked().connect (sigc::mem_fun (*this, &VideoCopyDialog::abort_clicked));
|
||||
|
||||
progress_box = manage (new VBox);
|
||||
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 (*path_hbox, false, false);
|
||||
get_vbox()->pack_start (*progress_box, false, false);
|
||||
|
||||
|
||||
cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||
get_action_area()->pack_start (copy_button, false, false);
|
||||
show_all_children ();
|
||||
progress_box->hide();
|
||||
}
|
||||
|
||||
VideoCopyDialog::~VideoCopyDialog ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VideoCopyDialog::setup_non_interactive_copy (std::string destfn)
|
||||
{
|
||||
if (destfn.empty()) {
|
||||
std::string dstdir = video_dest_dir(_session->session_directory().video_path(), video_get_docroot(Config));
|
||||
outfn= dstdir + G_DIR_SEPARATOR + Glib::path_get_basename(infn);
|
||||
} else {
|
||||
outfn=destfn;
|
||||
}
|
||||
autostart=true;
|
||||
}
|
||||
|
||||
void
|
||||
VideoCopyDialog::on_show ()
|
||||
{
|
||||
if (autostart) {
|
||||
Glib::signal_timeout().connect_once (sigc::mem_fun(*this, &VideoCopyDialog::launch_copy), 200);
|
||||
}
|
||||
Dialog::on_show ();
|
||||
}
|
||||
|
||||
void
|
||||
VideoCopyDialog::abort_clicked ()
|
||||
{
|
||||
aborted = true;
|
||||
}
|
||||
|
||||
gint
|
||||
VideoCopyDialog::progress_timeout ()
|
||||
{
|
||||
if (p_tot == 0) {
|
||||
pbar.set_pulse_step(.5);
|
||||
pbar.pulse();
|
||||
return 1;
|
||||
}
|
||||
pbar.set_fraction ((double)p_cur / (double) p_tot);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void*
|
||||
video_copy_thread (void *arg)
|
||||
{
|
||||
VideoCopyDialog *cvd = static_cast<VideoCopyDialog*>(arg);
|
||||
cvd->do_copy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VideoCopyDialog::launch_copy ()
|
||||
{
|
||||
if (!autostart) {
|
||||
outfn = path_entry.get_text();
|
||||
}
|
||||
if (!confirm_video_outfn(outfn)) { return; }
|
||||
p_cur = 0; p_tot = 0;
|
||||
|
||||
p_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &VideoCopyDialog::progress_timeout), 80);
|
||||
|
||||
pbar.set_size_request(300,-1);
|
||||
progress_box->show();
|
||||
path_hbox->hide();
|
||||
cancel_button->hide();
|
||||
copy_button.hide();
|
||||
aborted = false;
|
||||
finished = false;
|
||||
|
||||
pthread_create(&thread, NULL, video_copy_thread ,this);
|
||||
while (!finished) {
|
||||
if (gtk_events_pending()) {
|
||||
gtk_main_iteration ();
|
||||
} else {
|
||||
usleep (10000);
|
||||
}
|
||||
}
|
||||
pthread_join(thread, NULL);
|
||||
|
||||
p_connection.disconnect();
|
||||
|
||||
if (aborted) {
|
||||
Gtk::Dialog::response(RESPONSE_CANCEL);
|
||||
} else {
|
||||
Gtk::Dialog::response(RESPONSE_ACCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VideoCopyDialog::do_copy ()
|
||||
{
|
||||
progress_label.set_text (_("Linking File."));
|
||||
|
||||
unlink (outfn.c_str());
|
||||
|
||||
bool try_hardlink = false; // Config->get_try_link_for_embed(); /* XXX */
|
||||
struct stat sb;
|
||||
if (lstat (infn.c_str(), &sb) == 0) {
|
||||
p_tot = sb.st_size;
|
||||
/* don't hardlink a symlink */
|
||||
if ((sb.st_mode&S_IFMT) == S_IFLNK) {
|
||||
try_hardlink = false;
|
||||
if (stat (infn.c_str(), &sb) == 0) {
|
||||
p_tot = sb.st_size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Can not stat() input file */
|
||||
warning << _("Can not read input file.") << endmsg;
|
||||
aborted=true;
|
||||
finished=true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !try_hardlink || link(infn.c_str(), outfn.c_str()) ) {
|
||||
/* hard-link failed , try copy */
|
||||
progress_label.set_text (_("Copying File."));
|
||||
int infd = open (infn.c_str(), O_RDONLY);
|
||||
int outfd = open (outfn.c_str(), O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||||
if (infd <0 || outfd <0) {
|
||||
if (infd != -1) close(infd);
|
||||
warning << _("Can not open files for copy.") << endmsg;
|
||||
aborted=true;
|
||||
finished=true;
|
||||
return;
|
||||
}
|
||||
char buffer[BUFSIZ];
|
||||
ssize_t nrb, ret;
|
||||
while ((nrb = read(infd, buffer, BUFSIZ)) > 0 && nrb != -1 ) {
|
||||
ret = write(outfd, buffer, nrb);
|
||||
if(ret != nrb || aborted) {
|
||||
warning << _("File copy failed.") << endmsg;
|
||||
unlink(outfn.c_str());
|
||||
aborted=true;
|
||||
finished=true;
|
||||
return;
|
||||
}
|
||||
p_cur+=ret;
|
||||
}
|
||||
}
|
||||
finished=true;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
VideoCopyDialog::open_browse_dialog ()
|
||||
{
|
||||
Gtk::FileChooserDialog dialog(_("Video File Copy Destination"), Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||
dialog.set_filename (path_entry.get_text());
|
||||
|
||||
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
||||
dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
|
||||
|
||||
int result = dialog.run();
|
||||
|
||||
if (result == Gtk::RESPONSE_OK) {
|
||||
std::string filename = dialog.get_filename();
|
||||
|
||||
if (filename.length()) {
|
||||
path_entry.set_text (filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_VIDEOTIMELINE */
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2010 Paul Davis
|
||||
Author: Robin Gareus <robin@gareus.org>
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifdef WITH_VIDEOTIMELINE
|
||||
|
||||
#ifndef __gtk_ardour_video_copy_dialog_h__
|
||||
#define __gtk_ardour_video_copy_dialog_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/template_utils.h"
|
||||
#include "ardour_dialog.h"
|
||||
|
||||
/** @class ExportVideoDialog
|
||||
* @brief dialog box and progress report for linking and copying video-files to the session.
|
||||
*/
|
||||
class VideoCopyDialog : public ArdourDialog , public PBD::ScopedConnectionList
|
||||
{
|
||||
public:
|
||||
/** @param infile absolute-path to the file to copy or link */
|
||||
VideoCopyDialog (ARDOUR::Session*, std::string infile);
|
||||
~VideoCopyDialog ();
|
||||
/** if set to true before calling dialog->show()
|
||||
* the dialog will only show the progres report and
|
||||
* start copying or linking immediatly
|
||||
* @param destfn destination path to copy or link the infile to.
|
||||
*/
|
||||
void setup_non_interactive_copy(std::string destfn ="");
|
||||
std::string get_filename () { return outfn; }
|
||||
|
||||
/*
|
||||
* Note: it's actually 'private' function but used
|
||||
* by the internal pthread, which only has a pointer
|
||||
* to this instance and thus can only access public fn.
|
||||
*/
|
||||
void do_copy ();
|
||||
|
||||
private:
|
||||
void on_show ();
|
||||
void abort_clicked ();
|
||||
bool aborted;
|
||||
bool autostart;
|
||||
bool finished;
|
||||
pthread_t thread;
|
||||
|
||||
void launch_copy ();
|
||||
std::string infn;
|
||||
std::string outfn;
|
||||
|
||||
gint progress_timeout ();
|
||||
sigc::connection p_connection;
|
||||
ssize_t p_cur;
|
||||
off_t p_tot;
|
||||
|
||||
void open_browse_dialog ();
|
||||
Gtk::Label path_label;
|
||||
Gtk::Entry path_entry;
|
||||
Gtk::Button browse_button;
|
||||
Gtk::Button *cancel_button;
|
||||
Gtk::Button copy_button;
|
||||
|
||||
Gtk::HBox* path_hbox;
|
||||
Gtk::VBox* progress_box;
|
||||
Gtk::Button abort_button;
|
||||
Gtk::Label progress_label;
|
||||
Gtk::ProgressBar pbar;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_video_copy_dialog_h__ */
|
||||
|
||||
#endif /* WITH_VIDEOTIMELINE */
|
||||
|
|
@ -41,7 +41,7 @@ VideoMonitor::VideoMonitor (PublicEditor *ed, std::string xjadeo_bin_path)
|
|||
clock_connection = sigc::connection();
|
||||
debug_enable = false;
|
||||
|
||||
process = new SystemExec(xjadeo_bin_path);
|
||||
process = new SystemExec(xjadeo_bin_path, X_("-R"));
|
||||
process->ReadStdout.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::parse_output, this, _1 ,_2), gui_context());
|
||||
process->Terminated.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::terminated, this), gui_context());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,12 +153,16 @@ VideoTimeLine::save_session ()
|
|||
void
|
||||
VideoTimeLine::close_session ()
|
||||
{
|
||||
if (video_duration == 0) {
|
||||
return;
|
||||
}
|
||||
close_video_monitor();
|
||||
save_session();
|
||||
|
||||
remove_frames();
|
||||
video_filename = "";
|
||||
video_duration = 0L;
|
||||
video_duration = 0;
|
||||
GuiUpdate("set-xjadeo-sensitive-off");
|
||||
}
|
||||
|
||||
/** load settings from session */
|
||||
|
|
@ -171,6 +175,11 @@ VideoTimeLine::set_session (ARDOUR::Session *s)
|
|||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
XMLNode* node = _session->extra_xml (X_("Videotimeline"));
|
||||
|
||||
if (!node || !node->property (X_("Filename"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
ARDOUR_UI::instance()->start_video_server((Gtk::Window*)0, false);
|
||||
|
||||
|
|
@ -210,7 +219,7 @@ VideoTimeLine::set_session (ARDOUR::Session *s)
|
|||
node = _session->extra_xml (X_("Videomonitor"));
|
||||
if (node) {
|
||||
const XMLProperty* prop = node->property (X_("active"));
|
||||
if (prop->value() == "yes" && found_xjadeo() && !video_filename.empty() && local_file) {
|
||||
if (prop && prop->value() == "yes" && found_xjadeo() && !video_filename.empty() && local_file) {
|
||||
open_video_monitor(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -523,8 +532,16 @@ VideoTimeLine::video_file_info (std::string filename, bool local)
|
|||
if (found_xjadeo() && local_file) {
|
||||
GuiUpdate("set-xjadeo-sensitive-on");
|
||||
if (vmonitor && vmonitor->is_started()) {
|
||||
#if 1
|
||||
/* xjadeo <= 0.6.4 has a bug where changing the video-file may segfauls
|
||||
* if the geometry changes to a different line-size alignment
|
||||
*/
|
||||
reopen_vmonitor = true;
|
||||
vmonitor->quit();
|
||||
#else
|
||||
vmonitor->set_fps(video_file_fps);
|
||||
vmonitor->open(video_filename);
|
||||
#endif
|
||||
}
|
||||
} else if (!local_file) {
|
||||
#if 1 /* temp debug/devel message */
|
||||
|
|
|
|||
|
|
@ -429,7 +429,6 @@ def build(bld):
|
|||
'transcode_ffmpeg.cc',
|
||||
'transcode_video_dialog.cc',
|
||||
'video_server_dialog.cc',
|
||||
'video_copy_dialog.cc',
|
||||
'utils_videotl.cc',
|
||||
'export_video_dialog.cc',
|
||||
'export_video_infobox.cc'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue