From 657653534fc9902d92f306ebab1712c55c34407e Mon Sep 17 00:00:00 2001 From: ronag Date: Sat, 14 May 2011 10:56:22 +0000 Subject: [PATCH] 2.0.0.2: Added some utility algorithms. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@739 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- common/common.vcxproj | 1 + common/common.vcxproj.filters | 3 ++ common/utility/algorithm.h | 25 +++++++++ core/mixer/frame_mixer_device.cpp | 2 +- .../ffmpeg/producer/audio/audio_decoder.cpp | 17 +++--- modules/ffmpeg/producer/ffmpeg_producer.cpp | 52 +++++++------------ 6 files changed, 57 insertions(+), 43 deletions(-) create mode 100644 common/utility/algorithm.h diff --git a/common/common.vcxproj b/common/common.vcxproj index 235708c9d..df99d2d69 100644 --- a/common/common.vcxproj +++ b/common/common.vcxproj @@ -224,6 +224,7 @@ + diff --git a/common/common.vcxproj.filters b/common/common.vcxproj.filters index b0b0d26ad..293dfc54c 100644 --- a/common/common.vcxproj.filters +++ b/common/common.vcxproj.filters @@ -108,5 +108,8 @@ concurrency + + utility + \ No newline at end of file diff --git a/common/utility/algorithm.h b/common/utility/algorithm.h new file mode 100644 index 000000000..c65711830 --- /dev/null +++ b/common/utility/algorithm.h @@ -0,0 +1,25 @@ +#pragma once + +namespace caspar { + +template +typename T::value_type pop_front(T& container) +{ + auto item = std::move(container.front()); + container.pop_front(); + return std::move(item); +} + +template +std::vector split(const T& container, size_t size) +{ + std::vector result; + const auto last = container.end() - container.size() % size; + for(auto it = container.begin(); it != last; it += size) + result.push_back(T(it, it + size)); + result.push_back(T(last, container.end())); + + return std::move(result); +} + +} \ No newline at end of file diff --git a/core/mixer/frame_mixer_device.cpp b/core/mixer/frame_mixer_device.cpp index fc88c8386..9c7dca934 100644 --- a/core/mixer/frame_mixer_device.cpp +++ b/core/mixer/frame_mixer_device.cpp @@ -115,7 +115,7 @@ public: diag_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f)); diag_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f)); diag_->set_color("input-buffer", diagnostics::color(1.0f, 1.0f, 0.0f)); - executor_.set_capacity(1); + executor_.set_capacity(2); executor_.begin_invoke([] { SetThreadPriority(GetCurrentThread(), ABOVE_NORMAL_PRIORITY_CLASS); diff --git a/modules/ffmpeg/producer/audio/audio_decoder.cpp b/modules/ffmpeg/producer/audio/audio_decoder.cpp index 311df2f47..e3265ef5f 100644 --- a/modules/ffmpeg/producer/audio/audio_decoder.cpp +++ b/modules/ffmpeg/producer/audio/audio_decoder.cpp @@ -21,6 +21,8 @@ #include "audio_decoder.h" +#include + #if defined(_MSC_VER) #pragma warning (push) #pragma warning (disable : 4244) @@ -39,14 +41,12 @@ extern "C" namespace caspar { struct audio_decoder::implementation : boost::noncopyable -{ - typedef std::vector> buffer; - +{ AVCodecContext* codec_context_; const core::video_format_desc format_desc_; - buffer current_chunk_; + std::vector current_chunk_; public: explicit implementation(AVCodecContext* codec_context, const core::video_format_desc& format_desc) @@ -97,13 +97,10 @@ public: current_chunk_.resize(s + written_bytes/2); - const auto last = current_chunk_.end() - current_chunk_.size() % format_desc_.audio_samples_per_frame; - - std::vector> chunks; - for(auto it = current_chunk_.begin(); it != last; it += format_desc_.audio_samples_per_frame) - chunks.push_back(std::vector(it, it + format_desc_.audio_samples_per_frame)); + auto chunks = split(current_chunk_, format_desc_.audio_samples_per_frame); - current_chunk_.erase(current_chunk_.begin(), last); + current_chunk_ = chunks.back(); + chunks.pop_back(); return chunks; } diff --git a/modules/ffmpeg/producer/ffmpeg_producer.cpp b/modules/ffmpeg/producer/ffmpeg_producer.cpp index db7e00602..933270402 100644 --- a/modules/ffmpeg/producer/ffmpeg_producer.cpp +++ b/modules/ffmpeg/producer/ffmpeg_producer.cpp @@ -25,45 +25,40 @@ #include "audio/audio_decoder.h" #include "video/video_decoder.h" -#include #include +#include +#include +#include #include #include #include -#include - -#include -#include -#include #include #include #include -#include namespace caspar { struct ffmpeg_producer : public core::frame_producer { - const std::wstring filename_; - const bool loop_; + const std::wstring filename_; + const bool loop_; - std::shared_ptr graph_; - boost::timer perf_timer_; + std::shared_ptr graph_; + boost::timer perf_timer_; std::deque> video_frame_buffer_; std::deque> audio_chunk_buffer_; - - std::queue> ouput_channel_; + std::queue> output_channel_; std::shared_ptr frame_factory_; - input input_; - std::unique_ptr video_decoder_; - std::unique_ptr audio_decoder_; + input input_; + std::unique_ptr video_decoder_; + std::unique_ptr audio_decoder_; public: explicit ffmpeg_producer(const safe_ptr& frame_factory, const std::wstring& filename, bool loop, int start_frame, int end_frame) : filename_(filename) @@ -117,7 +112,7 @@ public: { perf_timer_.restart(); - for(size_t n = 0; ouput_channel_.size() < 2 && input_.has_packet() && n < 32; ++n) // 32 packets should be enough. Otherwise there probably was an error and we want to avoid infinite recursion. + for(size_t n = 0; output_channel_.size() < 2 && input_.has_packet() && n < 32; ++n) // 32 packets should be enough. Otherwise there probably was an error and we want to avoid infinite recursion. { tbb::parallel_invoke ( @@ -189,16 +184,12 @@ public: if(!video_frame_buffer_.empty() && !audio_chunk_buffer_.empty()) { - frame = video_frame_buffer_.front(); - video_frame_buffer_.pop_front(); - - frame->audio_data() = std::move(audio_chunk_buffer_.front()); - audio_chunk_buffer_.pop_front(); + frame = pop_front(video_frame_buffer_); + frame->audio_data() = pop_front(audio_chunk_buffer_); } else if(!video_frame_buffer_.empty() && !audio_decoder_) { - frame = video_frame_buffer_.front(); - video_frame_buffer_.pop_front(); + frame = pop_front(video_frame_buffer_); frame->get_audio_transform().set_has_audio(false); } else if(!audio_chunk_buffer_.empty() && !video_decoder_) @@ -206,12 +197,11 @@ public: frame = frame_factory_->create_frame(this, 1, 1); std::fill(frame->image_data().begin(), frame->image_data().end(), 0); - frame->audio_data() = std::move(audio_chunk_buffer_.front()); - audio_chunk_buffer_.pop_front(); + frame->audio_data() = pop_front(audio_chunk_buffer_); } if(frame) - ouput_channel_.push(make_safe(frame)); + output_channel_.push(make_safe(frame)); } safe_ptr get_next_frame() @@ -219,20 +209,18 @@ public: if(is_eof()) return core::basic_frame::eof(); - if(ouput_channel_.empty()) + if(output_channel_.empty()) { graph_->add_tag("underflow"); return core::basic_frame::late(); } - auto frame = std::move(ouput_channel_.front()); - ouput_channel_.pop(); - return frame; + return pop_front(output_channel_); } bool is_eof() const { - return ouput_channel_.empty() && (!video_decoder_ && !audio_decoder_) || !input_.is_running(); + return output_channel_.empty() && (!video_decoder_ && !audio_decoder_) || !input_.is_running(); } }; -- 2.39.2