X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mixer.cpp;h=4560bbb4976fc74b497c24e16ceee465f52c33db;hb=cac2642ad13c118b70f08f85adbdfe62913251b6;hp=ccbbf1a089b27b8a2f9694d63f2d8e8fc31eea7a;hpb=0f603d88d39c89dc3476b65d65a8bd2072aed782;p=nageru diff --git a/mixer.cpp b/mixer.cpp index ccbbf1a..4560bbb 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -198,8 +198,17 @@ void upload_texture(GLuint tex, GLuint width, GLuint height, GLuint stride, bool } // namespace +void QueueLengthPolicy::register_metrics(const vector> &labels) +{ + global_metrics.add("input_queue_length_frames", labels, &metric_input_queue_length_frames, Metrics::TYPE_GAUGE); + global_metrics.add("input_queue_safe_length_frames", labels, &metric_input_queue_safe_length_frames, Metrics::TYPE_GAUGE); + global_metrics.add("input_queue_duped_frames", labels, &metric_input_duped_frames); +} + void QueueLengthPolicy::update_policy(unsigned queue_length) { + metric_input_queue_length_frames = queue_length; + if (queue_length == 0) { // Starvation. if (been_at_safe_point_since_last_starvation && safe_queue_length < unsigned(global_flags.max_input_queue_frames)) { ++safe_queue_length; @@ -208,6 +217,8 @@ void QueueLengthPolicy::update_policy(unsigned queue_length) } frames_with_at_least_one = 0; been_at_safe_point_since_last_starvation = false; + ++metric_input_duped_frames; + metric_input_queue_safe_length_frames = safe_queue_length; return; } if (queue_length >= safe_queue_length) { @@ -215,6 +226,7 @@ void QueueLengthPolicy::update_policy(unsigned queue_length) } if (++frames_with_at_least_one >= 1000 && safe_queue_length > 1) { --safe_queue_length; + metric_input_queue_safe_length_frames = safe_queue_length; fprintf(stderr, "Card %u: Spare frames for more than 1000 frames, reducing safe limit to %u frame(s)\n", card_index, safe_queue_length); frames_with_at_least_one = 0; @@ -390,9 +402,13 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards) set_output_card_internal(global_flags.output_card); } - global_metrics.register_int_metric("frames_output_total", &metric_frames_output_total); - global_metrics.register_int_metric("frames_output_dropped", &metric_frames_output_dropped); - global_metrics.register_double_metric("uptime_seconds", &metric_uptime_seconds); + metric_start_time_seconds = get_timestamp_for_metrics(); + + global_metrics.add("frames_output_total", &metric_frames_output_total); + global_metrics.add("frames_output_dropped", &metric_frames_output_dropped); + global_metrics.add("start_time_seconds", &metric_start_time_seconds, Metrics::TYPE_GAUGE); + global_metrics.add("memory_used_bytes", &metrics_memory_used_bytes); + global_metrics.add("metrics_memory_locked_limit_bytes", &metrics_memory_locked_limit_bytes); } Mixer::~Mixer() @@ -458,6 +474,39 @@ void Mixer::configure_card(unsigned card_index, CaptureInterface *capture, CardT audio_mixer.reset_resampler(device); audio_mixer.set_display_name(device, card->capture->get_description()); audio_mixer.trigger_state_changed_callback(); + + // Register metrics. + vector> labels; + char card_name[64]; + snprintf(card_name, sizeof(card_name), "%d", card_index); + labels.emplace_back("card", card_name); + + switch (card_type) { + case CardType::LIVE_CARD: + labels.emplace_back("cardtype", "live"); + break; + case CardType::FAKE_CAPTURE: + labels.emplace_back("cardtype", "fake"); + break; + case CardType::FFMPEG_INPUT: + labels.emplace_back("cardtype", "ffmpeg"); + break; + default: + assert(false); + } + card->queue_length_policy.register_metrics(labels); + global_metrics.add("input_dropped_frames_jitter", labels, &card->metric_input_dropped_frames_jitter); + global_metrics.add("input_dropped_frames_error", labels, &card->metric_input_dropped_frames_error); + global_metrics.add("input_dropped_frames_resets", labels, &card->metric_input_resets); + + global_metrics.add("input_has_signal_bool", labels, &card->metric_input_has_signal_bool, Metrics::TYPE_GAUGE); + global_metrics.add("input_is_connected_bool", labels, &card->metric_input_is_connected_bool, Metrics::TYPE_GAUGE); + global_metrics.add("input_interlaced_bool", labels, &card->metric_input_interlaced_bool, Metrics::TYPE_GAUGE); + global_metrics.add("input_width_pixels", labels, &card->metric_input_width_pixels, Metrics::TYPE_GAUGE); + global_metrics.add("input_height_pixels", labels, &card->metric_input_height_pixels, Metrics::TYPE_GAUGE); + global_metrics.add("input_frame_rate_nom", labels, &card->metric_input_frame_rate_nom, Metrics::TYPE_GAUGE); + global_metrics.add("input_frame_rate_den", labels, &card->metric_input_frame_rate_den, Metrics::TYPE_GAUGE); + global_metrics.add("input_sample_rate_hz", labels, &card->metric_input_sample_rate_hz, Metrics::TYPE_GAUGE); } void Mixer::set_output_card_internal(int card_index) @@ -523,6 +572,15 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode, DeviceSpec device{InputSourceType::CAPTURE_CARD, card_index}; CaptureCard *card = &cards[card_index]; + card->metric_input_has_signal_bool = video_format.has_signal; + card->metric_input_is_connected_bool = video_format.is_connected; + card->metric_input_interlaced_bool = video_format.interlaced; + card->metric_input_width_pixels = video_format.width; + card->metric_input_height_pixels = video_format.height; + card->metric_input_frame_rate_nom = video_format.frame_rate_nom; + card->metric_input_frame_rate_den = video_format.frame_rate_den; + card->metric_input_sample_rate_hz = audio_format.sample_rate; + if (is_mode_scanning[card_index]) { if (video_format.has_signal) { // Found a stable signal, so stop scanning. @@ -572,10 +630,12 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode, card_index, card->last_timecode, timecode); audio_mixer.reset_resampler(device); dropped_frames = 0; + ++card->metric_input_resets; } else if (dropped_frames > 0) { // Insert silence as needed. fprintf(stderr, "Card %d dropped %d frame(s) (before timecode 0x%04x), inserting silence.\n", card_index, dropped_frames, timecode); + card->metric_input_dropped_frames_error += dropped_frames; bool success; do { @@ -879,7 +939,6 @@ void Mixer::thread_func() metric_frames_output_total = frame_num; metric_frames_output_dropped = stats_dropped_frames; - metric_uptime_seconds = elapsed; if (frame_num % 100 == 0) { printf("%d frames (%d dropped) in %.3f seconds = %.1f fps (%.1f ms/frame)", @@ -911,12 +970,16 @@ void Mixer::thread_func() long(limit.rlim_cur / 1048576), float(100.0 * (used.ru_maxrss * 1024.0) / limit.rlim_cur)); } + metrics_memory_locked_limit_bytes = limit.rlim_cur; } else { printf(", using %ld MB memory (not locked)", long(used.ru_maxrss / 1024)); + metrics_memory_locked_limit_bytes = 0.0 / 0.0; } printf("\n"); + + metrics_memory_used_bytes = used.ru_maxrss; } @@ -984,6 +1047,8 @@ void Mixer::trim_queue(CaptureCard *card, unsigned card_index) ++dropped_frames; } + card->metric_input_dropped_frames_jitter += dropped_frames; + #if 0 if (dropped_frames > 0) { fprintf(stderr, "Card %u dropped %u frame(s) to keep latency down.\n",