]> git.decadent.org.uk Git - videolink.git/blobdiff - generate_dvd.cpp
Moved -loop_input option before -i option so that it is actually effective.
[videolink.git] / generate_dvd.cpp
index d5185c2702e6fa88926800ac62c03429d6df6f86..e28659e1be467c225738b9044aa7c21b326eee8a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2005-6 Ben Hutchings <ben@decadent.org.uk>.
+// Copyright 2005-8 Ben Hutchings <ben@decadent.org.uk>.
 // See the file "COPYING" for licence details.
 
 #include <cerrno>
 #include <sstream>
 #include <stdexcept>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 #include <gdkmm/pixbuf.h>
 #include <glibmm/miscutils.h>
 #include <glibmm/spawn.h>
@@ -234,53 +238,36 @@ void dvd_generator::generate_menu_vob(unsigned index,
     if (!spumux_file)
        throw std::runtime_error("Failed to write control file for spumux");
 
+    std::string output_name(
+       temp_file_name(temp_dir_, "menu-%3d.mpeg", 1 + index));
+
     std::ostringstream command_stream;
-    unsigned frame_count(menu_duration_frames(frame_params_));
     if (encoder_ == mpeg_encoder_ffmpeg)
     {
-       for (unsigned i = 0; i != frame_count; ++i)
-       {
-           std::string frame_name(background_name);
-           frame_name.push_back('-');
-           frame_name.push_back('0' + i / 10);
-           frame_name.push_back('0' + i % 10);
-           if (symlink(background_name.c_str(), frame_name.c_str()) != 0)
-               throw std::runtime_error(
-                   std::string("symlink: ").append(std::strerror(errno)));
-       }
        command_stream <<
            "ffmpeg -f image2 -vcodec png"
            " -r " << frame_params_.rate_numer <<
            "/" << frame_params_.rate_denom <<
-           " -i " << background_name << "-%02d"
+           " -loop_input -i " << background_name <<
+           " -t " << menu_duration_seconds(frame_params_) <<
            " -target " << frame_params_.common_name <<  "-dvd"
            " -vcodec mpeg2video -aspect 4:3 -an -y /dev/stdout";
     }
     else
     {
-       assert(encoder_ == mpeg_encoder_mjpegtools_old
-              || encoder_ == mpeg_encoder_mjpegtools_new);
+       assert(encoder_ == mpeg_encoder_mjpegtools);
        command_stream
            << "pngtopnm " << background_name
-           << " | ppmtoy4m -v0 -n" << frame_count << " -F"
-           << frame_params_.rate_numer << ":" << frame_params_.rate_denom
+           << " | ppmtoy4m -v0 -n" << menu_duration_frames(frame_params_)
+           << " -F" << frame_params_.rate_numer << ":" << frame_params_.rate_denom
            << " -A" << frame_params_.pixel_ratio_width
            << ":" << frame_params_.pixel_ratio_height
-           << " -Ip ";
-       // The chroma subsampling keywords changed between
-       // versions 1.6.2 and 1.8 of mjpegtools.  There is no
-       // keyword that works with both.
-       if (encoder_ == mpeg_encoder_mjpegtools_old)
-           command_stream << "-S420_mpeg2";
-       else
-           command_stream << "-S420mpeg2";
-       command_stream <<
+           << " -Ip -S420mpeg2"
            " | mpeg2enc -v0 -f8 -a2 -o/dev/stdout"
            " | mplex -v0 -f8 -o/dev/stdout /dev/stdin";
     }
     command_stream
-       << " | spumux -v0 -mdvd " << spumux_name
-       << " > " << temp_file_name(temp_dir_, "menu-%3d.mpeg", 1 + index);
+       << " | spumux -v0 -mdvd " << spumux_name << " > " << output_name;
     std::string command(command_stream.str());
     const char * argv[] = {
        "/bin/sh", "-c", command.c_str(), 0
@@ -295,7 +282,9 @@ void dvd_generator::generate_menu_vob(unsigned index,
                     sigc::slot<void>(),
                     0, 0,
                     &command_result);
-    if (command_result != 0)
+    struct stat stat_buf;
+    if (command_result != 0 || stat(output_name.c_str(), &stat_buf) != 0
+       || stat_buf.st_size == 0)
        throw std::runtime_error("spumux pipeline failed");
 }