]> git.sesse.net Git - casparcg/blobdiff - modules/ogl/consumer/ogl_consumer.cpp
ogl_consumer: Add "FULLSCREEN" option to ADD SCREEN.
[casparcg] / modules / ogl / consumer / ogl_consumer.cpp
index 32233d2cdb7bc7fb0f8e7ae25efa4490c869f013..56629197da28d30580a43a17afd928ea33a91cf9 100644 (file)
@@ -68,6 +68,8 @@ extern "C"
 #pragma warning (pop)\r
 #endif\r
 \r
+typedef int (*PFNWGLEXTGETSWAPINTERVALPROC) (void);\r
\r
 namespace caspar { namespace ogl {\r
                \r
 enum stretch\r
@@ -80,12 +82,21 @@ enum stretch
 \r
 struct configuration\r
 {\r
+       enum aspect_ratio\r
+       {\r
+               aspect_4_3 = 0,\r
+               aspect_16_9,\r
+               aspect_invalid,\r
+       };\r
+               \r
        std::wstring    name;\r
        size_t                  screen_index;\r
        stretch                 stretch;\r
        bool                    windowed;\r
        bool                    auto_deinterlace;\r
        bool                    key_only;\r
+       aspect_ratio    aspect; \r
+       bool                    vsync;\r
 \r
        configuration()\r
                : name(L"ogl")\r
@@ -94,6 +105,8 @@ struct configuration
                , windowed(true)\r
                , auto_deinterlace(true)\r
                , key_only(false)\r
+               , aspect(aspect_invalid)\r
+               , vsync(false)\r
        {\r
        }\r
 };\r
@@ -106,7 +119,7 @@ struct ogl_consumer : boost::noncopyable
 \r
        GLuint                                  texture_;\r
        std::vector<GLuint>             pbos_;\r
-       \r
+                       \r
        float                                   width_;\r
        float                                   height_;        \r
        unsigned int                    screen_x_;\r
@@ -141,9 +154,20 @@ public:
                , square_height_(format_desc.square_height)\r
                , filter_(format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? L"" : L"YADIF=0:-1", boost::assign::list_of(PIX_FMT_BGRA))\r
        {               \r
+               if(format_desc_.format == core::video_format::ntsc && config_.aspect == configuration::aspect_4_3)\r
+               {\r
+                       // Use default values which are 4:3.\r
+               }\r
+               else\r
+               {\r
+                       if(config_.aspect == configuration::aspect_16_9)\r
+                               square_width_ = (format_desc.height*16)/9;\r
+                       else if(config_.aspect == configuration::aspect_4_3)\r
+                               square_width_ = (format_desc.height*4)/3;\r
+               }\r
+\r
                frame_buffer_.set_capacity(2);\r
                \r
-               graph_->add_guide("tick-time", 0.5);\r
                graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));   \r
                graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
                graph_->set_color("dropped-frame", diagnostics::color(0.3f, 0.6f, 0.3f));\r
@@ -156,17 +180,17 @@ public:
                        displayDevices.push_back(d_device);\r
 \r
                if(config_.screen_index >= displayDevices.size())\r
-                       BOOST_THROW_EXCEPTION(out_of_range() << arg_name_info("screen_index_") << msg_info(narrow(print())));\r
+                       CASPAR_LOG(warning) << print() << L" Invalid screen-index: " << config_.screen_index;\r
                \r
                DEVMODE devmode = {};\r
                if(!EnumDisplaySettings(displayDevices[config_.screen_index].DeviceName, ENUM_CURRENT_SETTINGS, &devmode))\r
-                       BOOST_THROW_EXCEPTION(invalid_operation() << arg_name_info("screen_index") << msg_info(narrow(print()) + " EnumDisplaySettings"));\r
+                       CASPAR_LOG(warning) << print() << L" Could not find display settings for screen-index: " << config_.screen_index;\r
                \r
                screen_x_               = devmode.dmPosition.x;\r
                screen_y_               = devmode.dmPosition.y;\r
                screen_width_   = config_.windowed ? square_width_ : devmode.dmPelsWidth;\r
                screen_height_  = config_.windowed ? square_height_ : devmode.dmPelsHeight;\r
-               \r
+\r
                is_running_ = true;\r
                thread_ = boost::thread([this]{run();});\r
        }\r
