Preserve stream capture settings and refine audio playback

This commit is contained in:
evgeny committed 2026-10-16 14:05:54 +02:00
1 parent 198ebc0acb
commit d60f8e4b1b
16 files changed
+244 -43

No files matched your search

+9 -4
View File
@@ -30,6 +30,7 @@ struct stream_playback_audio {
soundtouch::SoundTouch stretch;
Span input[mapCapacity], output[mapCapacity];
unsigned inputHead = 0, inputCount = 0, outputHead = 0, outputCount = 0;
unsigned bufferFrames = 0;
int tempo = 1000;
int64_t startPts = 0, expectedPts = -1;
double expectedOutput = 0, producedOutput = 0, lastPts = 0;
@@ -85,12 +86,15 @@ static int feedPcm(stream_playback_audio* a, int64_t pts, const uint8_t* packet,
extern "C" {
struct stream_playback_audio* stream_playback_audio_create(int64_t start) {
struct stream_playback_audio* stream_playback_audio_create(int64_t start, unsigned bufferMs) {
if (start < 0) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "playback audio invalid start=%lld", (long long)start); return nullptr; }
if (!bufferMs || bufferMs > 1000) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "playback audio invalid PCM buffer=%ums range=1..1000ms", bufferMs); return nullptr;
}
void* memory = u_malloc(sizeof(stream_playback_audio));
if (!memory) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "playback audio allocation failed"); return nullptr; }
auto* a = new (memory) stream_playback_audio;
a->startPts = start; a->lastPts = (double)start;
a->startPts = start; a->lastPts = (double)start; a->bufferFrames = rate * bufferMs / 1000;
a->opus = opus_codec_decoder_create(rate, 2);
if (!a->opus) {
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "playback audio Opus initialization failed"); stream_playback_audio_destroy(a); return nullptr;
@@ -99,7 +103,8 @@ struct stream_playback_audio* stream_playback_audio_create(int64_t start) {
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_OVERLAP_MS, 4); a->stretch.setSetting(SETTING_USE_AA_FILTER, 0);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "playback audio created start=%lld stereo=1 tempo=1.0..1.1", (long long)start);
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "playback audio created start=%lld stereo=1 tempo=1.0..1.1 PCM_buffer=%ums/%u_frames",
(long long)start, bufferMs, a->bufferFrames);
return a;
}
@@ -143,7 +148,7 @@ void stream_playback_audio_set_tempo(struct stream_playback_audio* a, int tempo)
}
int stream_playback_audio_needs_input(const struct stream_playback_audio* a) {
return a && !a->finished && !a->failed && a->stretch.numSamples() < framesPerPacket;
return a && !a->finished && !a->failed && a->stretch.numSamples() < a->bufferFrames;
}
/* Ограничение готовой границы применяется до выдачи PCM устройству, сохраняя общий A/V clock. */
+3 -1
View File
@@ -15,7 +15,9 @@ extern "C" {
#endif
struct stream_playback_audio;
struct stream_playback_audio *stream_playback_audio_create(int64_t start_pts_us);
/* buffer_ms (1..1000) — порог пополнения готового PCM; трансляции используют 40 мс.
* Это запас декодера, без аппаратной задержки и сетевого джиттер-буфера. */
struct stream_playback_audio *stream_playback_audio_create(int64_t start_pts_us, unsigned buffer_ms);
void stream_playback_audio_destroy(struct stream_playback_audio *audio);
int stream_playback_audio_feed(struct stream_playback_audio *audio, int64_t pts_us, const uint8_t *packet, size_t length);
void stream_playback_audio_set_tempo(struct stream_playback_audio *audio, int tempo_milli);