Measure stream viewer request and worker delays

This commit is contained in:
evgeny committed 2026-10-20 22:30:04 +02:00
1 parent 7ce60ca0f2
commit c6f7d50838
3 files changed
+19 -4

No files matched your search

+17 -3
View File
@@ -19,6 +19,8 @@ struct viewer {
int64_t position, audio_ahead;
uint64_t replies, fulfilled_repeats; /* Выданные ответы и погашенные ими повторные запросы. */
uint64_t created_us, prepared_us, report_us;
/* Время подготовки ответа и его ожидания до pull; статистика за отчётный интервал. */
uint64_t demand_us, delivered, prepare_total_us, prepare_max_us, handoff_total_us, handoff_max_us;
unsigned first_records; /* Диагностика первой выдачи VIDEO/AUDIO; не влияет на cursor. */
};
struct stream_viewers {
@@ -129,17 +131,20 @@ static void process(void *arg) {
uint64_t now = get_time_us();
if (now - s->report_us >= 1000000) {
s->report_us = now;
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM,
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
"viewer buffer id=%llu source=%llx epoch=%llx elapsed_us=%llu initialized=%d generation=%llu "
"start_us=%lld position_us=%lld ready_us=%lld video_us=%lld audio_us=%lld reserve_us=%lld "
"requested=%d waiting=%d slot=%d slot_age_us=%llu",
"requested=%d waiting=%d slot=%d slot_age_us=%llu records=%llu prepare_us=%llu/%llu handoff_us=%llu/%llu timing=mean/max",
(unsigned long long)s->id, (unsigned long long)s->source, (unsigned long long)s->epoch,
(unsigned long long)(now - s->created_us), s->status.initialized, (unsigned long long)s->status.generation,
(long long)s->status.start_us, (long long)s->position, (long long)s->status.ready_us,
(long long)s->status.video_us, (long long)s->status.audio_us,
(long long)(s->status.initialized && s->position >= 0 ? s->status.ready_us - s->position : -1),
s->requested, s->waiting, s->record ? s->record->kind : 0,
(unsigned long long)(s->record ? now - s->prepared_us : 0));
(unsigned long long)(s->record ? now - s->prepared_us : 0), (unsigned long long)s->delivered,
(unsigned long long)(s->delivered ? s->prepare_total_us / s->delivered : 0), (unsigned long long)s->prepare_max_us,
(unsigned long long)(s->delivered ? s->handoff_total_us / s->delivered : 0), (unsigned long long)s->handoff_max_us);
s->delivered = s->prepare_total_us = s->prepare_max_us = s->handoff_total_us = s->handoff_max_us = 0;
}
if (!s->requested || s->waiting || s->record) continue;
s->requested = 0;
@@ -231,6 +236,13 @@ struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *v, uint64
struct stream_viewer_record *r = s && !s->stopping ? s->record : NULL;
if (r) {
unsigned bit = r->kind == STREAM_VIEWER_VIDEO ? 1 : r->kind == STREAM_VIEWER_AUDIO ? 2 : 0;
if (bit) {
uint64_t handoff = get_time_us() - s->prepared_us;
uint64_t prepare = s->demand_us && s->prepared_us >= s->demand_us ? s->prepared_us - s->demand_us : 0;
s->delivered++; s->prepare_total_us += prepare; s->handoff_total_us += handoff;
if (prepare > s->prepare_max_us) s->prepare_max_us = prepare;
if (handoff > s->handoff_max_us) s->handoff_max_us = handoff;
}
if (bit && !(s->first_records & bit)) {
uint64_t now = get_time_us(); s->first_records |= bit;
DEBUG_INFO(DEBUG_CATEGORY_STREAM,
@@ -263,6 +275,7 @@ int stream_viewer_request(struct stream_viewers *v, uint64_t id, int64_t positio
int result = -1;
if (s && !s->stopping && (s->opening || s->handle)) {
int changed = s->position != position || s->video != video || s->audio_ahead != audio_ahead;
if (!s->requested && !s->record) s->demand_us = get_time_us();
s->position = position; s->video = video; s->audio_ahead = audio_ahead; s->requested = video || audio_ahead >= 0;
result = 0;
if (s->requested && !s->record && (!s->waiting || changed)) { s->waiting = 0; result = schedule(v); }
@@ -287,6 +300,7 @@ int stream_viewer_resync(struct stream_viewers *v, uint64_t id) {
if (s && s->handle && !s->stopping && schedule(v) == 0) {
u_free(s->record); s->record = NULL;
memset(&s->status, 0, sizeof(s->status));
s->demand_us = get_time_us();
s->resync = s->requested = 1; s->waiting = 0; s->position = -1; result = 0;
}
pthread_mutex_unlock(&v->lock); return result;
+1 -1
View File
@@ -293,7 +293,7 @@ void StreamPlayerWindow::decode() {
/* Забираем выход прежде следующего входа. При FIN тот же проход дренирует codec до EOF. */
auto drainVideo = [&] {
if (!decoder) return;
for (unsigned work = 0; work < 8 && p.running; work++) {
for (unsigned attempt = 0; attempt < 8 && p.running; attempt++) {
{ std::lock_guard<std::mutex> guard(p.lock); if (p.videos.size() >= 2) return; }
int64_t codecAt = nowUs();
int result = avcodec_receive_frame(decoder, frame);
+1
View File
@@ -208,6 +208,7 @@ private slots:
void initTestCase() {
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); debug_set_category_level(DEBUG_CATEGORY_STREAM, DEBUG_LEVEL_INFO);
if (qEnvironmentVariableIsSet("UTUN_TEST_DEBUG")) {
debug_set_category_level(DEBUG_CATEGORY_DEBUG, DEBUG_LEVEL_DEBUG);
debug_set_category_level(DEBUG_CATEGORY_STREAM, DEBUG_LEVEL_TRACE);
debug_set_category_level(DEBUG_CATEGORY_VIDEO, DEBUG_LEVEL_TRACE);
}