@@ -212,6 +236,18 @@ public:
                glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbos_[1]);\r
                glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW_ARB);\r
                glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);\r
+                               \r
+               if(config_.vsync)\r
+               {\r
+                       auto wglSwapIntervalEXT = reinterpret_cast<void(APIENTRY*)(int)>(wglGetProcAddress("wglSwapIntervalEXT"));\r
+                       if(wglSwapIntervalEXT)\r
+                       {\r
+                               wglSwapIntervalEXT(1);\r
+                               CASPAR_LOG(info) << print() << " Successfully enabled vsync.";\r
+                       }\r
+                       else\r
+                               CASPAR_LOG(info) << print() << " Failed to enable vsync.";\r
+               }\r
 \r
                CASPAR_LOG(info) << print() << " Successfully Initialized.";\r
        }\r
@@ -253,11 +289,11 @@ public:
                                        \r
                                        perf_timer_.restart();\r
                                        render(frame);\r
-                                       graph_->update_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5); \r
+                                       graph_->set_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5);    \r
 \r
                                        window_.Display();\r
                                        \r
-                                       graph_->update_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);  \r
+                                       graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);     \r
                                        tick_timer_.restart();\r
                                }\r
                                catch(...)\r
@@ -360,7 +396,7 @@ public:
        bool send(const safe_ptr<core::read_frame>& frame)\r
        {\r
                if(!frame_buffer_.try_push(frame))\r
-                       graph_->add_tag("dropped-frame");\r
+                       graph_->set_tag("dropped-frame");\r
                return is_running_;\r
        }\r
                \r
@@ -499,14 +535,17 @@ safe_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>&
        \r
        configuration config;\r
                \r
-       if(params.size() > 1) \r
-               config.screen_index = lexical_cast_or_default<int>(params[2], config.screen_index);\r
-\r
-       if(params.size() > 2) \r
-               config.windowed = lexical_cast_or_default<bool>(params[3], config.windowed);\r
-\r
+       auto device_it = std::find(params.begin(), params.end(), L"DEVICE");\r
+       if(device_it != params.end() && ++device_it != params.end())\r
+               config.screen_index = boost::lexical_cast<int>(*device_it);\r
+               \r
+       config.windowed = std::find(params.begin(), params.end(), L"FULLSCREEN") == params.end();\r
        config.key_only = std::find(params.begin(), params.end(), L"KEY_ONLY") != params.end();\r
 \r
+       auto name_it    = std::find(params.begin(), params.end(), L"NAME");\r
+       if(name_it != params.end() && ++name_it != params.end())\r
+               config.name = *name_it;\r
+\r
        return make_safe<ogl_consumer_proxy>(config);\r
 }\r
 \r
@@ -518,12 +557,19 @@ safe_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptre
        config.windowed                 = ptree.get(L"windowed", config.windowed);\r
        config.key_only                 = ptree.get(L"key-only", config.key_only);\r
        config.auto_deinterlace = ptree.get(L"auto-deinterlace", config.auto_deinterlace);\r
-       \r
+       config.vsync                    = ptree.get(L"vsync", config.vsync);\r
+\r
        auto stretch_str = ptree.get(L"stretch", L"default");\r
        if(stretch_str == L"uniform")\r
                config.stretch = stretch::uniform;\r
        else if(stretch_str == L"uniform_to_fill")\r
                config.stretch = stretch::uniform_to_fill;\r
+\r
+       auto aspect_str = ptree.get(L"aspect-ratio", L"default");\r
+       if(aspect_str == L"16:9")\r
+               config.aspect = configuration::aspect_16_9;\r
+       else if(aspect_str == L"4:3")\r
+               config.aspect = configuration::aspect_4_3;\r
        \r
        return make_safe<ogl_consumer_proxy>(config);\r
 }\r