From 90012acc26c4a8210c4bce3dac69a09309cce9f8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 27 Nov 2005 20:49:30 +0000 Subject: [PATCH] Added more video standard parameters and organised them into structures. Removed -geometry hack and added a --video-std option accepting a standard name in upper or lower case. --- video.cpp | 18 ++++++++++ video.hpp | 12 ++++--- webdvd.cpp | 101 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 video.cpp diff --git a/video.cpp b/video.cpp new file mode 100644 index 0000000..a84fe74 --- /dev/null +++ b/video.cpp @@ -0,0 +1,18 @@ +#include "video.hpp" + +namespace video +{ + const struct frame_params pal_params = + { + 720, 576, + 25, 1, + 59, 54 + }; + + const struct frame_params ntsc_params = + { + 720, 480, + 30000, 1001, + 10, 11 + }; +} diff --git a/video.hpp b/video.hpp index 7b76b17..8319ea0 100644 --- a/video.hpp +++ b/video.hpp @@ -3,10 +3,14 @@ namespace video { - const int pal_oscan_width = 720; - const int pal_oscan_height = 576; - const int ntsc_oscan_width = 720; - const int ntsc_oscan_height = 480; + struct frame_params + { + unsigned int width, height; + unsigned int rate_numer, rate_denom; + unsigned int pixel_ratio_width, pixel_ratio_height; + }; + + extern const frame_params pal_params, ntsc_params; } #endif // !INC_VIDEO_HPP diff --git a/webdvd.cpp b/webdvd.cpp index 4d951ee..ee44118 100644 --- a/webdvd.cpp +++ b/webdvd.cpp @@ -133,7 +133,7 @@ namespace class WebDvdWindow : public Gtk::Window { public: - WebDvdWindow(int width, int height); + WebDvdWindow(const video::frame_params & frame_params); void add_page(const std::string & uri); private: @@ -148,7 +148,7 @@ namespace enum ResourceType { page_resource, video_resource }; typedef std::pair ResourceEntry; - int width_, height_; + video::frame_params frame_params_; BrowserWidget browser_widget_; nsCOMPtr stylesheet_; std::queue page_queue_; @@ -161,13 +161,13 @@ namespace std::auto_ptr link_state_; }; - WebDvdWindow::WebDvdWindow(int width, int height) - : width_(width), height_(height), + WebDvdWindow::WebDvdWindow(const video::frame_params & frame_params) + : frame_params_(frame_params), stylesheet_(load_css("file://" WEBDVD_LIB_DIR "/webdvd.css")), loading_(false), pending_req_count_(0) { - set_default_size(width, height); + set_default_size(frame_params_.width, frame_params_.height); add(browser_widget_); browser_widget_.show(); browser_widget_.signal_net_state().connect( @@ -306,7 +306,8 @@ namespace std::cout << "saving " << filename << std::endl; Gdk::Pixbuf::create(Glib::RefPtr(window), window->get_colormap(), - 0, 0, 0, 0, width_, height_) + 0, 0, 0, 0, + frame_params_.width, frame_params_.height) ->save(filename, "png"); } @@ -352,10 +353,10 @@ namespace { state.reset(new link_state); - state->diff_pixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, - true, // has_alpha - 8, // bits_per_sample - width_, height_); + state->diff_pixbuf = Gdk::Pixbuf::create( + Gdk::COLORSPACE_RGB, + true, 8, // has_alpha, bits_per_sample + frame_params_.width, frame_params_.height); char spumux_filename[20]; std::sprintf(spumux_filename, @@ -377,7 +378,9 @@ namespace state->link_changing = false; } - rectangle window_rect = { 0, 0, width_, height_ }; + rectangle window_rect = { + 0, 0, frame_params_.width, frame_params_.height + }; for (/* no initialisation */; state->links_it != state->links_end; @@ -755,38 +758,78 @@ namespace } } + const video::frame_params & lookup_frame_params(const char * str) + { + assert(str); + static const struct { const char * str; bool is_ntsc; } + known_strings[] = { + { "NTSC", true }, + { "ntsc", true }, + { "PAL", false }, + { "pal", false }, + // For DVD purposes, SECAM can be treated identically to PAL. + { "SECAM", false }, + { "secam", false } + }; + for (std::size_t i = 0; + i != sizeof(known_strings)/sizeof(known_strings[0]); + ++i) + if (std::strcmp(str, known_strings[i].str) == 0) + return known_strings[i].is_ntsc ? + video::ntsc_params : video::pal_params; + throw std::runtime_error( + std::string("Invalid video standard: ").append(str)); + } + } // namespace int main(int argc, char ** argv) { - // Get dimensions - int width = video::pal_oscan_width, height = video::pal_oscan_height; - for (int i = 1; i < argc - 1; ++i) - if (std::strcmp(argv[i], "-geometry") == 0) - { - std::sscanf(argv[i + 1], "%dx%d", &width, &height); - break; - } - // A depth of 24 results in 8 bits each for RGB components, which - // translates into "enough" bits for YUV components. - const int depth = 24; - try { + // Determine video frame parameters. + video::frame_params frame_params = video::pal_params; + for (int argi = 1; argi != argc; ++argi) + { + if (std::strcmp(argv[argi], "--") == 0) + break; + if (std::strcmp(argv[argi], "--video-std") == 0) + { + if (argi + 1 == argc) + { + std::cerr << "Missing argument to --video-std\n"; + return EXIT_FAILURE; + } + frame_params = lookup_frame_params(argv[argi + 1]); + break; + } + } + // Spawn Xvfb and set env variables so that Xlib will use it - FrameBuffer fb(width, height, depth); + // Use 8 bits each for RGB components, which should translate into + // "enough" bits for YUV components. + FrameBuffer fb(frame_params.width, frame_params.height, 3 * 8); setenv("XAUTHORITY", fb.get_x_authority().c_str(), true); setenv("DISPLAY", fb.get_x_display().c_str(), true); // Initialise Gtk and Mozilla Gtk::Main kit(argc, argv); BrowserWidget::init(); - - WebDvdWindow window(width, height); - for (int argi = 1; argi < argc; ++argi) - window.add_page(argv[argi]); - if (argc < 2) + + WebDvdWindow window(frame_params); + int argi = 1; + if (std::strcmp(argv[argi], "--video-std") == 0) + argi += 2; + else if (std::strcmp(argv[argi], "--") == 0) + argi += 1; + else if (argv[argi][0] == '-') + throw std::runtime_error( + std::string("Invalid option: ").append(argv[argi])); + if (argi == argc) window.add_page("about:"); + else + for (/* no initialisation */; argi != argc; ++argi) + window.add_page(argv[argi]); Gtk::Main::run(window); } catch (std::exception & e) -- 2.39.2