<ClInclude Include="compiler\vs\disable_silly_warnings.h" />\r
<ClInclude Include="concurrency\com_context.h" />\r
<ClInclude Include="concurrency\executor.h" />\r
+ <ClInclude Include="concurrency\lock.h" />\r
<ClInclude Include="concurrency\target.h" />\r
<ClInclude Include="diagnostics\graph.h" />\r
<ClInclude Include="exception\exceptions.h" />\r
<ClInclude Include="utility\utf8conv_inl.h">\r
<Filter>source\utility</Filter>\r
</ClInclude>\r
+ <ClInclude Include="concurrency\lock.h">\r
+ <Filter>source\concurrency</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace caspar {\r
+\r
+template<typename T, typename F>\r
+void lock(T& mutex, F&& func)\r
+{\r
+ T::scoped_lock lock(mutex);\r
+ func();\r
+}\r
+\r
+}
\ No newline at end of file
#pragma warning (disable : 4244)\r
\r
#include "../concurrency/executor.h"\r
+#include "../concurrency/lock.h"\r
#include "../env.h"\r
\r
#include <SFML/Graphics.hpp>\r
#include <boost/circular_buffer.hpp>\r
#include <boost/range/algorithm_ext/erase.hpp>\r
\r
-#include <numeric>\r
-#include <map>\r
+#include <tbb/concurrent_unordered_map.h>\r
+#include <tbb/atomic.h>\r
+#include <tbb/spin_mutex.h>\r
+\r
#include <array>\r
+#include <numeric>\r
+#include <tuple>\r
\r
namespace caspar { namespace diagnostics {\r
\r
+int color(float r, float g, float b, float a)\r
+{\r
+ int code = 0;\r
+ code |= static_cast<int>(r*255.0f+0.5f) << 24;\r
+ code |= static_cast<int>(g*255.0f+0.5f) << 16;\r
+ code |= static_cast<int>(b*255.0f+0.5f) << 8;\r
+ code |= static_cast<int>(a*255.0f+0.5f) << 0;\r
+ return code;\r
+}\r
+\r
+std::tuple<float, float, float, float> color(int code)\r
+{\r
+ float r = static_cast<float>((code >> 24) & 255)/255.0f;\r
+ float g = static_cast<float>((code >> 16) & 255)/255.0f;\r
+ float b = static_cast<float>((code >> 8) & 255)/255.0f;\r
+ float a = static_cast<float>((code >> 0) & 255)/255.0f;\r
+ return std::make_tuple(r, g, b, a);\r
+}\r
+\r
struct drawable : public sf::Drawable\r
{\r
virtual ~drawable(){}\r
{ \r
std::unique_ptr<sf::RenderWindow> window_;\r
\r
- std::list<std::shared_ptr<drawable>> drawables_;\r
+ std::list<std::weak_ptr<drawable>> drawables_;\r
\r
executor executor_;\r
public: \r
\r
- template<typename Func>\r
- static void begin_invoke(Func&& func, task_priority priority) // noexcept\r
- { \r
- if(get_instance().executor_.size() < 128)\r
- get_instance().executor_.begin_invoke(std::forward<Func>(func), priority); \r
- }\r
-\r
static void register_drawable(const std::shared_ptr<drawable>& drawable)\r
{\r
if(!drawable)\r
return;\r
\r
- begin_invoke([=]\r
+ get_instance().executor_.begin_invoke([=]\r
{\r
get_instance().do_register_drawable(drawable);\r
}, high_priority);\r
\r
static void show(bool value)\r
{\r
- begin_invoke([=]\r
+ get_instance().executor_.begin_invoke([=]\r
{ \r
get_instance().do_show(value);\r
}, high_priority);\r
{\r
if(!window_)\r
{\r
- window_.reset(new sf::RenderWindow(sf::VideoMode(600, 1000), "CasparCG Diagnostics"));\r
+ window_.reset(new sf::RenderWindow(sf::VideoMode(750, 750), "CasparCG Diagnostics"));\r
window_->SetPosition(0, 0);\r
window_->SetActive();\r
glEnable(GL_BLEND);\r
glClear(GL_COLOR_BUFFER_BIT);\r
window_->Draw(*this);\r
window_->Display();\r
- boost::this_thread::sleep(boost::posix_time::milliseconds(20));\r
+ boost::this_thread::sleep(boost::posix_time::milliseconds(15));\r
executor_.begin_invoke([this]{tick();});\r
}\r
\r
int n = 0;\r
for(auto it = drawables_.begin(); it != drawables_.end(); ++n)\r
{\r
- auto& drawable = *it;\r
- if(!drawable.unique())\r
+ auto drawable = it->lock();\r
+ if(drawable)\r
{\r
drawable->SetScale(static_cast<float>(window_->GetWidth()), static_cast<float>(target_dy*window_->GetHeight()));\r
float target_y = std::max(last_y, static_cast<float>(n * window_->GetHeight())*target_dy);\r
\r
void do_register_drawable(const std::shared_ptr<drawable>& drawable)\r
{\r
- if(std::find(drawables_.begin(), drawables_.end(), drawable) == drawables_.end())\r
- drawables_.push_back(drawable);\r
+ drawables_.push_back(drawable);\r
+ auto it = drawables_.begin();\r
+ while(it != drawables_.end())\r
+ {\r
+ if(it->lock())\r
+ ++it;\r
+ else \r
+ it = drawables_.erase(it); \r
+ }\r
}\r
\r
static context& get_instance()\r
}\r
};\r
\r
-class guide : public drawable\r
-{\r
- float value_;\r
- color c_;\r
-public:\r
- guide(color c = color(1.0f, 1.0f, 1.0f, 0.6f)) \r
- : value_(0.0f)\r
- , c_(c){}\r
-\r
- guide(float value, color c = color(1.0f, 1.0f, 1.0f, 0.6f)) \r
- : value_(value)\r
- , c_(c){}\r
- \r
- void set_color(color c) {c_ = c;}\r
-\r
- void render(sf::RenderTarget&)\r
- { \r
- glEnable(GL_LINE_STIPPLE);\r
- glLineStipple(3, 0xAAAA);\r
- glBegin(GL_LINE_STRIP); \r
- glColor4f(c_.red, c_.green, c_.blue+0.2f, c_.alpha); \r
- glVertex3f(0.0f, (1.0f-value_) * 0.8f + 0.1f, 0.0f); \r
- glVertex3f(1.0f, (1.0f-value_) * 0.8f + 0.1f, 0.0f); \r
- glEnd();\r
- glDisable(GL_LINE_STIPPLE);\r
- }\r
-};\r
-\r
class line : public drawable\r
{\r
- boost::optional<diagnostics::guide> guide_;\r
- boost::circular_buffer<std::pair<double, bool>> line_data_;\r
+ boost::circular_buffer<std::pair<float, bool>> line_data_;\r
\r
- boost::circular_buffer<double> tick_data_;\r
- bool tick_tag_;\r
- color c_;\r
+ tbb::atomic<float> tick_data_;\r
+ tbb::atomic<bool> tick_tag_;\r
+ tbb::atomic<int> color_;\r
public:\r
line(size_t res = 600)\r
: line_data_(res)\r
- , tick_data_(50)\r
- , tick_tag_(false)\r
- , c_(1.0f, 1.0f, 1.0f)\r
{\r
+ tick_data_ = -1.0f;\r
+ color_ = 0xFFFFFFFF;\r
+ tick_tag_ = false;\r
+\r
line_data_.push_back(std::make_pair(-1.0f, false));\r
}\r
\r
- void update(double value)\r
+ void set_value(float value)\r
{\r
- tick_data_.push_back(value);\r
- }\r
-\r
- void set(double value)\r
- {\r
- tick_data_.clear();\r
- tick_data_.push_back(value);\r
+ tick_data_ = value;\r
}\r
\r
- void tag()\r
+ void set_tag()\r
{\r
tick_tag_ = true;\r
}\r
-\r
- void guide(const guide& guide)\r
+ \r
+ void set_color(int color)\r
{\r
- guide_ = guide;\r
- guide_->set_color(c_);\r
+ color_ = color;\r
}\r
- \r
- void set_color(color c)\r
+\r
+ int get_color()\r
{\r
- c_ = c;\r
- if(guide_)\r
- guide_->set_color(c_);\r
+ return color_;\r
}\r
-\r
- color get_color() const { return c_; }\r
- \r
+ \r
void render(sf::RenderTarget& target)\r
{\r
float dx = 1.0f/static_cast<float>(line_data_.capacity());\r
float x = static_cast<float>(line_data_.capacity()-line_data_.size())*dx;\r
\r
- if(!tick_data_.empty())\r
- {\r
- float sum = std::accumulate(tick_data_.begin(), tick_data_.end(), 0.0) + std::numeric_limits<float>::min();\r
- line_data_.push_back(std::make_pair(static_cast<float>(sum)/static_cast<float>(tick_data_.size()), tick_tag_));\r
- tick_data_.clear();\r
- }\r
- else if(!line_data_.empty())\r
- {\r
- line_data_.push_back(std::make_pair(line_data_.back().first, tick_tag_));\r
- }\r
- tick_tag_ = false;\r
-\r
- if(guide_)\r
- target.Draw(*guide_);\r
- \r
+ line_data_.push_back(std::make_pair(tick_data_, tick_tag_)); \r
+ tick_tag_ = false;\r
+ \r
glBegin(GL_LINE_STRIP);\r
- glColor4f(c_.red, c_.green, c_.blue, 0.8f); \r
+ auto c = color(color_);\r
+ glColor4f(std::get<0>(c), std::get<1>(c), std::get<2>(c), 0.8f); \r
for(size_t n = 0; n < line_data_.size(); ++n) \r
if(line_data_[n].first > -0.5)\r
glVertex3d(x+n*dx, std::max(0.05, std::min(0.95, (1.0f-line_data_[n].first)*0.8 + 0.1f)), 0.0); \r
{\r
if(line_data_[n].second)\r
{\r
- glBegin(GL_LINE_STRIP);\r
- glColor4f(c_.red, c_.green, c_.blue, c_.alpha); \r
+ glBegin(GL_LINE_STRIP); \r
glVertex3f(x+n*dx, 0.0f, 0.0f); \r
glVertex3f(x+n*dx, 1.0f, 0.0f); \r
glEnd();\r
}\r
};\r
\r
-struct graph::implementation : public drawable\r
+struct graph::impl : public drawable\r
{\r
- std::map<std::string, diagnostics::line> lines_;\r
- std::string name_;\r
- std::string text_;\r
- \r
- implementation(const std::string& name) \r
- : name_(name)\r
- , text_(name_){}\r
- \r
- void set_text(const std::string& value)\r
- {\r
- text_ = value;\r
- }\r
+ tbb::concurrent_unordered_map<std::string, diagnostics::line> lines_;\r
+\r
+ tbb::spin_mutex mutex_;\r
+ std::wstring text_;\r
\r
- void update(const std::string& name, double value)\r
+ impl()\r
{\r
- lines_[name].update(value);\r
}\r
-\r
- void set(const std::string& name, double value)\r
+ \r
+ void set_text(const std::wstring& value)\r
{\r
- lines_[name].set(value);\r
+ auto temp = value;\r
+ lock(mutex_, [&]\r
+ {\r
+ text_ = std::move(temp);\r
+ });\r
}\r
\r
- void tag(const std::string& name)\r
+ void set_value(const std::string& name, double value)\r
{\r
- lines_[name].tag();\r
+ lines_[name].set_value(value);\r
}\r
\r
- void set_color(const std::string& name, color c)\r
+ void set_tag(const std::string& name)\r
{\r
- lines_[name].set_color(c);\r
+ lines_[name].set_tag();\r
}\r
- \r
- void guide(const std::string& name, double value)\r
+\r
+ void set_color(const std::string& name, int color)\r
{\r
- lines_[name].guide(diagnostics::guide(value)); \r
+ lines_[name].set_color(color);\r
}\r
- \r
+ \r
private:\r
void render(sf::RenderTarget& target)\r
{\r
const size_t text_margin = 2;\r
const size_t text_offset = (text_size+text_margin*2)*2;\r
\r
- sf::String text(text_.c_str(), sf::Font::GetDefaultFont(), text_size);\r
+ std::wstring text_str;\r
+ {\r
+ tbb::spin_mutex::scoped_lock lock(mutex_);\r
+ text_str = text_;\r
+ }\r
+\r
+ sf::String text(text_str.c_str(), sf::Font::GetDefaultFont(), text_size);\r
text.SetStyle(sf::String::Italic);\r
text.Move(text_margin, text_margin);\r
\r
sf::String line_text(it->first, sf::Font::GetDefaultFont(), text_size);\r
line_text.SetPosition(x_offset, text_margin+text_offset/2);\r
auto c = it->second.get_color();\r
- line_text.SetColor(sf::Color(c.red*255.0f, c.green*255.0f, c.blue*255.0f, c.alpha*255.0f));\r
+ line_text.SetColor(sf::Color((c >> 24) & 255, (c >> 16) & 255, (c >> 8) & 255, (c >> 0) & 255));\r
target.Draw(line_text);\r
x_offset = line_text.GetRect().Right + text_margin*2;\r
}\r
glTranslated(0.0f, text_offset/GetScale().y, 1.0f);\r
glScaled(1.0f, 1.0-text_offset/GetScale().y, 1.0f);\r
\r
- target.Draw(diagnostics::guide(1.0f, color(1.0f, 1.0f, 1.0f, 0.6f)));\r
- target.Draw(diagnostics::guide(0.0f, color(1.0f, 1.0f, 1.0f, 0.6f)));\r
+ glEnable(GL_LINE_STIPPLE);\r
+ glLineStipple(3, 0xAAAA);\r
+ glColor4f(1.0f, 1.0f, 1.9f, 0.5f); \r
+ glBegin(GL_LINE_STRIP); \r
+ glVertex3f(0.0f, (1.0f-0.5f) * 0.8f + 0.1f, 0.0f); \r
+ glVertex3f(1.0f, (1.0f-0.5f) * 0.8f + 0.1f, 0.0f); \r
+ glEnd();\r
+ glBegin(GL_LINE_STRIP); \r
+ glVertex3f(0.0f, (1.0f-0.0f) * 0.8f + 0.1f, 0.0f); \r
+ glVertex3f(1.0f, (1.0f-0.0f) * 0.8f + 0.1f, 0.0f); \r
+ glEnd();\r
+ glBegin(GL_LINE_STRIP); \r
+ glVertex3f(0.0f, (1.0f-1.0f) * 0.8f + 0.1f, 0.0f); \r
+ glVertex3f(1.0f, (1.0f-1.0f) * 0.8f + 0.1f, 0.0f); \r
+ glEnd();\r
+ glDisable(GL_LINE_STIPPLE);\r
+\r
+ //target.Draw(diagnostics::guide(1.0f, color(1.0f, 1.0f, 1.0f, 0.6f)));\r
+ //target.Draw(diagnostics::guide(0.0f, color(1.0f, 1.0f, 1.0f, 0.6f)));\r
\r
for(auto it = lines_.begin(); it != lines_.end(); ++it) \r
target.Draw(it->second);\r
glPopMatrix();\r
}\r
\r
- implementation(implementation&);\r
- implementation& operator=(implementation&);\r
+ impl(impl&);\r
+ impl& operator=(impl&);\r
};\r
\r
-graph::graph() : impl_(new implementation(""))\r
-{\r
-\r
-}\r
-\r
-void graph::set_text(const std::string& value)\r
+graph::graph() : impl_(new impl())\r
{\r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->set_text(value);\r
- }, high_priority);\r
}\r
\r
-void graph::set_text(const std::wstring& value)\r
-{\r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- set_text(narrow(value));\r
- }, high_priority);\r
-}\r
-\r
-void graph::update_value(const std::string& name, double value)\r
-{\r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->update(name, value);\r
- }, high_priority);\r
-}\r
-void graph::set_value(const std::string& name, double value)\r
-{ \r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->set(name, value);\r
- }, high_priority); \r
-}\r
-void graph::set_color(const std::string& name, color c)\r
-{ \r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->set_color(name, c);\r
- }, high_priority);\r
-}\r
-void graph::add_tag(const std::string& name)\r
-{ \r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->tag(name);\r
- }, high_priority);\r
-}\r
-void graph::add_guide(const std::string& name, double value)\r
-{ \r
- auto p = impl_;\r
- context::begin_invoke([=]\r
- { \r
- p->guide(name, value);\r
- }, high_priority);\r
-}\r
+void graph::set_text(const std::wstring& value){impl_->set_text(value);}\r
+void graph::set_value(const std::string& name, double value){impl_->set_value(name, value);}\r
+void graph::set_color(const std::string& name, int color){impl_->set_color(name, color);}\r
+void graph::set_tag(const std::string& name){impl_->set_tag(name);}\r
\r
void register_graph(const safe_ptr<graph>& graph)\r
{\r
//namespace v2\r
//{ \r
// \r
-//struct line::implementation\r
+//struct line::impl\r
//{\r
// std::wstring name_;\r
// boost::circular_buffer<data> ticks_;\r
//\r
-// implementation(const std::wstring& name) \r
+// impl(const std::wstring& name) \r
// : name_(name)\r
// , ticks_(1024){}\r
// \r
-// void update_value(float value)\r
+// void set_value(float value)\r
// {\r
// ticks_.push_back();\r
// ticks_.back().value = value;\r
// void set_value(float value)\r
// {\r
// ticks_.clear();\r
-// update_value(value);\r
+// set_value(value);\r
// }\r
//};\r
//\r
//line::line(){}\r
-//line::line(const std::wstring& name) : impl_(new implementation(name)){}\r
+//line::line(const std::wstring& name) : impl_(new impl(name)){}\r
//std::wstring line::print() const {return impl_->name_;}\r
-//void line::update_value(float value){impl_->update_value(value);}\r
+//void line::set_value(float value){impl_->set_value(value);}\r
//void line::set_value(float value){impl_->set_value(value);}\r
//boost::circular_buffer<data>& line::ticks() { return impl_->ticks_;}\r
//\r
-//struct graph::implementation\r
+//struct graph::impl\r
//{\r
// std::map<std::wstring, line> lines_;\r
// color color_;\r
// printer printer_;\r
//\r
-// implementation(const std::wstring& name) \r
+// impl(const std::wstring& name) \r
// : printer_([=]{return name;}){}\r
//\r
-// implementation(const printer& parent_printer) \r
+// impl(const printer& parent_printer) \r
// : printer_(parent_printer){}\r
// \r
-// void update_value(const std::wstring& name, float value)\r
+// void set_value(const std::wstring& name, float value)\r
// {\r
// auto it = lines_.find(name);\r
// if(it == lines_.end())\r
// it = lines_.insert(std::make_pair(name, line(name))).first;\r
//\r
-// it->second.update_value(value);\r
+// it->second.set_value(value);\r
// }\r
//\r
// void set_value(const std::wstring& name, float value)\r
// }\r
//};\r
// \r
-//graph::graph(const std::wstring& name) : impl_(new implementation(name)){}\r
-//graph::graph(const printer& parent_printer) : impl_(new implementation(parent_printer)){}\r
-//void graph::update_value(const std::wstring& name, float value){impl_->update_value(name, value);}\r
+//graph::graph(const std::wstring& name) : impl_(new impl(name)){}\r
+//graph::graph(const printer& parent_printer) : impl_(new impl(parent_printer)){}\r
+//void graph::set_value(const std::wstring& name, float value){impl_->set_value(name, value);}\r
//void graph::set_value(const std::wstring& name, float value){impl_->set_value(name, value);}\r
//void graph::set_color(const std::wstring& name, color c){impl_->set_color(name, c);}\r
//color graph::get_color() const {return impl_->get_color();}\r
\r
#include "../memory/safe_ptr.h"\r
\r
-#include <functional>\r
#include <string>\r
-#include <vector>\r
-#include <map>\r
+#include <tuple>\r
\r
-#include <boost/range/iterator_range.hpp>\r
-#include <boost/circular_buffer.hpp>\r
-\r
-namespace caspar {\r
- \r
-typedef std::function<std::wstring()> printer;\r
- \r
-namespace diagnostics {\r
- \r
-struct color\r
-{\r
- float red;\r
- float green;\r
- float blue;\r
- float alpha;\r
+namespace caspar { namespace diagnostics {\r
\r
- color(float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 1.0f)\r
- : red(r)\r
- , green(g)\r
- , blue(b)\r
- , alpha(a){}\r
-};\r
+int color(float r, float g, float b, float a = 1.0f);\r
+std::tuple<float, float, float, float> color(int code);\r
\r
class graph\r
{\r
friend void register_graph(const safe_ptr<graph>& graph);\r
public:\r
graph();\r
- void set_text(const std::string& value);\r
void set_text(const std::wstring& value);\r
- void update_value(const std::string& name, double value);\r
void set_value(const std::string& name, double value);\r
- void set_color(const std::string& name, color c);\r
- void add_tag(const std::string& name);\r
- void add_guide(const std::string& name, double value);\r
+ void set_color(const std::string& name, int color);\r
+ void set_tag(const std::string& name);\r
private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
+ struct impl;\r
+ std::shared_ptr<impl> impl_;\r
};\r
\r
void register_graph(const safe_ptr<graph>& graph);\r
void show_graphs(bool value);\r
\r
-//namespace v2\r
-//{\r
-// \r
-// struct data\r
-// {\r
-// float value;\r
-// };\r
-//\r
-// class line\r
-// {\r
-// public:\r
-// line();\r
-// line(const std::wstring& name);\r
-// std::wstring print() const;\r
-// void update_value(float value);\r
-// void set_value(float value);\r
-// void set_tag(const std::wstring& tag);\r
-//\r
-// boost::circular_buffer<data>& ticks();\r
-// private:\r
-// struct implementation;\r
-// std::shared_ptr<implementation> impl_;\r
-// };\r
-// \r
-// class graph;\r
-//\r
-//\r
-// class graph\r
-// {\r
-// public:\r
-// graph(const std::wstring& name);\r
-// graph(const printer& parent_printer);\r
-//\r
-// void update_value(const std::wstring& name, float value);\r
-// void set_value(const std::wstring& name, float value);\r
-//\r
-// void set_guide(const std::wstring& name, float value);\r
-// void set_color(const std::wstring& name, color c);\r
-//\r
-// color get_color() const;\r
-// std::map<std::wstring, line>& get_lines();\r
-//\r
-// std::wstring print() const;\r
-//\r
-// safe_ptr<graph> clone() const;\r
-// private:\r
-// struct implementation;\r
-// std::shared_ptr<implementation> impl_;\r
-// };\r
-// \r
-// static safe_ptr<graph> create_graph(const std::wstring& name);\r
-// static safe_ptr<graph> create_graph(const printer& parent_printer);\r
-// static std::vector<safe_ptr<graph>> get_all_graphs();\r
-//}\r
-\r
}}
\ No newline at end of file
, format_desc_(format_desc)\r
, executor_(L"output")\r
{\r
- graph_->set_color("consume-time", diagnostics::color(1.0f, 0.4f, 0.0f));\r
+ graph_->set_color("consume-time", diagnostics::color(1.0f, 0.4f, 0.0f, 0.8));\r
} \r
\r
void add(int index, safe_ptr<frame_consumer> consumer)\r
}\r
}\r
\r
- graph_->update_value("consume-time", consume_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("consume-time", consume_timer_.elapsed()*format_desc_.fps*0.5);\r
}\r
catch(...)\r
{\r
\r
auto max = boost::range::max_element(result);\r
\r
- graph_->update_value("volume", static_cast<double>(std::abs(*max))/std::numeric_limits<int32_t>::max());\r
+ graph_->set_value("volume", static_cast<double>(std::abs(*max))/std::numeric_limits<int32_t>::max());\r
\r
return result;\r
}\r
, audio_mixer_(graph_)\r
, executor_(L"mixer")\r
{ \r
- graph_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 0.9f));\r
+ graph_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 0.9f, 0.8));\r
}\r
\r
void send(const std::pair<std::map<int, safe_ptr<core::basic_frame>>, std::shared_ptr<void>>& packet)\r
auto audio = audio_mixer_(format_desc_);\r
image.wait();\r
\r
- graph_->update_value("mix-time", mix_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("mix-time", mix_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
target_->send(std::make_pair(make_safe<read_frame>(ogl_, format_desc_.size, std::move(image.get()), std::move(audio)), packet.second)); \r
}\r
, target_(target)\r
, executor_(L"stage")\r
{\r
- graph_->add_guide("tick-time", 0.5f); \r
- graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); \r
+ graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f, 0.8)); \r
graph_->set_color("produce-time", diagnostics::color(0.0f, 1.0f, 0.0f));\r
}\r
\r
frames[layer.first] = frame1;\r
});\r
\r
- graph_->update_value("produce-time", produce_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("produce-time", produce_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
std::shared_ptr<void> ticket(nullptr, [self](void*)\r
{\r
\r
target_->send(std::make_pair(frames, ticket));\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
{\r
executor_.set_capacity(1);\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_->add_guide("frame-time", 0.5f); \r
graph_->set_color("sync-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
graph_->set_color("frame-time", diagnostics::color(0.5f, 1.0f, 0.2f));\r
graph_->set_text(print());\r
try\r
{ \r
display_frame(frame); \r
- graph_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()*format_desc_.fps*0.5));\r
+ graph_->set_value("tick-time", static_cast<float>(tick_timer_.elapsed()*format_desc_.fps*0.5));\r
tick_timer_.restart();\r
}\r
catch(...)\r
sync_timer_.restart();\r
unsigned long n_field = 0;\r
blue_->wait_output_video_synch(UPD_FMT_FRAME, n_field);\r
- graph_->update_value("sync-time", sync_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("sync-time", sync_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
frame_timer_.restart(); \r
\r
\r
boost::range::rotate(reserved_frames_, std::begin(reserved_frames_)+1);\r
\r
- graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
+ graph_->set_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
}\r
\r
void encode_hanc(BLUE_UINT32* hanc_data, void* audio_data, size_t audio_samples, size_t audio_nchannels)\r
video_frame_buffer_.set_capacity(1);\r
audio_frame_buffer_.set_capacity(1);\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("late-frame", diagnostics::color(0.6f, 0.3f, 0.3f));\r
graph_->set_color("dropped-frame", diagnostics::color(0.3f, 0.6f, 0.3f));\r
{\r
if(result == bmdOutputFrameDisplayedLate)\r
{\r
- graph_->add_tag("late-frame");\r
+ graph_->set_tag("late-frame");\r
video_scheduled_ += format_desc_.duration;\r
audio_scheduled_ += reinterpret_cast<decklink_frame*>(completed_frame)->audio_data().size()/format_desc_.audio_channels;\r
//++video_scheduled_;\r
//++audio_scheduled_;\r
}\r
else if(result == bmdOutputFrameDropped)\r
- graph_->add_tag("dropped-frame");\r
+ graph_->set_tag("dropped-frame");\r
else if(result == bmdOutputFrameFlushed)\r
- graph_->add_tag("flushed-frame");\r
+ graph_->set_tag("flushed-frame");\r
\r
std::shared_ptr<core::read_frame> frame; \r
video_frame_buffer_.pop(frame); \r
\r
unsigned long buffered;\r
output_->GetBufferedVideoFrameCount(&buffered);\r
- graph_->update_value("buffered-video", static_cast<double>(buffered)/format_desc_.fps);\r
+ graph_->set_value("buffered-video", static_cast<double>(buffered)/format_desc_.fps);\r
}\r
catch(...)\r
{\r
\r
unsigned long buffered;\r
output_->GetBufferedAudioSampleFrameCount(&buffered);\r
- graph_->update_value("buffered-audio", static_cast<double>(buffered)/(format_desc_.audio_cadence[0]*2));\r
+ graph_->set_value("buffered-audio", static_cast<double>(buffered)/(format_desc_.audio_cadence[0]*2));\r
}\r
catch(...)\r
{\r
\r
video_scheduled_ += format_desc_.duration;\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
\r
hints_ = 0;\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("late-frame", diagnostics::color(0.6f, 0.3f, 0.3f));\r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
\r
try\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
frame_timer_.restart();\r
for(auto frame = muxer_.poll(); frame; frame = muxer_.poll())\r
{\r
if(!frame_buffer_.try_push(make_safe_ptr(frame)))\r
- graph_->add_tag("dropped-frame");\r
+ graph_->set_tag("dropped-frame");\r
}\r
\r
- graph_->update_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity())); \r
}\r
\r
safe_ptr<core::basic_frame> frame = core::basic_frame::late();\r
if(!frame_buffer_.try_pop(frame))\r
- graph_->add_tag("late-frame");\r
+ graph_->set_tag("late-frame");\r
graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity())); \r
return frame;\r
}\r
// TODO: Ask stakeholders about case where file already exists.\r
boost::filesystem2::remove(boost::filesystem2::wpath(env::media_folder() + widen(filename))); // Delete the file if it exists\r
\r
- graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
graph_->set_color("write-time", diagnostics::color(0.5f, 0.5f, 0.1f));\r
graph_->set_text(print());\r
auto video = encode_video_frame(frame);\r
auto audio = encode_audio_frame(frame);\r
\r
- graph_->update_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
file_write_executor_.begin_invoke([=]\r
{\r
if(audio)\r
av_write_frame(oc_.get(), audio.get());\r
\r
- graph_->update_value("write-time", write_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("write-time", write_timer_.elapsed()*format_desc_.fps*0.5);\r
});\r
});\r
}\r
, last_frame_(core::basic_frame::empty())\r
, frame_number_(0)\r
{\r
- graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
graph_->set_color("underflow", diagnostics::color(0.6f, 0.3f, 0.9f)); \r
diagnostics::register_graph(graph_);\r
for(int n = 0; n < 16 && frame_buffer_.size() < 2; ++n)\r
try_decode_frame(hints);\r
\r
- graph_->update_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
\r
if(frame_buffer_.empty() && input_.eof())\r
return last_frame();\r
\r
if(frame_buffer_.empty())\r
{\r
- graph_->add_tag("underflow"); \r
+ graph_->set_tag("underflow"); \r
return core::basic_frame::late(); \r
}\r
\r
buffer_cond_.notify_all();\r
}\r
\r
- graph_->update_value("buffer-size", (static_cast<double>(buffer_size_)+0.001)/MAX_BUFFER_SIZE);\r
- graph_->update_value("buffer-count", (static_cast<double>(buffer_.size()+0.001)/MAX_BUFFER_COUNT));\r
+ graph_->set_value("buffer-size", (static_cast<double>(buffer_size_)+0.001)/MAX_BUFFER_SIZE);\r
+ graph_->set_value("buffer-count", (static_cast<double>(buffer_.size()+0.001)/MAX_BUFFER_COUNT));\r
\r
return result;\r
}\r
if(loop_)\r
{\r
do_seek(start_);\r
- graph_->add_tag("seek"); \r
+ graph_->set_tag("seek"); \r
CASPAR_LOG(trace) << print() << " Looping."; \r
} \r
}\r
buffer_.try_push(packet);\r
buffer_size_ += packet->size;\r
\r
- graph_->update_value("buffer-size", (static_cast<double>(buffer_size_)+0.001)/MAX_BUFFER_SIZE);\r
- graph_->update_value("buffer-count", (static_cast<double>(buffer_.size()+0.001)/MAX_BUFFER_COUNT));\r
+ graph_->set_value("buffer-size", (static_cast<double>(buffer_size_)+0.001)/MAX_BUFFER_SIZE);\r
+ graph_->set_value("buffer-count", (static_cast<double>(buffer_.size()+0.001)/MAX_BUFFER_COUNT));\r
} \r
}\r
\r
, width_(width)\r
, height_(height)\r
{ \r
- graph_->add_guide("frame-time", 0.5f);\r
graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\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("param", diagnostics::color(1.0f, 0.5f, 0.0f)); \r
graph_->set_color("skip-sync", diagnostics::color(0.8f, 0.3f, 0.2f)); \r
\r
if(!ax_->FlashCall(param, result))\r
CASPAR_LOG(warning) << print() << L" Flash call failed:" << param;//BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Flash function call failed.") << arg_name_info("param") << arg_value_info(narrow(param)));\r
- graph_->add_tag("param");\r
+ graph_->set_tag("param");\r
\r
return result;\r
}\r
{\r
float frame_time = 1.0f/ax_->GetFPS();\r
\r
- graph_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()/frame_time)*0.5f);\r
+ graph_->set_value("tick-time", static_cast<float>(tick_timer_.elapsed()/frame_time)*0.5f);\r
tick_timer_.restart();\r
\r
if(ax_->IsEmpty())\r
if(!has_underflow) \r
timer_.tick(frame_time); // This will block the thread.\r
else\r
- graph_->add_tag("skip-sync");\r
+ graph_->set_tag("skip-sync");\r
\r
frame_timer_.restart();\r
\r
head_ = frame;\r
} \r
\r
- graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()/frame_time)*0.5f);\r
+ graph_->set_value("frame-time", static_cast<float>(frame_timer_.elapsed()/frame_time)*0.5f);\r
return head_;\r
}\r
\r
\r
auto frame = core::basic_frame::late();\r
if(!frame_buffer_.try_pop(frame) && context_)\r
- graph_->add_tag("underflow");\r
+ graph_->set_tag("underflow");\r
\r
return frame;\r
}\r
\r
graph_->set_value("output-buffer-count", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity())); \r
fps_.fetch_and_store(static_cast<int>(context_->fps()*100.0)); \r
- graph_->set_text(narrow(print()));\r
+ graph_->set_text(print());\r
\r
render(renderer);\r
}\r
: container_(16)\r
, channel_index_(-1)\r
{\r
- graph_->add_guide("tick-time", 0.5);\r
graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); \r
diagnostics::register_graph(graph_);\r
\r
data.Samples = container_.back().data();\r
data.NbSamples = container_.back().size(); \r
\r
- graph_->update_value("tick-time", perf_timer_.elapsed()*format_desc_.fps*0.5); \r
+ graph_->set_value("tick-time", perf_timer_.elapsed()*format_desc_.fps*0.5); \r
perf_timer_.restart();\r
\r
return is_running_;\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
\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
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