Browse Source

Keep viewer snapshots scoped and normalize Opus packet cadence

master
evgeny 6 days ago
parent
commit
8d317dbb85
  1. 9
      src/stream/stream_playback_audio.cpp
  2. 6
      tools/chatgui/transport/stream_bridge.cpp

9
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; auto* a = new (memory) stream_playback_audio;
a->startPts = start; a->lastPts = (double)start; a->startPts = start; a->lastPts = (double)start;
a->opus = opus_codec_decoder_create(rate, 2); 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.setSampleRate(rate); a->stretch.setChannels(2); a->stretch.setTempo(1.0);
a->stretch.setSetting(SETTING_USE_QUICKSEEK, 1); a->stretch.setSetting(SETTING_USE_QUICKSEEK, 1);
a->stretch.setSetting(SETTING_SEQUENCE_MS, 20); a->stretch.setSetting(SETTING_SEEKWINDOW_MS, 10); 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", DEBUG_WARN(DEBUG_CATEGORY_STREAM, "playback audio discontinuity pts=%lld expected=%lld missing=%d",
(long long)pts, (long long)a->expectedPts, missing); return -2; (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; 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; if (feedPcm(a, effectivePts, packet, (int)length) < 0) return -1;
a->expectedPts = pts + 20000; a->expectedPts = effectivePts + 20000;
return 0; return 0;
} }

6
tools/chatgui/transport/stream_bridge.cpp

@ -23,6 +23,7 @@ struct Bridge {
bool wantRead = false, waiting = false, resync = false; bool wantRead = false, waiting = false, resync = false;
int64_t position = -1, videoAhead = STREAM_MEDIA_READ_AHEAD_US, audioAhead = STREAM_MEDIA_READ_AHEAD_US; int64_t position = -1, videoAhead = STREAM_MEDIA_READ_AHEAD_US, audioAhead = STREAM_MEDIA_READ_AHEAD_US;
stream_media_status status{}; stream_media_status status{};
uint64_t statusId = 0;
Viewer viewer, requested; Viewer viewer, requested;
STREAM_HANDLE* handle = nullptr; STREAM_HANDLE* handle = nullptr;
std::deque<StreamRecord> output; std::deque<StreamRecord> 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) { 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; StreamRecord record; record.id = bridge.viewer.id; record.format = *format;
if (video) { if (video) {
record.kind = StreamRecordKind::Video; record.pts = video->pts_us; record.flags = video->flags; record.kind = StreamRecordKind::Video; record.pts = video->pts_us; record.flags = video->flags;
@ -104,7 +104,7 @@ void process(void*) {
} }
if (bridge.opening) { if (bridge.opening) {
bridge.opening = false; bridge.viewer = bridge.requested; bridge.requested = {}; 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{}; stream_member_state member{};
int reason = STREAM_CLOSE_FAILED; int reason = STREAM_CLOSE_FAILED;
int result = stream_member_load(bridge.inst, bridge.viewer.group, bridge.viewer.source, &member, nullptr); 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) { bool gui_stream_status(uint64_t id, stream_media_status& status) {
std::lock_guard<std::mutex> guard(bridge.lock); std::lock_guard<std::mutex> guard(bridge.lock);
if (bridge.viewer.id != id && !bridge.status.finished) return false; if (bridge.statusId != id) return false;
status = bridge.status; return true; status = bridge.status; return true;
} }

Loading…
Cancel
Save