Consume repeated viewer demand when delivering its reply
This commit is contained in:
1 parent
68fb937063
commit
ea5d1fcd45
3 files changed
+45
-5
No files matched your search
@@ -17,6 +17,7 @@ struct viewer {
|
||||
int opening, stopping, resync, requested, waiting;
|
||||
int video;
|
||||
int64_t position, audio_ahead;
|
||||
uint64_t replies, fulfilled_repeats; /* Выданные ответы и погашенные ими повторные запросы. */
|
||||
};
|
||||
struct stream_viewers {
|
||||
pthread_mutex_t lock;
|
||||
@@ -66,8 +67,9 @@ static void close_viewer(struct viewer *s, enum stream_viewer_kind kind, int rea
|
||||
if (s->handle) stream_close(s->handle);
|
||||
s->handle = NULL; s->opening = s->requested = s->waiting = s->resync = 0;
|
||||
if (kind) output(s, kind, reason, NULL);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "viewer released id=%llu group=%llx source=%llx kind=%d reason=%d",
|
||||
(unsigned long long)s->id, (unsigned long long)s->group, (unsigned long long)s->source, kind, reason);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "viewer released id=%llu group=%llx source=%llx kind=%d reason=%d replies=%llu repeats=%llu",
|
||||
(unsigned long long)s->id, (unsigned long long)s->group, (unsigned long long)s->source, kind, reason,
|
||||
(unsigned long long)s->replies, (unsigned long long)s->fulfilled_repeats);
|
||||
}
|
||||
|
||||
/* Событие будит всех readers этой эпохи, не меняя их независимые позиции и запросы. */
|
||||
@@ -207,7 +209,16 @@ struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *v, uint64
|
||||
pthread_mutex_lock(&v->lock);
|
||||
struct viewer *s = find(v, id);
|
||||
struct stream_viewer_record *r = s && !s->stopping ? s->record : NULL;
|
||||
if (r) s->record = NULL;
|
||||
if (r) {
|
||||
/* Ответ обслуживает и повторный request: AVAILABLE не должен прочитать следующий кадр до нового demand. */
|
||||
int repeated = s->requested;
|
||||
s->record = NULL; s->requested = 0; s->replies++;
|
||||
if (repeated) s->fulfilled_repeats++;
|
||||
if (s->replies == 1 || (repeated && (s->fulfilled_repeats == 1 || s->fulfilled_repeats % 256 == 0)))
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "viewer reply id=%llu kind=%d pts=%llu repeated=%d replies=%llu repeats=%llu pending=0",
|
||||
(unsigned long long)s->id, r->kind, (unsigned long long)r->pts, repeated,
|
||||
(unsigned long long)s->replies, (unsigned long long)s->fulfilled_repeats);
|
||||
}
|
||||
pthread_mutex_unlock(&v->lock); return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ void stream_viewers_destroy(struct stream_viewers *viewers);
|
||||
* Открытие асинхронно: OPENED/CLOSED возвращается через pull. tracks — VIDEO или VIDEO|AUDIO. */
|
||||
int stream_viewer_open(struct stream_viewers *viewers, uint64_t id, uint64_t group, uint64_t source, uint64_t epoch, unsigned tracks);
|
||||
void stream_viewer_stop(struct stream_viewers *viewers, uint64_t id);
|
||||
/* Один owned ответ или NULL. Новые данные запрашиваются request; idle не копирует кольцо. */
|
||||
/* Один owned ответ или NULL. Выдача ответа погашает demand, включая повторный request до pull.
|
||||
* NULL сохраняет ожидающий запрос. Следующие данные требуют нового request; idle не копирует кольцо. */
|
||||
struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *viewers, uint64_t id);
|
||||
/* Позиция и audio_ahead относятся только к этому reader; повторный demand заменяет прежний.
|
||||
* 0 — принято, -1 — неизвестный/закрытый ID или ошибка scheduling. */
|
||||
|
||||
Reference in new issue
Block a user