diff --git a/tools/chatgui/tests/test_stream_view.cpp b/tools/chatgui/tests/test_stream_view.cpp index 656a5e41..01e8ff9a 100644 --- a/tools/chatgui/tests/test_stream_view.cpp +++ b/tools/chatgui/tests/test_stream_view.cpp @@ -257,6 +257,7 @@ private slots: void modernCodecPlayback() { #ifdef HAVE_FFMPEG + debug_set_category_level(DEBUG_CATEGORY_STREAM, DEBUG_LEVEL_DEBUG); struct Fixture { uint8_t type; const char* encoder; }; const Fixture fixtures[] = {{STREAM_MEDIA_H265, "libx265"}, {STREAM_MEDIA_VP9, "libvpx-vp9"}, {STREAM_MEDIA_AV1, "libaom-av1"}}; for (const auto& fixture : fixtures) { @@ -303,6 +304,7 @@ private slots: QTRY_VERIFY_WITH_TIMEOUT(stream_get_info(publisher, &info) == STREAM_OK && info.owners == 1, 2000); window.close(); QTest::qWait(20); } + debug_set_category_level(DEBUG_CATEGORY_STREAM, DEBUG_LEVEL_INFO); #endif } diff --git a/tools/chatgui/transport/stream_bridge.cpp b/tools/chatgui/transport/stream_bridge.cpp index 2b7d9aef..356b42a5 100644 --- a/tools/chatgui/transport/stream_bridge.cpp +++ b/tools/chatgui/transport/stream_bridge.cpp @@ -59,6 +59,13 @@ void output(StreamRecord record) { /* Только uasync под lock; снимает собственное владение подпиской, не транспорт других владельцев. */ void closeViewer(StreamRecordKind kind, int reason) { + if (kind == StreamRecordKind::Closed) { + for (auto i = bridge.output.begin(); i != bridge.output.end();) { + if (i->id == bridge.viewer.id && (i->kind == StreamRecordKind::Video || i->kind == StreamRecordKind::Audio)) { + bridge.bytes -= static_cast(i->data.size()); i = bridge.output.erase(i); + } else ++i; + } + } if (bridge.viewer.id) output({bridge.viewer.id, 0, kind, {}, 0, reason}); if (bridge.handle) stream_close(bridge.handle); DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop viewer released id=%llu reason=%d", @@ -144,10 +151,16 @@ void process(void*) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop media index failed result=%d", statusResult); closeViewer(StreamRecordKind::Closed, STREAM_CLOSE_FAILED); return; } - if (!bridge.wantRead || bridge.output.size() >= 2 || bridge.bytes + STREAM_MEDIA_MAX_FRAME > 4u * 1024u * 1024u) return; + unsigned prepared = 0; + for (const auto& record : bridge.output) + if (record.id == bridge.viewer.id && (record.kind == StreamRecordKind::Video || record.kind == StreamRecordKind::Audio)) prepared++; + if (!bridge.wantRead || prepared >= 2 || bridge.bytes + STREAM_MEDIA_MAX_FRAME > 4u * 1024u * 1024u) return; bridge.wantRead = false; stream_media_packet packet{}; int result = stream_media_read(bridge.handle, bridge.position, bridge.videoAhead, bridge.audioAhead, &packet); + DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop media read id=%llu PTS=%lld ahead=%lld/%lld result=%d kind=%d prepared=%u records=%zu", + (unsigned long long)bridge.viewer.id, (long long)bridge.position, (long long)bridge.videoAhead, + (long long)bridge.audioAhead, result, result == STREAM_OK ? (int)packet.kind : -1, prepared, bridge.output.size()); if (stream_media_get_status(bridge.handle, &bridge.status) < 0) result = STREAM_ERR_FORMAT; if (result == STREAM_OK) { if (packet.kind == STREAM_MEDIA_READ_END) closeViewer(StreamRecordKind::End, 0);