make Item::set_position() do nothing if the position doesn't change
[ardour.git] / gtk2_ardour / export_video_dialog.cc
index c7ef6efd9ae344b972e12ba5a0f212591a7dc432..a9d0f99ad1246623199dd31d4e4d8cfc888dae11 100644 (file)
@@ -28,7 +28,8 @@
 #include <fcntl.h>
 
 #include <sigc++/bind.h>
-#include <libgen.h>
+
+#include <glib/gstdio.h>
 
 #include "pbd/error.h"
 #include "pbd/convert.h"
@@ -62,9 +63,9 @@ using namespace PBD;
 using namespace ARDOUR;
 using namespace VideoUtils;
 
-ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
+ExportVideoDialog::ExportVideoDialog (Session* s, TimeSelection &tme, bool range)
        : ArdourDialog (_("Export Video File "))
-       , editor (ed)
+       , export_range (tme)
        , outfn_path_label (_("File:"), Gtk::ALIGN_LEFT)
        , outfn_browse_button (_("Browse"))
        , invid_path_label (_("Video:"), Gtk::ALIGN_LEFT)
@@ -150,7 +151,14 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
        } else {
                insnd_combo.append_text (_("from the video's start to the video's end"));
        }
-       insnd_combo.set_active(0);
+       if (!export_range.empty()) {
+               insnd_combo.append_text (_("Selected range"));  // TODO show export_range.start() -> export_range.end_frame()
+       }
+       if (range) {
+               insnd_combo.set_active(2);
+       } else {
+               insnd_combo.set_active(0);
+       }
 
        outfn_path_entry.set_width_chars(38);
        outfn_path_entry.set_text (_session->session_directory().export_path() + G_DIR_SEPARATOR +"export.avi");
@@ -408,8 +416,8 @@ void
 ExportVideoDialog::finished ()
 {
        if (aborted) {
-               unlink(outfn_path_entry.get_text().c_str());
-               unlink (insnd.c_str());
+               ::g_unlink(outfn_path_entry.get_text().c_str());
+               ::g_unlink (insnd.c_str());
                Gtk::Dialog::response(RESPONSE_CANCEL);
        } else if (twopass && firstpass) {
                firstpass = false;
@@ -419,9 +427,9 @@ ExportVideoDialog::finished ()
                if (twopass_checkbox.get_active()) {
                        std::string outfn = outfn_path_entry.get_text();
                        std::string p2log = Glib::path_get_dirname (outfn) + G_DIR_SEPARATOR + "ffmpeg2pass";
-                       unlink (p2log.c_str());
+                       ::g_unlink (p2log.c_str());
                }
-               unlink (insnd.c_str());
+               ::g_unlink (insnd.c_str());
                Gtk::Dialog::response(RESPONSE_ACCEPT);
        }
 }
@@ -507,6 +515,10 @@ ExportVideoDialog::launch_export ()
                }
                end += av_offset;
        }
+       else if (insnd_combo.get_active_row_number() == 2) {
+               start = ARDOUR_UI::instance()->video_timeline->quantify_frames_to_apv(export_range.start());
+               end   = ARDOUR_UI::instance()->video_timeline->quantify_frames_to_apv(export_range.end_frame());
+       }
        if (end <= 0) {
                start = _session->current_start_frame();
                end   = _session->current_end_frame();
@@ -515,6 +527,15 @@ ExportVideoDialog::launch_export ()
        printf("audio export-range %lld -> %lld\n", start, end);
 #endif
 
+       const frameoffset_t vstart = ARDOUR_UI::instance()->video_timeline->get_offset();
+       const frameoffset_t vend   = vstart + ARDOUR_UI::instance()->video_timeline->get_duration();
+
+       if ( (start >= end) || (end < vstart) || (start > vend)) {
+               warning << _("Export Video: export-range does not include video.") << endmsg;
+               Gtk::Dialog::response(RESPONSE_CANCEL);
+               return;
+       }
+
        tsp->set_range (start, end);
        tsp->set_name ("mysession");
        tsp->set_range_id ("session");
@@ -551,13 +572,13 @@ ExportVideoDialog::launch_export ()
                if (gtk_events_pending()) {
                        gtk_main_iteration ();
                } else {
-                       usleep (10000);
+                       Glib::usleep (10000);
                }
        }
        audio_progress_connection.disconnect();
        status->finish ();
        if (status->aborted()) {
-               unlink (insnd.c_str());
+               ::g_unlink (insnd.c_str());
                Gtk::Dialog::response(RESPONSE_CANCEL);
                return;
        }
