virtual boost::unique_future<bool> send(const safe_ptr<core::read_frame>& frame) override { CASPAR_VERIFY(format_desc_.height * format_desc_.width * 4 == static_cast<unsigned>(frame->image_data().size())); return executor_.begin_invoke([=]() -> bool { graph_->set_value("tick-time", tick_timer_.elapsed() * format_desc_.fps * 0.5); tick_timer_.restart(); frame_timer_.restart(); // AUDIO std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>> audio_buffer; if (core::needs_rearranging( frame->multichannel_view(), channel_layout_, channel_layout_.num_channels)) { core::audio_buffer downmixed; downmixed.resize( frame->multichannel_view().num_samples() * channel_layout_.num_channels, 0); auto dest_view = core::make_multichannel_view<int32_t>( downmixed.begin(), downmixed.end(), channel_layout_); core::rearrange_or_rearrange_and_mix( frame->multichannel_view(), dest_view, core::default_mix_config_repository()); audio_buffer = core::audio_32_to_16(downmixed); } else { audio_buffer = core::audio_32_to_16(frame->audio_data()); } airsend::add_audio(air_send_.get(), audio_buffer.data(), audio_buffer.size() / channel_layout_.num_channels); // VIDEO connected_ = airsend::add_frame_bgra(air_send_.get(), frame->image_data().begin()); graph_->set_text(print()); graph_->set_value("frame-time", frame_timer_.elapsed() * format_desc_.fps * 0.5); return true; }); }
virtual boost::unique_future<bool> send(const safe_ptr<read_frame>& frame) override { if(audio_cadence_.size() == 1) return consumer_->send(frame); boost::unique_future<bool> result = caspar::wrap_as_future(true); if(boost::range::equal(sync_buffer_, audio_cadence_) && audio_cadence_.front() * frame->num_channels() == static_cast<size_t>(frame->audio_data().size())) { // Audio sent so far is in sync, now we can send the next chunk. result = consumer_->send(frame); boost::range::rotate(audio_cadence_, std::begin(audio_cadence_)+1); } else CASPAR_LOG(trace) << print() << L" Syncing audio."; sync_buffer_.push_back(static_cast<size_t>(frame->audio_data().size() / frame->num_channels())); return std::move(result); }