X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fscreen%2Fconsumer%2Fscreen_consumer.cpp;h=d40429d2492d0e6ab0ab3dcdfc23c87d31778ce2;hb=b8c8660af595b9897af41183fe8b12786d45af98;hp=84b3c5a0766addd9aec503978272ee8a7b77408f;hpb=3eefdca43ad463fd035c144af2a289808eff5367;p=casparcg diff --git a/modules/screen/consumer/screen_consumer.cpp b/modules/screen/consumer/screen_consumer.cpp index 84b3c5a07..d40429d24 100644 --- a/modules/screen/consumer/screen_consumer.cpp +++ b/modules/screen/consumer/screen_consumer.cpp @@ -42,6 +42,7 @@ //#include #include +#include #include #include @@ -69,7 +70,7 @@ #pragma warning (push) #pragma warning (disable : 4244) #endif -extern "C" +extern "C" { #define __STDC_CONSTANT_MACROS #define __STDC_LIMIT_MACROS @@ -81,7 +82,7 @@ extern "C" #endif namespace caspar { namespace screen { - + enum class stretch { none, @@ -98,7 +99,7 @@ struct configuration aspect_16_9, aspect_invalid, }; - + std::wstring name = L"Screen consumer"; int screen_index = 0; screen::stretch stretch = screen::stretch::fill; @@ -119,7 +120,7 @@ struct screen_consumer : boost::noncopyable GLuint texture_ = 0; std::vector pbos_ = std::vector { 0, 0 }; - + float width_; float height_; int screen_x_; @@ -152,20 +153,20 @@ public: const configuration& config, const core::video_format_desc& format_desc, int channel_index, - core::interaction_sink* sink) + core::interaction_sink* sink) : config_(config) , format_desc_(format_desc) , channel_index_(channel_index) , pts_(0) , sink_(sink) , filter_([&]() -> ffmpeg::filter - { - const auto sample_aspect_ratio = + { + const auto sample_aspect_ratio = boost::rational( - format_desc.square_width, + format_desc.square_width, format_desc.square_height) / boost::rational( - format_desc.width, + format_desc.width, format_desc.height); return ffmpeg::filter( @@ -178,7 +179,7 @@ public: { AV_PIX_FMT_BGRA }, format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? "" : "format=pix_fmts=gbrp,YADIF=1:-1"); }()) - { + { if (format_desc_.format == core::video_format::ntsc && config_.aspect == configuration::aspect_ratio::aspect_4_3) { // Use default values which are 4:3. @@ -192,13 +193,13 @@ public: } frame_buffer_.set_capacity(1); - - graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); + + graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f)); graph_->set_color("dropped-frame", diagnostics::color(0.3f, 0.6f, 0.3f)); graph_->set_text(print()); diagnostics::register_graph(graph_); - + /*DISPLAY_DEVICE d_device = {sizeof(d_device), 0}; std::vector displayDevices; for(int n = 0; EnumDisplayDevices(NULL, n, &d_device, NULL); ++n) @@ -206,11 +207,11 @@ public: if(config_.screen_index >= displayDevices.size()) CASPAR_LOG(warning) << print() << L" Invalid screen-index: " << config_.screen_index; - + DEVMODE devmode = {}; if(!EnumDisplaySettings(displayDevices[config_.screen_index].DeviceName, ENUM_CURRENT_SETTINGS, &devmode)) CASPAR_LOG(warning) << print() << L" Could not find display settings for screen-index: " << config_.screen_index; - + screen_x_ = devmode.dmPosition.x; screen_y_ = devmode.dmPosition.y; screen_width_ = config_.windowed ? square_width_ : devmode.dmPelsWidth; @@ -219,13 +220,13 @@ public: screen_y_ = 0; screen_width_ = square_width_; screen_height_ = square_height_; - + polling_event_ = false; is_running_ = true; current_presentation_age_ = 0; thread_ = boost::thread([this]{run();}); } - + ~screen_consumer() { is_running_ = false; @@ -245,7 +246,7 @@ public: window_.setPosition(sf::Vector2i(screen_x_, screen_y_)); window_.setSize(sf::Vector2u(screen_width_, screen_height_)); window_.setActive(); - + if(!GLEW_VERSION_2_1 && glewInit() != GLEW_OK) CASPAR_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Failed to initialize GLEW.")); @@ -253,13 +254,13 @@ public: CASPAR_THROW_EXCEPTION(not_supported() << msg_info("Missing OpenGL 2.1 support.")); GL(glEnable(GL_TEXTURE_2D)); - GL(glDisable(GL_DEPTH_TEST)); + GL(glDisable(GL_DEPTH_TEST)); GL(glClearColor(0.0, 0.0, 0.0, 0.0)); GL(glViewport(0, 0, format_desc_.width, format_desc_.height)); GL(glLoadIdentity()); - + calculate_aspect(); - + GL(glGenTextures(1, &texture_)); GL(glBindTexture(GL_TEXTURE_2D, texture_)); GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -268,15 +269,15 @@ public: GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)); GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, format_desc_.width, format_desc_.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0)); GL(glBindTexture(GL_TEXTURE_2D, 0)); - + GL(glGenBuffers(2, pbos_.data())); - + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbos_[0]); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW_ARB); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbos_[1]); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW_ARB); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - + window_.setVerticalSyncEnabled(config_.vsync); if (config_.vsync) @@ -286,7 +287,7 @@ public: } void uninit() - { + { if(texture_) glDeleteTextures(1, &texture_); @@ -306,7 +307,7 @@ public: init(); while(is_running_) - { + { try { auto poll_event = [this](sf::Event& e) @@ -364,20 +365,20 @@ public: } } } - + core::const_frame frame; frame_buffer_.pop(frame); render_and_draw_frame(frame); - + /*perf_timer_.restart(); render(frame); - graph_->set_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5); + graph_->set_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5); window_.Display();*/ current_presentation_age_ = frame.get_age_millis(); - graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5); + graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5); tick_timer_.restart(); } catch(...) @@ -414,11 +415,10 @@ public: } spl::shared_ptr get_av_frame() - { - spl::shared_ptr av_frame(av_frame_alloc(), [](AVFrame* p) { av_frame_free(&p); }); - avcodec_get_frame_defaults(av_frame.get()); - - av_frame->linesize[0] = format_desc_.width*4; + { + auto av_frame = ffmpeg::create_frame(); + + av_frame->linesize[0] = format_desc_.width*4; av_frame->format = PIX_FMT_BGRA; av_frame->width = format_desc_.width; av_frame->height = format_desc_.height; @@ -436,7 +436,7 @@ public: if(screen_width_ == 0 && screen_height_ == 0) return; - + perf_timer_.restart(); auto av_frame = get_av_frame(); av_frame->data[0] = const_cast(input_frame.image_data().begin()); @@ -497,20 +497,20 @@ public: { fast_memcpy(ptr, av_frame->data[0], format_desc_.size); } - + GL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); // release the mapped buffer } GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - - GL(glClear(GL_COLOR_BUFFER_BIT)); + + GL(glClear(GL_COLOR_BUFFER_BIT)); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(-width_, -height_); glTexCoord2f(1.0f, 1.0f); glVertex2f( width_, -height_); glTexCoord2f(1.0f, 0.0f); glVertex2f( width_, height_); glTexCoord2f(0.0f, 0.0f); glVertex2f(-width_, height_); glEnd(); - + GL(glBindTexture(GL_TEXTURE_2D, 0)); std::rotate(pbos_.begin(), pbos_.begin() + 1, pbos_.end()); @@ -531,10 +531,10 @@ public: } std::wstring print() const - { + { return config_.name + L" " + channel_and_format(); } - + void calculate_aspect() { if(config_.windowed) @@ -542,7 +542,7 @@ public: screen_height_ = window_.getSize().y; screen_width_ = window_.getSize().x; } - + GL(glViewport(0, 0, screen_width_, screen_height_)); std::pair target_ratio = None(); @@ -556,7 +556,7 @@ public: width_ = target_ratio.first; height_ = target_ratio.second; } - + std::pair None() { float width = static_cast(square_width_)/static_cast(screen_width_); @@ -607,7 +607,7 @@ public: , sink_(sink) { } - + // frame_consumer void initialize(const core::video_format_desc& format_desc, const core::audio_channel_layout&, int channel_index) override @@ -625,7 +625,7 @@ public: { return consumer_->send(frame); } - + std::wstring print() const override { return consumer_ ? consumer_->print() : L"[screen_consumer]"; @@ -651,7 +651,7 @@ public: { return false; } - + int buffer_depth() const override { return 1; @@ -666,7 +666,7 @@ public: { return monitor_subject_; } -}; +}; void describe_consumer(core::help_sink& sink, const core::help_repository& repo) { @@ -700,12 +700,12 @@ spl::shared_ptr create_consumer(const std::vector 1) config.screen_index = boost::lexical_cast(params.at(1)); - + config.windowed = !contains_param(L"FULLSCREEN", params); config.key_only = contains_param(L"KEY_ONLY", params); config.interactive = !contains_param(L"NON_INTERACTIVE", params); @@ -718,7 +718,7 @@ spl::shared_ptr create_consumer(const std::vector(config, sink); } -spl::shared_ptr create_preconfigured_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink) +spl::shared_ptr create_preconfigured_consumer(const boost::property_tree::wptree& ptree, core::interaction_sink* sink) { configuration config; config.name = ptree.get(L"name", config.name); @@ -741,7 +741,7 @@ spl::shared_ptr create_preconfigured_consumer(const boost: config.aspect = configuration::aspect_ratio::aspect_16_9; else if(aspect_str == L"4:3") config.aspect = configuration::aspect_ratio::aspect_4_3; - + return spl::make_shared(config, sink); }