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
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;
video::frame_params frame_params_;
std::string output_dir_;
+ mpeg_encoder encoder_;
browser_widget browser_widget_;
nsCOMPtr<nsIStyleSheet> stylesheet_;
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),
{
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
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()
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
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";
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())