Preserve stream capture settings and refine audio playback
This commit is contained in:
1 parent
198ebc0acb
commit
d60f8e4b1b
16 files changed
+244
-43
No files matched your search
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user