set(SOURCES
diagnostics/graph.cpp
+ diagnostics/graph_to_log_sink.cpp
gl/gl_check.cpp
endif ()
set(HEADERS
diagnostics/graph.h
+ diagnostics/graph_to_log_sink.h
gl/gl_check.h
sink->set_value(name, value);
}
- void set_tag(const std::string& name)
+ void set_tag(tag_severity severity, const std::string& name)
{
for (auto& sink : sinks_)
- sink->set_tag(name);
+ sink->set_tag(severity, name);
}
void set_color(const std::string& name, int color)
void graph::set_text(const std::wstring& value) { impl_->set_text(value); }
void graph::set_value(const std::string& name, double value) { impl_->set_value(name, value); }
void graph::set_color(const std::string& name, int color) { impl_->set_color(name, color); }
-void graph::set_tag(const std::string& name) { impl_->set_tag(name); }
+void graph::set_tag(tag_severity severity, const std::string& name) { impl_->set_tag(severity, name); }
void graph::auto_reset() { impl_->auto_reset(); }
void register_graph(const spl::shared_ptr<graph>& graph)
int color(float r, float g, float b, float a = 1.0f);
std::tuple<float, float, float, float> color(int code);
+enum class tag_severity
+{
+ WARNING,
+ INFO
+};
+
class graph : boost::noncopyable
{
friend void register_graph(const spl::shared_ptr<graph>& graph);
void set_text(const std::wstring& value);
void set_value(const std::string& name, double value);
void set_color(const std::string& name, int color);
- void set_tag(const std::string& name);
+ void set_tag(tag_severity severity, const std::string& name);
void auto_reset();
private:
struct impl;
virtual void set_text(const std::wstring& value) = 0;
virtual void set_value(const std::string& name, double value) = 0;
virtual void set_color(const std::string& name, int color) = 0;
- virtual void set_tag(const std::string& name) = 0;
+ virtual void set_tag(tag_severity severity, const std::string& name) = 0;
virtual void auto_reset() = 0;
};
--- /dev/null
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#include "graph_to_log_sink.h"
+
+#include "../log.h"
+
+#include <tbb/spin_mutex.h>
+
+namespace caspar { namespace diagnostics {
+
+class graph_to_log_sink : public spi::graph_sink
+{
+ tbb::spin_mutex mutex_;
+ std::wstring text_;
+public:
+ void activate() override
+ {
+ }
+
+ void set_text(const std::wstring& value) override
+ {
+ tbb::spin_mutex::scoped_lock lock(mutex_);
+ text_ = value;
+ }
+
+ void set_value(const std::string& name, double value) override
+ {
+ }
+
+ void set_color(const std::string& name, int color) override
+ {
+ }
+
+ void set_tag(tag_severity severity, const std::string& name) override
+ {
+ tbb::spin_mutex::scoped_lock lock(mutex_);
+
+ switch (severity)
+ {
+ case tag_severity::INFO:
+ CASPAR_LOG(trace) << L"[diagnostics] [" << text_ << L"] " << name;
+ break;
+ case tag_severity::WARNING:
+ CASPAR_LOG(warning) << L"[diagnostics] [" << text_ << L"] " << name;
+ break;
+ }
+ }
+
+ void auto_reset() override
+ {
+ }
+};
+
+void register_graph_to_log_sink()
+{
+ spi::register_sink_factory([] { return spl::make_shared<graph_to_log_sink>(); });
+}
+
+}}
--- /dev/null
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#pragma once
+
+#include "../memory.h"
+#include "graph.h"
+
+namespace caspar { namespace diagnostics {
+
+void register_graph_to_log_sink();
+
+}}
lines_[name].set_value(value);
}
- void set_tag(const std::string& name) override
+ void set_tag(caspar::diagnostics::tag_severity /*severity*/, const std::string& name) override
{
lines_[name].set_tag();
}
*subject_ << monitor::message("/color/" + name) % color;
}
- void set_tag(const std::string& name) override
+ void set_tag(caspar::diagnostics::tag_severity severity, const std::string& name) override
{
- *subject_ << monitor::message("/tag/" + name);
+ std::string severity_path;
+
+ switch (severity)
+ {
+ case caspar::diagnostics::tag_severity::INFO:
+ severity_path = "info/";
+ break;
+ case caspar::diagnostics::tag_severity::WARNING:
+ severity_path = "warning/";
+ break;
+ }
+
+ *subject_ << monitor::message("/tag/" + severity_path + name);
send_full_state_if_long_ago();
}
if(result == bmdOutputFrameDisplayedLate)
{
- graph_->set_tag("late-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "late-frame");
video_scheduled_ += format_desc_.duration;
audio_scheduled_ += dframe->audio_data().size() / out_channel_layout_.num_channels;
//++video_scheduled_;
//++audio_scheduled_;
}
else if(result == bmdOutputFrameDropped)
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
else if(result == bmdOutputFrameFlushed)
- graph_->set_tag("flushed-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "flushed-frame");
auto frame = core::const_frame::empty();
video_frame_buffer_.pop(frame);
frame_buffer_.try_pop(dummy);
frame_buffer_.try_push(frame);
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
}
}
core::draw_frame frame = core::draw_frame::late();
if(!frame_buffer_.try_pop(frame))
- graph_->set_tag("late-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "late-frame");
graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity()));
return frame;
}
void mark_dropped()
{
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
}
std::wstring print() const
muxer_->pop();
}
else
- graph_->set_tag("underflow");
-
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "underflow");
+
graph_->set_value("frame-time", frame_timer.elapsed()*format_desc_.fps*0.5);
*monitor_subject_
<< core::monitor::message("/profiler/time") % frame_timer.elapsed() % (1.0/format_desc_.fps);
private:
void internal_seek(uint32_t target)
{
- graph_->set_tag("seek");
+ graph_->set_tag(diagnostics::tag_severity::INFO, "seek");
CASPAR_LOG(debug) << print() << " Seeking: " << target;
if (boost::starts_with(result, L"<exception>"))
CASPAR_LOG(warning) << print() << L" Flash call failed:" << result;
- graph_->set_tag("param");
+ graph_->set_tag(diagnostics::tag_severity::INFO, "param");
return result;
}
if (output_buffer_.try_pop(frame))
last_frame_ = frame;
else
- graph_->set_tag("late-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "late-frame");
fill_buffer();
while (frames_.size() > max_in_queue)
{
frames_.pop();
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
}
});
graph_->set_value("copy-time", copy_timer.elapsed()
}
else
{
- graph_->set_tag("late-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "late-frame");
if (format_desc_.field_mode != core::field_mode::progressive)
{
if (executor_.size() > 0 || executor_.is_currently_in_task())
{
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
return make_ready_future(true);
}
}
}
alSourcePlay(source_);
- graph_->set_tag("late-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "late-frame");
}
auto audio = core::audio_32_to_16(channel_remapper_->mix_and_rearrange(frame.audio_data()));
alSourceQueueBuffers(source_, 1, &buffer);
}
else
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
graph_->set_value("tick-time", perf_timer_.elapsed()*format_desc_.fps*0.5);
perf_timer_.restart();
std::future<bool> send(core::const_frame frame)
{
if(!frame_buffer_.try_push(frame))
- graph_->set_tag("dropped-frame");
+ graph_->set_tag(diagnostics::tag_severity::WARNING, "dropped-frame");
return make_ready_future(is_running_.load());
}
#include <common/utf.h>
#include <common/memory.h>
#include <common/polling_filesystem_monitor.h>
+#include <common/diagnostics/graph_to_log_sink.h>
#include <core/video_channel.h>
#include <core/video_format.h>
, shutdown_server_now_(shutdown_server_now)
{
running_ = false;
- core::diagnostics::osd::register_sink();
+ caspar::diagnostics::register_graph_to_log_sink();
+ caspar::core::diagnostics::osd::register_sink();
diag_subject_->attach_parent(monitor_subject_);
module_dependencies dependencies(