86 lines
2.8 KiB
Diff
86 lines
2.8 KiB
Diff
diff '--color=auto' -ru a/plugins/linux-pipewire/pipewire.c b/plugins/linux-pipewire/pipewire.c
|
|
--- a/plugins/linux-pipewire/pipewire.c 2023-02-04 13:17:10.000000000 +0300
|
|
+++ b/plugins/linux-pipewire/pipewire.c 2023-03-04 20:51:36.512199751 +0300
|
|
@@ -125,6 +125,41 @@
|
|
blog(LOG_WARNING, "[pipewire] failed to parse server version");
|
|
}
|
|
|
|
+static uint32_t calc_spa_enumformat_buffer_size(obs_pipewire *obs_pw)
|
|
+{
|
|
+ // from spa/pod/pod.h
|
|
+ uint32_t spa_pod_object_size = sizeof(struct spa_pod_object);
|
|
+ uint32_t spa_pod_prop_size = sizeof(struct spa_pod_prop);
|
|
+ uint32_t spa_pod_value_size = 1 * sizeof(uint64_t);
|
|
+ uint32_t spa_pod_choice_size = 2 * sizeof(uint64_t);
|
|
+ // This is counted from the build_format function
|
|
+ uint32_t n_objects = 0;
|
|
+ uint32_t n_props = 0;
|
|
+ uint32_t n_values = 0;
|
|
+ uint32_t n_choices = 0;
|
|
+ uint32_t size;
|
|
+
|
|
+ for (size_t i = 0; i < obs_pw->format_info.num; i++) {
|
|
+ if (obs_pw->format_info.array[i].modifiers.num == 0)
|
|
+ continue;
|
|
+ n_objects += 1;
|
|
+ n_props += 5 + 1;
|
|
+ n_values += 9 + 2 + obs_pw->format_info.array[i].modifiers.num;
|
|
+ n_choices += 2 + 1;
|
|
+ }
|
|
+ for (size_t i = 0; i < obs_pw->format_info.num; i++) {
|
|
+ n_objects += 1;
|
|
+ n_props += 5;
|
|
+ n_values += 9;
|
|
+ n_choices += 2;
|
|
+ }
|
|
+ size = n_objects * spa_pod_object_size + n_props * spa_pod_prop_size +
|
|
+ n_values * spa_pod_value_size + n_choices * spa_pod_choice_size;
|
|
+ blog(LOG_DEBUG, "[pipewire]: calculated spa enumFormat buffer size %u",
|
|
+ size);
|
|
+ return size;
|
|
+}
|
|
+
|
|
static void teardown_pipewire(obs_pipewire_data *obs_pw)
|
|
{
|
|
if (obs_pw->thread_loop) {
|
|
@@ -319,6 +354,10 @@
|
|
obs_pw->format_info.array[i].spa_format,
|
|
obs_pw->format_info.array[i].modifiers.array,
|
|
obs_pw->format_info.array[i].modifiers.num);
|
|
+ if (!params[params_count - 1]) {
|
|
+ blog(LOG_ERROR, "[pipewire] Failed to format param");
|
|
+ return false;
|
|
+ }
|
|
}
|
|
|
|
build_shm:
|
|
@@ -326,6 +365,10 @@
|
|
params[params_count++] = build_format(
|
|
pod_builder, &obs_pw->video_info,
|
|
obs_pw->format_info.array[i].spa_format, NULL, 0);
|
|
+ if (!params[params_count - 1]) {
|
|
+ blog(LOG_ERROR, "[pipewire] Failed to format param");
|
|
+ return false;
|
|
+ }
|
|
}
|
|
*param_list = params;
|
|
*n_params = params_count;
|
|
@@ -432,7 +475,7 @@
|
|
|
|
pw_thread_loop_lock(obs_pw->thread_loop);
|
|
|
|
- uint8_t params_buffer[2048];
|
|
+ uint8_t params_buffer[calc_spa_enumformat_buffer_size(obs_pw)];
|
|
struct spa_pod_builder pod_builder =
|
|
SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
|
|
uint32_t n_params;
|
|
@@ -757,7 +800,7 @@
|
|
struct spa_pod_builder pod_builder;
|
|
const struct spa_pod **params = NULL;
|
|
uint32_t n_params;
|
|
- uint8_t params_buffer[2048];
|
|
+ uint8_t params_buffer[calc_spa_enumformat_buffer_size(obs_pw)];
|
|
|
|
obs_pw->thread_loop = pw_thread_loop_new("PipeWire thread loop", NULL);
|
|
obs_pw->context = pw_context_new(
|