diff --git a/src/stream/stream_playback_audio.cpp b/src/stream/stream_playback_audio.cpp index e1fc26ba..d0ac9012 100644 --- a/src/stream/stream_playback_audio.cpp +++ b/src/stream/stream_playback_audio.cpp @@ -88,7 +88,9 @@ struct stream_playback_audio* stream_playback_audio_create(int64_t start) { auto* a = new (memory) stream_playback_audio; a->startPts = start; a->lastPts = (double)start; a->opus = opus_codec_decoder_create(rate, 2); - if (!a->opus) { stream_playback_audio_destroy(a); return nullptr; } + if (!a->opus) { + DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "playback audio Opus initialization failed"); stream_playback_audio_destroy(a); return nullptr; + } a->stretch.setSampleRate(rate); a->stretch.setChannels(2); a->stretch.setTempo(1.0); a->stretch.setSetting(SETTING_USE_QUICKSEEK, 1); a->stretch.setSetting(SETTING_SEQUENCE_MS, 20); a->stretch.setSetting(SETTING_SEEKWINDOW_MS, 10); @@ -117,9 +119,10 @@ int stream_playback_audio_feed(struct stream_playback_audio* a, int64_t pts, con DEBUG_WARN(DEBUG_CATEGORY_STREAM, "playback audio discontinuity pts=%lld expected=%lld missing=%d", (long long)pts, (long long)a->expectedPts, missing); return -2; } + int64_t effectivePts = a->expectedPts < 0 ? pts : a->expectedPts + missing * 20000; for (int i = 0; i < missing; i++) if (feedPcm(a, a->expectedPts + i * 20000, nullptr, 0) < 0) return -1; - if (feedPcm(a, pts, packet, (int)length) < 0) return -1; - a->expectedPts = pts + 20000; + if (feedPcm(a, effectivePts, packet, (int)length) < 0) return -1; + a->expectedPts = effectivePts + 20000; return 0; } diff --git a/tools/chatgui/transport/stream_bridge.cpp b/tools/chatgui/transport/stream_bridge.cpp index 54265bbb..b1e50641 100644 --- a/tools/chatgui/transport/stream_bridge.cpp +++ b/tools/chatgui/transport/stream_bridge.cpp @@ -23,6 +23,7 @@ struct Bridge { bool wantRead = false, waiting = false, resync = false; int64_t position = -1, videoAhead = STREAM_MEDIA_READ_AHEAD_US, audioAhead = STREAM_MEDIA_READ_AHEAD_US; stream_media_status status{}; + uint64_t statusId = 0; Viewer viewer, requested; STREAM_HANDLE* handle = nullptr; std::deque output; @@ -66,7 +67,6 @@ void closeViewer(StreamRecordKind kind, int reason) { } void mediaFrame(void*, const stream_media_format* format, const stream_media_video* video, const stream_media_audio* audio) { - if (bridge.overflow) return; StreamRecord record; record.id = bridge.viewer.id; record.format = *format; if (video) { record.kind = StreamRecordKind::Video; record.pts = video->pts_us; record.flags = video->flags; @@ -104,7 +104,7 @@ void process(void*) { } if (bridge.opening) { bridge.opening = false; bridge.viewer = bridge.requested; bridge.requested = {}; - bridge.status = {}; bridge.position = -1; bridge.waiting = false; + bridge.status = {}; bridge.statusId = bridge.viewer.id; bridge.position = -1; bridge.waiting = false; stream_member_state member{}; int reason = STREAM_CLOSE_FAILED; int result = stream_member_load(bridge.inst, bridge.viewer.group, bridge.viewer.source, &member, nullptr); @@ -235,7 +235,7 @@ bool gui_stream_pull(uint64_t id, StreamRecord& record, int64_t position, int64_ bool gui_stream_status(uint64_t id, stream_media_status& status) { std::lock_guard guard(bridge.lock); - if (bridge.viewer.id != id && !bridge.status.finished) return false; + if (bridge.statusId != id) return false; status = bridge.status; return true; }