From ef1488deebfb1a8f84ea4c0c498e50b90b75ff3d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 14 Oct 2006 02:23:02 +0000 Subject: [PATCH] Increased number of frames in menu, defined a cell covering each menu, and moved still time from menu PGCs to cells. This should result in more reliable freeze-framing. --- generate_dvd.cpp | 53 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/generate_dvd.cpp b/generate_dvd.cpp index aa57775..398fdd1 100644 --- a/generate_dvd.cpp +++ b/generate_dvd.cpp @@ -72,6 +72,16 @@ namespace return Glib::build_filename(dir.get_name(), base_name); } + + // We would like to use just a single frame for the menu but this + // seems not to be legal or compatible. The minimum length of a + // cell is 0.4 seconds but I've seen a static menu using 12 frames + // on a "PAL" disc so let's say 0.5 seconds rounded down. + const char menu_duration_string[] = "0.5"; + unsigned menu_duration_frames(const video::frame_params & params) + { + return params.rate_numer / params.rate_denom / 2; + } } dvd_generator::dvd_generator(const video::frame_params & frame_params, @@ -188,23 +198,31 @@ void dvd_generator::generate_menu_vob(unsigned index, throw std::runtime_error("Failed to write control file for spumux"); std::ostringstream command_stream; + unsigned frame_count(menu_duration_frames(frame_params_)); if (encoder_ == mpeg_encoder_ffmpeg) { - command_stream - << "ffmpeg" - << " -f image2 -vcodec png -i " - << background_name - << " -target " << frame_params_.common_name << "-dvd" - << " -vcodec mpeg2video -aspect 4:3 -an -y /dev/stdout"; + 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 -i " << background_name << "-%02d" + " -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); command_stream - << "pngtopnm " - << background_name - << " | ppmtoy4m -v0 -n1 -F" + << "pngtopnm " << background_name + << " | ppmtoy4m -v0 -n" << frame_count << " -F" << frame_params_.rate_numer << ":" << frame_params_.rate_denom << " -A" << frame_params_.pixel_ratio_width << ":" << frame_params_.pixel_ratio_height @@ -290,7 +308,7 @@ void dvd_generator::generate(const std::string & output_dir) const // This is the first (title) menu, displayed when the // disc is first played. file << - " \n" + " \n" "
\n"
 		// Set a default target location if none is set.
 		// This covers first play and use of the "top menu"
@@ -301,7 +319,7 @@ void dvd_generator::generate(const std::string & output_dir) const
 	else
 	{
 	    file <<
-		"      \n"
+		"      \n"
 		"        
\n";
 	}
 
@@ -351,7 +369,13 @@ void dvd_generator::generate(const std::string & output_dir) const
 	    "        
\n" " \n"; + << "'>\n" + // Define a cell covering the whole menu and set a still + // time at the end of that, since it seems all players + // support that but some ignore a still time set on a PGC. + " \n" + " \n"; for (unsigned button_index = 0; button_index != this_menu.entries.size(); @@ -410,11 +434,6 @@ void dvd_generator::generate(const std::string & output_dir) const } file << - // Some DVD players don't seem to obey pause='inf' so make - // them loop. - " \n" - " jump cell 1;\n" - " \n" "
\n"; } -- 2.39.2