Skip to content

Commit d631927

Browse files
committed
linux-pipewire: Make camera framerate non-mandatory
Formats can be without any framerate options.
1 parent 189ed7c commit d631927

File tree

1 file changed

+67
-52
lines changed

1 file changed

+67
-52
lines changed

plugins/linux-pipewire/camera-portal.c

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,6 @@ static void camera_format_list(struct camera_device *dev, obs_property_t *prop)
334334
struct spa_rectangle resolution;
335335

336336
const struct spa_pod_prop *framerate_prop = NULL;
337-
struct spa_pod *framerate_pod;
338-
uint32_t n_framerates;
339-
enum spa_choice_type framerate_choice;
340-
const struct spa_fraction *framerate_values;
341-
g_autoptr(GArray) framerates = NULL;
342337

343338
if (p->id != SPA_PARAM_EnumFormat || p->param == NULL)
344339
continue;
@@ -378,61 +373,68 @@ static void camera_format_list(struct camera_device *dev, obs_property_t *prop)
378373
obs_data_set_int(data, "height", resolution.height);
379374

380375
framerate_prop = spa_pod_find_prop(p->param, NULL, SPA_FORMAT_VIDEO_framerate);
381-
if (!framerate_prop)
382-
continue;
376+
if (framerate_prop) {
377+
struct spa_pod *framerate_pod;
378+
uint32_t n_framerates;
379+
enum spa_choice_type framerate_choice;
380+
const struct spa_fraction *framerate_values;
381+
g_autoptr(GArray) framerates = NULL;
382+
383+
framerate_pod = spa_pod_get_values(&framerate_prop->value, &n_framerates, &framerate_choice);
384+
if (framerate_pod->type != SPA_TYPE_Fraction) {
385+
blog(LOG_WARNING, "Framerate is not a fraction");
386+
continue;
387+
}
383388

384-
framerate_pod = spa_pod_get_values(&framerate_prop->value, &n_framerates, &framerate_choice);
385-
if (framerate_pod->type != SPA_TYPE_Fraction) {
386-
blog(LOG_WARNING, "Framerate is not a fraction");
387-
continue;
388-
}
389+
framerate_values = SPA_POD_BODY(framerate_pod);
390+
framerates = g_array_new(FALSE, FALSE, sizeof(struct spa_fraction));
389391

390-
framerate_values = SPA_POD_BODY(framerate_pod);
391-
framerates = g_array_new(FALSE, FALSE, sizeof(struct spa_fraction));
392+
switch (framerate_choice) {
393+
case SPA_CHOICE_None:
394+
g_array_append_val(framerates, framerate_values[0]);
395+
break;
396+
case SPA_CHOICE_Range:
397+
blog(LOG_WARNING, "Ranged framerates not supported");
398+
continue;
399+
case SPA_CHOICE_Step:
400+
blog(LOG_WARNING, "Stepped framerates not supported");
401+
continue;
402+
case SPA_CHOICE_Enum:
403+
/* i=0 is the default framerate, skip it */
404+
for (uint32_t i = 1; i < n_framerates; i++)
405+
g_array_append_val(framerates, framerate_values[i]);
406+
break;
407+
default:
408+
continue;
409+
}
392410

393-
switch (framerate_choice) {
394-
case SPA_CHOICE_None:
395-
g_array_append_val(framerates, framerate_values[0]);
396-
break;
397-
case SPA_CHOICE_Range:
398-
blog(LOG_WARNING, "Ranged framerates not supported");
399-
continue;
400-
case SPA_CHOICE_Step:
401-
blog(LOG_WARNING, "Stepped framerates not supported");
402-
continue;
403-
case SPA_CHOICE_Enum:
404-
/* i=0 is the default framerate, skip it */
405-
for (uint32_t i = 1; i < n_framerates; i++)
406-
g_array_append_val(framerates, framerate_values[i]);
407-
break;
408-
default:
409-
continue;
410-
}
411+
dstr_printf(&str, "%ux%u", resolution.width, resolution.height);
411412

412-
dstr_printf(&str, "%ux%u", resolution.width, resolution.height);
413+
aspect_ratio = aspect_ratio_from_spa_rectangle(resolution);
414+
if (aspect_ratio.len != 0) {
415+
dstr_catf(&str, " (%s)", aspect_ratio.array);
416+
dstr_free(&aspect_ratio);
417+
}
413418

414-
aspect_ratio = aspect_ratio_from_spa_rectangle(resolution);
415-
if (aspect_ratio.len != 0) {
416-
dstr_catf(&str, " (%s)", aspect_ratio.array);
417-
dstr_free(&aspect_ratio);
418-
}
419+
dstr_cat(&str, " - ");
419420

420-
dstr_cat(&str, " - ");
421+
for (int i = framerates->len - 1; i >= 0; i--) {
422+
const struct spa_fraction *framerate =
423+
&g_array_index(framerates, struct spa_fraction, i);
421424

422-
for (int i = framerates->len - 1; i >= 0; i--) {
423-
const struct spa_fraction *framerate = &g_array_index(framerates, struct spa_fraction, i);
425+
if (i != (int)framerates->len - 1)
426+
dstr_cat(&str, ", ");
424427

425-
if (i != (int)framerates->len - 1)
426-
dstr_cat(&str, ", ");
428+
if (framerate->denom == 1)
429+
dstr_catf(&str, "%u", framerate->num);
430+
else
431+
dstr_catf(&str, "%.2f", framerate->num / (double)framerate->denom);
432+
}
427433

428-
if (framerate->denom == 1)
429-
dstr_catf(&str, "%u", framerate->num);
430-
else
431-
dstr_catf(&str, "%.2f", framerate->num / (double)framerate->denom);
434+
dstr_cat(&str, " FPS");
432435
}
433436

434-
dstr_catf(&str, " FPS - %s", format_name);
435-
437+
dstr_catf(&str, " - %s", format_name);
436438
obs_property_list_add_string(prop, str.array, obs_data_get_json(data));
437439
dstr_free(&str);
438440
}
@@ -635,7 +637,7 @@ static int compare_framerates(gconstpointer a, gconstpointer b)
635637
return da - db;
636638
}
637639

