]> git.decadent.org.uk Git - videolink.git/commitdiff
Added support for mjpegtools 1.8 (now the default) and experimental support for ffmpe...
authorBen Hutchings <ben@decadent.org.uk>
Thu, 18 May 2006 22:09:14 +0000 (22:09 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 2 Nov 2008 23:39:58 +0000 (23:39 +0000)
video.cpp
video.hpp
webdvd.cpp

index a84fe74cb0b1e460f8ccf27af734a4e65c7eeb12..f6bcf6ad5d0c41596e1ad8f50f704da1711f1ad7 100644 (file)
--- a/video.cpp
+++ b/video.cpp
@@ -4,6 +4,7 @@ namespace video
 {
     const struct frame_params pal_params =
     {
+       "pal",
        720, 576,
        25, 1,
        59, 54
@@ -11,6 +12,7 @@ namespace video
 
     const struct frame_params ntsc_params =
     {
+       "ntsc",
        720, 480,
        30000, 1001,
        10, 11
index 8319ea09fc21bf95518b3b99a6cd37a1ed1aeb64..274eda622d508af3241c83d3d45c90511671e102 100644 (file)
--- a/video.hpp
+++ b/video.hpp
@@ -5,6 +5,7 @@ namespace video
 {
     struct frame_params
     {
+       const char * name;
        unsigned int width, height;
        unsigned int rate_numer, rate_denom;
        unsigned int pixel_ratio_width, pixel_ratio_height;
index 9c26c8fb20ef13df89ffc2ab9c6ea34a57c46282..5fd5e6ff8774a34bbb70345a2c8d32e5af05da3b 100644 (file)
@@ -68,6 +68,14 @@ using xpcom_support::check;
 
 namespace
 {
+    // We can try using any of these encoders to convert PNG to MPEG.
+    enum mpeg_encoder
+    {
+       mpeg_encoder_ffmpeg,         // ffmpeg - doesn't work yet
+       mpeg_encoder_mjpegtools_old, // mjpegtools before version 1.8
+       mpeg_encoder_mjpegtools_new  // mjpegtools from version 1.8
+    };
+
     struct rectangle
     {
        int left, top;     // inclusive
@@ -152,7 +160,8 @@ namespace
        webdvd_window(
            const video::frame_params & frame_params,
            const std::string & main_page_uri,
-           const std::string & output_dir);
+           const std::string & output_dir,
+           mpeg_encoder encoder);
 
        bool is_finished() const;
 
@@ -173,6 +182,7 @@ namespace
 
        video::frame_params frame_params_;
        std::string output_dir_;
+       mpeg_encoder encoder_;
        browser_widget browser_widget_;
        nsCOMPtr<nsIStyleSheet> stylesheet_;
 
@@ -194,9 +204,11 @@ namespace
     webdvd_window::webdvd_window(
        const video::frame_params & frame_params,
        const std::string & main_page_uri,
-       const std::string & output_dir)
+       const std::string & output_dir,
+       mpeg_encoder encoder)
            : frame_params_(frame_params),
              output_dir_(output_dir),
+             encoder_(encoder),
              stylesheet_(load_css("file://" WEBDVD_LIB_DIR "/webdvd.css")),
              pending_window_update_(false),
              pending_req_count_(0),
@@ -735,20 +747,45 @@ namespace
 
        {
            std::ostringstream command_stream;
-           command_stream << "pngtopnm "
-                          << background_temp_->get_name()
-                          << " | ppmtoy4m -v0 -n1 -F"
-                          << frame_params_.rate_numer
-                          << ":" << frame_params_.rate_denom
-                          << " -A" << frame_params_.pixel_ratio_width
-                          << ":" << frame_params_.pixel_ratio_height
-                          << (" -Ip -S420_mpeg2"
-                              " | mpeg2enc -v0 -f8 -a2 -o/dev/stdout"
-                              " | mplex -v0 -f8 -o/dev/stdout /dev/stdin"
-                              " | spumux -v0 -mdvd ")
-                          << state->spumux_temp.get_name()
-                          << " > "
-                          << contents_.menus[menu_num].vob_temp->get_name();
+           if (encoder_ == mpeg_encoder_ffmpeg)
+           {
+               command_stream
+                   << "ffmpeg"
+                   << " -f image2 -vcodec png -i "
+                   << background_temp_->get_name()
+                   << " -target " << frame_params_.name <<  "-dvd"
+                   << " -vcodec mpeg2video -an -y /dev/stdout"
+                   << " | spumux -v0 -mdvd " << state->spumux_temp.get_name()
+                   << " > " << contents_.menus[menu_num].vob_temp->get_name();
+           }
+           else
+           {
+               assert(encoder_ == mpeg_encoder_mjpegtools_old
+                      || encoder_ == mpeg_encoder_mjpegtools_new);
+               command_stream
+                   << "pngtopnm "
+                   << background_temp_->get_name()
+                   << " | ppmtoy4m -v0 -n1 -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
+                   << (" | mpeg2enc -v0 -f8 -a2 -o/dev/stdout"
+                       " | mplex -v0 -f8 -o/dev/stdout /dev/stdin"
+                       " | spumux -v0 -mdvd ")
+                   << state->spumux_temp.get_name()
+                   << " > "
+                   << contents_.menus[menu_num].vob_temp->get_name();
+           }
            std::string command(command_stream.str());
            const char * argv[] = {
                "/bin/sh", "-c", command.c_str(), 0
@@ -793,9 +830,11 @@ namespace
 
     void print_usage(std::ostream & stream, const char * command_name)
     {
-       stream << "Usage: " << command_name
-              << (" [gtk-options] [--video-std std-name]"
-                  " [--preview] menu-url [output-dir]\n");
+       stream <<
+           "Usage: " << command_name << " [gtk-options] [--preview]\n"
+           "           [--video-std {ntsc|pal|secam}]\n"
+           "           [--encoder {mjpegtools|mjpegtools-old}]\n"
+           "           menu-url [output-dir]\n");
     }
     
     void set_browser_preferences()
@@ -847,6 +886,7 @@ int main(int argc, char ** argv)
        bool preview_mode = false;
        std::string menu_url;
        std::string output_dir;
+       mpeg_encoder encoder = mpeg_encoder_mjpegtools_new;
 
        // Do initial option parsing.  We have to do this before
        // letting Gtk parse the arguments since we may need to spawn
@@ -923,6 +963,35 @@ int main(int argc, char ** argv)
                temp_file::keep_all(true);
                argi += 1;
            }
+           else if (std::strcmp(argv[argi], "--encoder") == 0)
+           {
+               if (argi + 1 == argc)
+               {
+                   std::cerr << "Missing argument to --encoder\n";
+                   print_usage(std::cerr, argv[0]);
+                   return EXIT_FAILURE;
+               }
+               if (std::strcmp(argv[argi + 1], "ffmpeg") == 0)
+               {
+                   encoder = mpeg_encoder_ffmpeg;
+               }
+               else if (std::strcmp(argv[argi + 1], "mjpegtools-old") == 0)
+               {
+                   encoder = mpeg_encoder_mjpegtools_old;
+               }
+               else if (std::strcmp(argv[argi + 1], "mjpegtools") == 0
+                        || std::strcmp(argv[argi + 1], "mjpegtools-new") == 0)
+               {
+                   encoder = mpeg_encoder_mjpegtools_new;
+               }
+               else
+               {
+                   std::cerr << "Invalid argument to --encoder\n";
+                   print_usage(std::cerr, argv[0]);
+                   return EXIT_FAILURE;
+               }
+               argi += 2;
+           }
            else if (argv[argi][0] == '-')
            {
                std::cerr << "Invalid option: " << argv[argi] << "\n";
@@ -965,7 +1034,7 @@ int main(int argc, char ** argv)
            null_prompt_service::install();
 
        // Run the browser/converter
-       webdvd_window window(frame_params, menu_url, output_dir);
+       webdvd_window window(frame_params, menu_url, output_dir, encoder);
        Gtk::Main::run(window);
 
        return ((preview_mode || window.is_finished())