From 1614cde357c6de1c1422d7ac935c38978bfa8423 Mon Sep 17 00:00:00 2001 From: ronag Date: Tue, 17 May 2011 09:18:31 +0000 Subject: [PATCH] 2.0.0.2: Increased mixer pipeline depth to take into consideration host to device transfers, which might affect multi-channel rendering. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@763 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- core/mixer/audio/audio_mixer.cpp | 21 ++++-- core/mixer/image/image_mixer.cpp | 88 ++++++++++++++--------- modules/flash/producer/flash_producer.cpp | 4 +- shell/caspar.config | 2 +- 4 files changed, 72 insertions(+), 43 deletions(-) diff --git a/core/mixer/audio/audio_mixer.cpp b/core/mixer/audio/audio_mixer.cpp index 7ab35d110..d7a9a22b4 100644 --- a/core/mixer/audio/audio_mixer.cpp +++ b/core/mixer/audio/audio_mixer.cpp @@ -29,7 +29,7 @@ namespace caspar { namespace mixer { struct audio_mixer::implementation { - std::vector audio_data_; + std::deque> audio_data_; std::stack transform_stack_; std::map prev_audio_transforms_; @@ -39,6 +39,10 @@ public: implementation() { transform_stack_.push(core::audio_transform()); + + // 2 frames delay + audio_data_.push_back(std::vector()); + audio_data_.push_back(std::vector()); } void begin(const core::basic_frame& frame) @@ -54,8 +58,8 @@ public: auto& audio_data = frame.audio_data(); auto tag = frame.tag(); // Get the identifier for the audio-stream. - if(audio_data_.empty()) - audio_data_.resize(audio_data.size(), 0); + if(audio_data_.back().empty()) + audio_data_.back().resize(audio_data.size(), 0); auto next = transform_stack_.top(); auto prev = next; @@ -79,11 +83,11 @@ public: { for(size_t n = r.begin(); n < r.end(); ++n) { - double alpha = static_cast(n)/static_cast(audio_data_.size()); + double alpha = static_cast(n)/static_cast(audio_data_.back().size()); double sample_gain = prev_gain * (1.0 - alpha) + next_gain * alpha; int sample = static_cast(audio_data[n]); sample = (static_cast(sample_gain*static_cast(1<<15))*sample)>>15; - audio_data_[n] = static_cast((static_cast(audio_data_[n]) + sample) & 0xFFFF); + audio_data_.back()[n] = static_cast((static_cast(audio_data_.back()[n]) + sample) & 0xFFFF); } } ); @@ -102,7 +106,12 @@ public: std::vector begin_pass() { - return std::move(audio_data_); + auto result = std::move(audio_data_.front()); + audio_data_.pop_front(); + + audio_data_.push_back(std::vector()); + + return result; } void end_pass() diff --git a/core/mixer/image/image_mixer.cpp b/core/mixer/image/image_mixer.cpp index 2fd86da69..4b531ecf1 100644 --- a/core/mixer/image/image_mixer.cpp +++ b/core/mixer/image/image_mixer.cpp @@ -63,10 +63,11 @@ struct image_mixer::implementation : boost::noncopyable struct render_item { core::pixel_format_desc desc; - std::vector> buffers; + std::vector> textures; core::image_transform transform; }; - + + std::vector waiting_queue_; std::vector render_queue_; public: @@ -115,14 +116,28 @@ public: auto gpu_frame = dynamic_cast(&frame); if(!gpu_frame) return; + + auto desc = gpu_frame->get_pixel_format_desc(); + auto buffers = gpu_frame->get_plane_buffers(); + auto transform = transform_stack_.top(); - render_item item; + ogl_device::begin_invoke([=] + { + render_item item; - item.desc = gpu_frame->get_pixel_format_desc(); - item.buffers = gpu_frame->get_plane_buffers(); - item.transform = transform_stack_.top(); + item.desc = desc; + item.transform = transform; + + for(size_t n = 0; n < buffers.size(); ++n) + { + GL(glActiveTexture(GL_TEXTURE0+n)); + auto texture = ogl_device::create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels); + texture->read(*buffers[n]); + item.textures.push_back(texture); + } - render_queue_.push_back(item); + waiting_queue_.push_back(item); + }); } void end() @@ -132,39 +147,58 @@ public: boost::unique_future> render() { - auto queue = render_queue_; - render_queue_.clear(); - return ogl_device::begin_invoke([=]() -> safe_ptr + auto result = ogl_device::begin_invoke([=]() -> safe_ptr + { + reading_->map(); // Might block. + return make_safe(reading_); + }); + + ogl_device::begin_invoke([=] { is_key_ = false; + + // Clear and bind frame-buffers. + key_target_->attach(); GL(glClear(GL_COLOR_BUFFER_BIT)); - // START_PASS - auto result = reading_; - result->map(); render_targets_[0]->attach(); GL(glClear(GL_COLOR_BUFFER_BIT)); - BOOST_FOREACH(auto item, queue) + // Render items. + + BOOST_FOREACH(auto item, render_queue_) render(item); - // END PASS + // Move waiting items to queue. + + render_queue_ = std::move(waiting_queue_); + + // Start read-back. + reading_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only); render_targets_[0]->attach(); render_targets_[0]->write(*reading_); - std::rotate(render_targets_.begin(), render_targets_.begin() + 1, render_targets_.end()); - - return make_safe(result); + std::swap(render_targets_[0], render_targets_[1]); }); + + return std::move(result); } void render(const render_item& item) { const auto desc = item.desc; - auto buffers = item.buffers; + auto textures = item.textures; const auto transform = item.transform; + // Bind textures + + for(size_t n = 0; n < textures.size(); ++n) + { + GL(glActiveTexture(GL_TEXTURE0+n)); + textures[n]->bind(); + } + // Setup key and kernel if(transform.get_is_key()) @@ -182,27 +216,13 @@ public: kernel_.apply(desc, transform, is_key_); if(is_key_) { - if(buffers.size() == 4) - buffers.pop_back(); is_key_ = false; render_targets_[0]->attach(); GL(glActiveTexture(GL_TEXTURE0+3)); key_target_->bind(); } - } - - // Bind textures - - std::vector> textures; - for(size_t n = 0; n < buffers.size(); ++n) - { - GL(glActiveTexture(GL_TEXTURE0+n)); - auto texture = ogl_device::create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels); - texture->read(*buffers[n]); - texture->bind(); - textures.push_back(texture); - } + } GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity())); GL(glViewport(0, 0, format_desc_.width, format_desc_.height)); diff --git a/modules/flash/producer/flash_producer.cpp b/modules/flash/producer/flash_producer.cpp index 625f062a9..5880daac1 100644 --- a/modules/flash/producer/flash_producer.cpp +++ b/modules/flash/producer/flash_producer.cpp @@ -297,14 +297,14 @@ public: const auto& format_desc = frame_factory_->get_video_format_desc(); auto frame = core::basic_frame::empty(); - if(abs(context_->fps()/2.0 - format_desc.fps) < 0.1) // flash == 2 * format -> interlace + if(abs(context_->fps()/2.0 - format_desc.fps) < 0.01) // flash == 2 * format -> interlace { auto frame1 = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()); auto frame2 = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()); frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, format_desc.mode)); frame = frame2; } - else if(abs(context_->fps()- format_desc.fps/2.0 ) < 0.1) // format == 2 * flash -> duplicate + else if(abs(context_->fps()- format_desc.fps/2.0) < 0.01) // format == 2 * flash -> duplicate { frame = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()); frame_buffer_.push(frame); diff --git a/shell/caspar.config b/shell/caspar.config index f4ddba672..523a89ee4 100644 --- a/shell/caspar.config +++ b/shell/caspar.config @@ -5,7 +5,7 @@ L:\\Casparcg\\_log\\ L:\\Casparcg\\_data\\ L:\\Casparcg\\_templates\\ - cg.fth.18 + cg.fth.1920x1080p29.97 true -- 2.39.5