diff options
-rw-r--r-- | .SRCINFO | 6 | ||||
-rw-r--r-- | PKGBUILD | 12 | ||||
-rw-r--r-- | pa_buffer_aggressive.patch | 112 | ||||
-rw-r--r-- | pa_fix_monitor_s32.patch | 108 |
4 files changed, 236 insertions, 2 deletions
@@ -1,7 +1,7 @@ pkgbase = obs-studio-tytan652 pkgdesc = Free and open source software for video recording and live streaming. With Browser dock and sources, VST 2 filter, FTL protocol, VLC sources, V4L2 devices by paths, my bind interface PR, and sometimes backported fixes. pkgver = 27.1.3 - pkgrel = 1 + pkgrel = 2 url = https://github.com/obsproject/obs-studio arch = i686 arch = x86_64 @@ -50,6 +50,8 @@ pkgbase = obs-studio-tytan652 source = v4l2_by-path.patch source = FindLibpci.cmake source = vaapi_set_dri_devices.patch + source = pa_buffer_aggressive.patch + source = pa_fix_monitor_s32.patch source = obs-browser::git+https://github.com/obsproject/obs-browser.git source = obs-vst::git+https://github.com/obsproject/obs-vst.git#commit=cca219fa3613dbc65de676ab7ba29e76865fa6f8 sha256sums = SKIP @@ -58,6 +60,8 @@ pkgbase = obs-studio-tytan652 sha256sums = fb55dffcb177fd89c2cbffeb14aaf920dae2ae60dcfa934cff252315f268470e sha256sums = 916f9fb3819c9d952140d65434e9dffc77b688dc1dc027b39226c33ee97be63f sha256sums = 5c18a85f95090f01a9eb24aeea13220f8698f8d433970e4dc6391432d033f065 + sha256sums = 4b90a29e75eb7281cbe754408327d44192c0892557f03bd3c612f3658af739fc + sha256sums = 994fcb78c948f3222a07ddd342453310da769e333307dcfea2e301c259d0d60a sha256sums = SKIP sha256sums = SKIP @@ -2,7 +2,7 @@ pkgname=obs-studio-tytan652 pkgver=27.1.3 -pkgrel=1 +pkgrel=2 pkgdesc="Free and open source software for video recording and live streaming. With Browser dock and sources, VST 2 filter, FTL protocol, VLC sources, V4L2 devices by paths, my bind interface PR, and sometimes backported fixes." arch=("i686" "x86_64" "aarch64") url="https://github.com/obsproject/obs-studio" @@ -57,6 +57,8 @@ source=( "v4l2_by-path.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/3437.patch "FindLibpci.cmake" # https://github.com/carlocastoldi/obs-studio/blob/2936-fix/cmake/Modules/FindLibpci.cmake "vaapi_set_dri_devices.patch" # Based on https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/5336.patch + "pa_buffer_aggressive.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/4908.patch + "pa_fix_monitor_s32.patch" # https://patch-diff.githubusercontent.com/raw/obsproject/obs-studio/pull/5400.patch "obs-browser::git+https://github.com/obsproject/obs-browser.git" "obs-vst::git+https://github.com/obsproject/obs-vst.git#commit=cca219fa3613dbc65de676ab7ba29e76865fa6f8" ) @@ -67,6 +69,8 @@ sha256sums=( "fb55dffcb177fd89c2cbffeb14aaf920dae2ae60dcfa934cff252315f268470e" "916f9fb3819c9d952140d65434e9dffc77b688dc1dc027b39226c33ee97be63f" "5c18a85f95090f01a9eb24aeea13220f8698f8d433970e4dc6391432d033f065" + "4b90a29e75eb7281cbe754408327d44192c0892557f03bd3c612f3658af739fc" + "994fcb78c948f3222a07ddd342453310da769e333307dcfea2e301c259d0d60a" "SKIP" "SKIP" ) @@ -93,6 +97,12 @@ prepare() { patch -Np1 < "$srcdir/vaapi_set_dri_devices.patch" # Add CMake finder for libpci (pciutils) cp "$srcdir/FindLibpci.cmake" cmake/Modules/ + + ## pulse: fill audio monitor buffer more aggressively (https://github.com/obsproject/obs-studio/pull/4908) + patch -Np1 < "$srcdir/pa_buffer_aggressive.patch" + + ## linux-pulseaudio: Fix monitoring volume for s32 format (https://github.com/obsproject/obs-studio/pull/5400) + patch -Np1 < "$srcdir/pa_fix_monitor_s32.patch" } build() { diff --git a/pa_buffer_aggressive.patch b/pa_buffer_aggressive.patch new file mode 100644 index 000000000000..5630ab09d076 --- /dev/null +++ b/pa_buffer_aggressive.patch @@ -0,0 +1,112 @@ +From 85e75085030664ff1bba2e87a79e8ff4294f28c4 Mon Sep 17 00:00:00 2001 +From: Kurt Kartaltepe <kkartaltepe@gmail.com> +Date: Wed, 16 Jun 2021 09:42:46 -0700 +Subject: [PATCH] pulse: fill audio monitor buffer more aggressively + +Previously we would wait for pulse to attempt to read from the monitor +source and obs buffered at least 5ms of audio data before we tried to +fill the buffer. In some cases this resulted in consistently triggering +underruns in pulse. + +Instead we try to fill the buffer immediately as obs outputs audio data +and while the pa buffer is not full. We also stop trying to grow the +buffer to prevent underruns after we reach 1s of latency. +--- + .../pulse/pulseaudio-output.c | 46 ++++++++++++------- + 1 file changed, 30 insertions(+), 16 deletions(-) + +diff --git a/libobs/audio-monitoring/pulse/pulseaudio-output.c b/libobs/audio-monitoring/pulse/pulseaudio-output.c +index 9abfcd78b4e..d4ec239de71 100644 +--- a/libobs/audio-monitoring/pulse/pulseaudio-output.c ++++ b/libobs/audio-monitoring/pulse/pulseaudio-output.c +@@ -20,7 +20,6 @@ struct audio_monitor { + + struct circlebuf new_data; + audio_resampler_t *resampler; +- size_t buffer_size; + size_t bytesRemaining; + size_t bytes_per_channel; + +@@ -176,21 +175,20 @@ static void do_stream_write(void *param) + PULSE_DATA(param); + uint8_t *buffer = NULL; + +- while (data->new_data.size >= data->buffer_size && +- data->bytesRemaining > 0) { +- size_t bytesToFill = data->buffer_size; +- +- if (bytesToFill > data->bytesRemaining) ++ while (data->new_data.size > 0 && data->bytesRemaining > 0) { ++ size_t bytesToFill = data->new_data.size; ++ if (data->bytesRemaining < bytesToFill) + bytesToFill = data->bytesRemaining; + + pulseaudio_lock(); +- pa_stream_begin_write(data->stream, (void **)&buffer, +- &bytesToFill); +- pulseaudio_unlock(); ++ if (pa_stream_begin_write(data->stream, (void **)&buffer, ++ &bytesToFill)) { ++ pulseaudio_unlock(); ++ return; ++ } + + circlebuf_pop_front(&data->new_data, buffer, bytesToFill); + +- pulseaudio_lock(); + pa_stream_write(data->stream, buffer, bytesToFill, NULL, 0LL, + PA_SEEK_RELATIVE); + pulseaudio_unlock(); +@@ -262,13 +260,30 @@ static void pulseaudio_underflow(pa_stream *p, void *userdata) + UNUSED_PARAMETER(p); + PULSE_DATA(userdata); + ++ pa_sample_spec spec = {0}; ++ spec.format = data->format; ++ spec.rate = (uint32_t)data->samples_per_sec; ++ spec.channels = data->channels; ++ uint64_t latency = pa_bytes_to_usec(data->attr.tlength, &spec); ++ + pthread_mutex_lock(&data->playback_mutex); +- if (obs_source_active(data->source)) ++ if (obs_source_active(data->source) && latency < 1000000) { ++ data->attr.fragsize = (uint32_t)-1; ++ data->attr.maxlength = (uint32_t)-1; ++ data->attr.prebuf = (uint32_t)-1; ++ data->attr.minreq = (uint32_t)-1; + data->attr.tlength = (data->attr.tlength * 3) / 2; +- +- pa_stream_set_buffer_attr(data->stream, &data->attr, NULL, NULL); ++ pa_stream_set_buffer_attr(data->stream, &data->attr, NULL, ++ NULL); ++ data->bytesRemaining = data->attr.maxlength; ++ } + pthread_mutex_unlock(&data->playback_mutex); + ++ if (latency >= 1000000) { ++ blog(LOG_WARNING, "source monitor reached max latency %ldms", ++ latency / 1000); ++ } ++ + pulseaudio_signal(0); + } + +@@ -460,9 +475,6 @@ static bool audio_monitor_init(struct audio_monitor *monitor, + monitor->attr.prebuf = (uint32_t)-1; + monitor->attr.tlength = pa_usec_to_bytes(25000, &spec); + +- monitor->buffer_size = +- monitor->bytes_per_frame * pa_usec_to_bytes(5000, &spec); +- + pa_stream_flags_t flags = PA_STREAM_INTERPOLATE_TIMING | + PA_STREAM_AUTO_TIMING_UPDATE; + +@@ -480,6 +492,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor, + return false; + } + ++ monitor->bytesRemaining = monitor->attr.maxlength; ++ + blog(LOG_INFO, "Started Monitoring in '%s'", monitor->device); + return true; + } diff --git a/pa_fix_monitor_s32.patch b/pa_fix_monitor_s32.patch new file mode 100644 index 000000000000..7910f64e99d3 --- /dev/null +++ b/pa_fix_monitor_s32.patch @@ -0,0 +1,108 @@ +From ebd3ff7e39c487718312a378637bb060cd8a1500 Mon Sep 17 00:00:00 2001 +From: Norihiro Kamae <norihiro@nagater.net> +Date: Mon, 11 Oct 2021 13:59:56 +0900 +Subject: [PATCH] linux-pulseaudio: Fix monitoring volume for s32 format + +When signed 32-bit audio arrived to pulseaudio-output and volume was +lowered, audio data was broken. In the function `process_volume`, the +type of the data is switched by `bytes_per_channel`. However the size of +signed 32-bit integer and the size of float are same so that the signed +32-bit integer is processed as float. +This commit changes these items. +- Use `format` instead of `bytes_per_channel` so that all the sample + types can be differentiated. +- Change `char` to `uint8_t` in `process_byte` because the type is + expected unsigned 8-bit. +- Change `short` to `int16_t` and renames existing function + `process_short` to `process_s16` to clarify the function is + processing signed 16-bit. +--- + .../pulse/pulseaudio-output.c | 41 ++++++++++++------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/libobs/audio-monitoring/pulse/pulseaudio-output.c b/libobs/audio-monitoring/pulse/pulseaudio-output.c +index 9abfcd78b4e..f84a8913475 100644 +--- a/libobs/audio-monitoring/pulse/pulseaudio-output.c ++++ b/libobs/audio-monitoring/pulse/pulseaudio-output.c +@@ -22,7 +22,6 @@ struct audio_monitor { + audio_resampler_t *resampler; + size_t buffer_size; + size_t bytesRemaining; +- size_t bytes_per_channel; + + bool ignore; + pthread_mutex_t playback_mutex; +@@ -127,17 +126,26 @@ static pa_channel_map pulseaudio_channel_map(enum speaker_layout layout) + + static void process_byte(void *p, size_t frames, size_t channels, float vol) + { +- register char *cur = (char *)p; +- register char *end = cur + frames * channels; ++ register uint8_t *cur = (uint8_t *)p; ++ register uint8_t *end = cur + frames * channels; + + while (cur < end) + *(cur++) *= vol; + } + +-static void process_short(void *p, size_t frames, size_t channels, float vol) ++static void process_s16(void *p, size_t frames, size_t channels, float vol) + { +- register short *cur = (short *)p; +- register short *end = cur + frames * channels; ++ register int16_t *cur = (int16_t *)p; ++ register int16_t *end = cur + frames * channels; ++ ++ while (cur < end) ++ *(cur++) *= vol; ++} ++ ++static void process_s32(void *p, size_t frames, size_t channels, float vol) ++{ ++ register int32_t *cur = (int32_t *)p; ++ register int32_t *end = cur + frames * channels; + + while (cur < end) + *(cur++) *= vol; +@@ -155,19 +163,26 @@ static void process_float(void *p, size_t frames, size_t channels, float vol) + void process_volume(const struct audio_monitor *monitor, float vol, + uint8_t *const *resample_data, uint32_t resample_frames) + { +- switch (monitor->bytes_per_channel) { +- case 1: ++ switch (monitor->format) { ++ case PA_SAMPLE_U8: + process_byte(resample_data[0], resample_frames, + monitor->channels, vol); + break; +- case 2: +- process_short(resample_data[0], resample_frames, +- monitor->channels, vol); ++ case PA_SAMPLE_S16LE: ++ process_s16(resample_data[0], resample_frames, ++ monitor->channels, vol); + break; +- default: ++ case PA_SAMPLE_S32LE: ++ process_s32(resample_data[0], resample_frames, ++ monitor->channels, vol); ++ break; ++ case PA_SAMPLE_FLOAT32LE: + process_float(resample_data[0], resample_frames, + monitor->channels, vol); + break; ++ default: ++ // just ignore ++ break; + } + } + +@@ -440,8 +455,6 @@ static bool audio_monitor_init(struct audio_monitor *monitor, + return false; + } + +- monitor->bytes_per_channel = get_audio_bytes_per_channel( +- pulseaudio_to_obs_audio_format(monitor->format)); + monitor->speakers = pulseaudio_channels_to_obs_speakers(spec.channels); + monitor->bytes_per_frame = pa_frame_size(&spec); + |