@@ -574,14 +595,14 @@ ExportVideoDialog::encode_pass (int pass)
        transcoder = new TranscodeFfmpeg(invid);
        if (!transcoder->ffexec_ok()) {
                /* ffmpeg binary was not found. TranscodeFfmpeg prints a warning */
-               unlink (insnd.c_str());
+               ::g_unlink (insnd.c_str());
                Gtk::Dialog::response(RESPONSE_CANCEL);
                return;
        }
        if (!transcoder->probe_ok()) {
                /* video input file can not be read */
                warning << _("Export Video: Video input file cannot be read.") << endmsg;
-         unlink (insnd.c_str());
+         ::g_unlink (insnd.c_str());
          Gtk::Dialog::response(RESPONSE_CANCEL);
          return;
        }
@@ -679,7 +700,7 @@ ExportVideoDialog::encode_pass (int pass)
                ffs["-an"] = "-y";
                ffs["-passlogfile"] =  Glib::path_get_dirname (outfn) + G_DIR_SEPARATOR + "ffmpeg2pass";
                ffs["-f"] = get_file_extension(invid).empty()?"mov":get_file_extension(invid);
-#ifdef _OS_WIN32
+#ifdef PLATFORM_WINDOWS
                outfn = "NUL";
 #else
                outfn = "/dev/null";
@@ -694,9 +715,14 @@ ExportVideoDialog::encode_pass (int pass)
        double duration_s  = 0;
 
        if (insnd_combo.get_active_row_number() == 0) {
+               /* session start to session end */
                framecnt_t duration_f = _session->current_end_frame() - _session->current_start_frame();
                duration_s = (double)duration_f / (double)_session->nominal_frame_rate();
+       } else if (insnd_combo.get_active_row_number() == 2) {
+               /* selected range */
+               duration_s = export_range.length() / (double)_session->nominal_frame_rate();
        } else {
+               /* video start to end */
                framecnt_t duration_f = ARDOUR_UI::instance()->video_timeline->get_duration();
                if (av_offset < 0 ) {
                        duration_f += av_offset;
@@ -712,10 +738,16 @@ ExportVideoDialog::encode_pass (int pass)
                transcoder->set_duration(duration_s * transcoder->get_fps());
        }
 
-       if (insnd_combo.get_active_row_number() == 0) {
-               const framepos_t start = _session->current_start_frame();
-               const framepos_t snend = _session->current_end_frame();
+       if (insnd_combo.get_active_row_number() == 0 || insnd_combo.get_active_row_number() == 2) {
+               framepos_t start, snend;
                const frameoffset_t vid_duration = ARDOUR_UI::instance()->video_timeline->get_duration();
+               if (insnd_combo.get_active_row_number() == 0) {
+                       start = _session->current_start_frame();
+                       snend = _session->current_end_frame();
+               } else {
+                       start = export_range.start();
+                       snend = export_range.end_frame();
+               }
 
 #if 0 /* DEBUG */
                printf("AV offset: %lld Vid-len: %lld Vid-end: %lld || start:%lld || end:%lld\n",
@@ -730,9 +762,17 @@ ExportVideoDialog::encode_pass (int pass)
                } else if (av_offset + vid_duration < snend) {
                        transcoder->set_leadinout(0, (snend - (av_offset + vid_duration)) / (double)_session->nominal_frame_rate());
                        transcoder->set_avoffset((av_offset - start) / (double)_session->nominal_frame_rate());
-               } else {
+               }
+#if 0
+               else if (start > av_offset) {
+                       std::ostringstream osstream; osstream << ((start - av_offset) / (double)_session->nominal_frame_rate());
+                       ffs["-ss"] = osstream.str();
+               }
+#endif
+               else {
                        transcoder->set_avoffset((av_offset - start) / (double)_session->nominal_frame_rate());
                }
+
        } else if (av_offset < 0) {
                /* from 00:00:00:00 to video-end */
                transcoder->set_avoffset(av_offset / (double)_session->nominal_frame_rate());