638-
static void framerate_list(struct camera_device *dev, uint32_t pixelformat, const struct spa_rectangle *resolution,
640+
static bool framerate_list(struct camera_device *dev, uint32_t pixelformat, const struct spa_rectangle *resolution,
639641
obs_property_t *prop)
640642
{
641643
g_autoptr(GArray) framerates = NULL;
@@ -739,6 +741,8 @@ static void framerate_list(struct camera_device *dev, uint32_t pixelformat, cons
739741
dstr_free(&str);
740742
}
741743
obs_data_release(data);
744+
745+
return framerates->len != 0;
742746
}
743747

744748
static bool parse_framerate(struct spa_fraction *dest, const char *json)
@@ -826,6 +830,7 @@ static bool format_selected(void *data, obs_properties_t *properties, obs_proper
826830
struct camera_device *device;
827831
enum spa_media_subtype last_subtype = camera_source->subtype;
828832
enum spa_video_format last_format = camera_source->format.spa_format;
833+
bool has_framerates;
829834

830835
blog(LOG_INFO, "[camera-portal] Selected format for '%s'", camera_source->device_id);
831836

@@ -845,7 +850,18 @@ static bool format_selected(void *data, obs_properties_t *properties, obs_proper
845850
}
846851

847852
property = obs_properties_get(properties, "framerate");
848-
framerate_list(device, camera_source->format.spa_format, &camera_source->resolution.rect, property);
853+
obs_property_set_modified_callback2(property, NULL, NULL);
854+
855+
has_framerates =
856+
framerate_list(device, camera_source->format.spa_format, &camera_source->resolution.rect, property);
857+
obs_property_set_enabled(property, has_framerates);
858+
859+
if (has_framerates) {
860+
obs_property_set_modified_callback2(property, framerate_selected, camera_source);
861+
obs_property_modified(property, settings);
862+
} else if (camera_source->obs_pw_stream) {
863+
obs_pipewire_stream_set_framerate(camera_source->obs_pw_stream, NULL);
864+
}
849865

850866
return true;
851867
}
@@ -1260,7 +1276,6 @@ static obs_properties_t *pipewire_camera_get_properties(void *data)
12601276

12611277
obs_property_set_modified_callback2(device_list, device_selected, camera_source);
12621278
obs_property_set_modified_callback2(format_list, format_selected, camera_source);
1263-
obs_property_set_modified_callback2(framerate_list, framerate_selected, camera_source);
12641279

12651280
return props;
12661281
}

0 commit comments

Comments
 (0)