diff --git a/src/stream/stream_viewer.h b/src/stream/stream_viewer.h index 9fc91d90..bcc281b2 100644 --- a/src/stream/stream_viewer.h +++ b/src/stream/stream_viewer.h @@ -35,6 +35,7 @@ void stream_viewer_stop(struct stream_viewers *viewers, uint64_t id); /* Owned батч или NULL. Выдача батча погашает demand, включая повторный request до pull. * NULL сохраняет ожидающий запрос. Следующие данные требуют нового request; idle не копирует кольцо. */ struct stream_viewer_record *stream_viewer_pull(struct stream_viewers *viewers, uint64_t id); +/* Освобождает всю owned цепочку и payload каждой записи; NULL допустим. */ void stream_viewer_records_free(struct stream_viewer_record *records); /* Позиция и audio_ahead относятся только к этому reader; повторный demand заменяет прежний. * video — максимум видеокадров; records — максимум всех записей, 1..STREAM_VIEWER_BATCH_RECORDS. diff --git a/tools/chatgui/tests/test_stream_view.cpp b/tools/chatgui/tests/test_stream_view.cpp index 2174b78d..4ca50b41 100644 --- a/tools/chatgui/tests/test_stream_view.cpp +++ b/tools/chatgui/tests/test_stream_view.cpp @@ -557,7 +557,7 @@ private slots: QVERIFY(receive(301, opened)); QCOMPARE(opened.kind, StreamRecordKind::Opened); QVERIFY(receive(302, opened)); QCOMPARE(opened.kind, StreamRecordKind::Opened); const QByteArray frame(1500, 'k'); const QList audio(5, QByteArray("opus")); - publish(frame, audio, 3); + publish(frame, audio, 1); // Начальный KEY единственный: оба cursor фиксируют PTS=100000. stream_media_status status{}; QTRY_VERIFY(gui_stream_status(301, status) && status.initialized); QTRY_VERIFY(gui_stream_status(302, status) && status.initialized); @@ -578,7 +578,8 @@ private slots: auto consume = [&] { for (const auto& record : records) { if (record.kind == StreamRecordKind::Video) { - QCOMPARE(record.pts, uint64_t(100000 + videos / 3 * 100000 + videos % 3 * 100000 / 3)); + uint64_t expected = videos ? 200000 + (videos - 1) / 3 * 100000 + (videos - 1) % 3 * 100000 / 3 : 100000; + QCOMPARE(record.pts, expected); QCOMPARE(record.data, frame); lastVideo = record.pts; videos++; } else if (record.kind == StreamRecordKind::Audio) { QCOMPARE(record.pts, uint64_t(100000 + audios * 20000)); lastAudio = record.pts; audios++; @@ -607,7 +608,7 @@ private slots: } consume(); } - QVERIFY(ended); QCOMPARE(videos, 30u); QCOMPARE(audios, 50u); QVERIFY(batches < 30); + QVERIFY(ended); QCOMPARE(videos, 28u); QCOMPARE(audios, 50u); QVERIFY(batches < 28); gui_stream_stop(301); before = notifications; QTest::qWait(20); QCOMPARE(notifications, before); DEBUG_INFO(DEBUG_CATEGORY_STREAM, "fixture batches: video=%u audio=%u batches=%u last_video=%llu last_audio=%llu signals=%u independent_readers=1",