#include <boost/circular_buffer.hpp>\r
#include <boost/range/algorithm_ext/erase.hpp>\r
\r
+#include <tbb/concurrent_unordered_map.h>\r
+#include <tbb/atomic.h>\r
+\r
#include <numeric>\r
-#include <map>\r
#include <array>\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
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
};\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
\r
- boost::circular_buffer<double> tick_data_;\r
- bool tick_tag_;\r
- color c_;\r
+ tbb::atomic<double> 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_ = 0;\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
- {\r
- tick_data_.push_back(value);\r
- }\r
-\r
- void set(double value)\r
+ void set_value(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
struct graph::implementation : 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
+ tbb::concurrent_unordered_map<std::string, diagnostics::line> lines_;\r
+ std::wstring text_;\r
+ \r
+ implementation()\r
{\r
- text_ = value;\r
}\r
\r
- void update(const std::string& name, double value)\r
+ void set_text(const std::wstring& value)\r
{\r
- lines_[name].update(value);\r
+ text_ = value;\r
}\r
\r
- void set(const std::string& name, double value)\r
+ void set_value(const std::string& name, double value)\r
{\r
- lines_[name].set(value);\r
+ lines_[name].set_value(value);\r
}\r
\r
- void tag(const std::string& name)\r
+ void set_tag(const std::string& name)\r
{\r
- lines_[name].tag();\r
+ lines_[name].set_tag();\r
}\r
\r
- void set_color(const std::string& name, color c)\r
+ void set_color(const std::string& name, int color)\r
{\r
- lines_[name].set_color(c);\r
+ lines_[name].set_color(color);\r
}\r
- \r
- void guide(const std::string& name, double value)\r
- {\r
- lines_[name].guide(diagnostics::guide(value)); \r
- }\r
- \r
+ \r
private:\r
void render(sf::RenderTarget& target)\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(0.8f, 0.8f, 0.8f, 1.0f); \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
implementation& operator=(implementation&);\r
};\r
\r
-graph::graph() : impl_(new implementation(""))\r
+graph::graph() : impl_(new implementation())\r
{\r
-\r
}\r
\r
-void graph::set_text(const std::string& value)\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(u8(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
// : 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
//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
// implementation(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
//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
+//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
#include "../memory/safe_ptr.h"\r
\r
#include <string>\r
+#include <tuple>\r
\r
namespace caspar { namespace diagnostics {\r
\r
-struct color\r
-{\r
- float red;\r
- float green;\r
- float blue;\r
- float alpha;\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
}\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
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_.width, format_desc_.height, 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("produce-time", diagnostics::color(0.0f, 1.0f, 0.0f));\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, int audio_samples, int 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
flags_ = 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::filesystem::remove(boost::filesystem::path(env::media_folder() + 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(flags);\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() << wmsg_info("Flash function call failed.") << arg_name_info("param") << arg_value_info(u8(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", (tick_timer_.elapsed()/frame_time)*0.5f);\r
+ graph_->set_value("tick-time", (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
: 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