@@ -535,6 +535,28 @@ static int compare_resolutions(gconstpointer a, gconstpointer b)
535
535
return 0 ;
536
536
}
537
537
538
+ static const void * get_values_from_pod (const struct spa_pod * p , uint32_t type , uint32_t * cnt )
539
+ {
540
+ uint32_t choice ;
541
+ const struct spa_pod * vals = spa_pod_get_values (p , cnt , & choice );
542
+ if (!vals || vals -> type != type || * cnt <= 0 )
543
+ return NULL ;
544
+
545
+ const void * body = SPA_POD_BODY_CONST (vals );
546
+
547
+ switch (choice ) {
548
+ case SPA_CHOICE_Enum :
549
+ /* skip the first one, the default value */
550
+ * cnt -= 1 ;
551
+ body = SPA_PTROFF (body , vals -> size , const void );
552
+ SPA_FALLTHROUGH ;
553
+ case SPA_CHOICE_None :
554
+ return body ;
555
+ default :
556
+ return NULL ;
557
+ }
558
+ }
559
+
538
560
static void resolution_list (struct camera_device * dev , uint32_t pixelformat , obs_property_t * prop )
539
561
{
540
562
g_autoptr (GArray ) resolutions = NULL ;
@@ -546,7 +568,6 @@ static void resolution_list(struct camera_device *dev, uint32_t pixelformat, obs
546
568
spa_list_for_each (p , & dev -> param_list , link )
547
569
{
548
570
struct obs_pw_video_format obs_pw_video_format ;
549
- struct spa_rectangle resolution ;
550
571
uint32_t media_type , media_subtype , format ;
551
572
552
573
if (p -> id != SPA_PARAM_EnumFormat || p -> param == NULL )
@@ -570,11 +591,18 @@ static void resolution_list(struct camera_device *dev, uint32_t pixelformat, obs
570
591
if (obs_pw_video_format .video_format != pixelformat )
571
592
continue ;
572
593
573
- if (spa_pod_parse_object (p -> param , SPA_TYPE_OBJECT_Format , NULL , SPA_FORMAT_VIDEO_size ,
574
- SPA_POD_OPT_Rectangle (& resolution )) < 0 )
594
+ const struct spa_pod_prop * size_prop = spa_pod_find_prop (p -> param , NULL , SPA_FORMAT_VIDEO_size );
595
+ if (!size_prop )
596
+ continue ;
597
+
598
+ uint32_t n_sizes ;
599
+ const struct spa_rectangle * sizes =
600
+ get_values_from_pod (& size_prop -> value , SPA_TYPE_Rectangle , & n_sizes );
601
+ if (!sizes )
575
602
continue ;
576
603
577
- g_array_append_val (resolutions , resolution );
604
+ for (size_t i = 0 ; i < n_sizes ; i ++ )
605
+ g_array_append_val (resolutions , sizes [i ]);
578
606
}
579
607
580
608
g_array_sort (resolutions , compare_resolutions );
@@ -644,15 +672,9 @@ static void framerate_list(struct camera_device *dev, uint32_t pixelformat, cons
644
672
645
673
spa_list_for_each (p , & dev -> param_list , link )
646
674
{
647
- const struct spa_fraction * framerate_values ;
648
675
struct obs_pw_video_format obs_pw_video_format ;
649
- enum spa_choice_type choice ;
650
- const struct spa_pod_prop * prop ;
651
- struct spa_rectangle this_resolution ;
652
- struct spa_pod * framerate_pod ;
653
676
uint32_t media_subtype ;
654
677
uint32_t media_type ;
655
- uint32_t n_framerates ;
656
678
uint32_t format ;
657
679
658
680
if (p -> id != SPA_PARAM_EnumFormat || p -> param == NULL )
@@ -676,43 +698,39 @@ static void framerate_list(struct camera_device *dev, uint32_t pixelformat, cons
676
698
if (obs_pw_video_format .video_format != pixelformat )
677
699
continue ;
678
700
679
- if ( spa_pod_parse_object ( p -> param , SPA_TYPE_OBJECT_Format , NULL , SPA_FORMAT_VIDEO_size ,
680
- SPA_POD_OPT_Rectangle ( & this_resolution )) < 0 )
701
+ const struct spa_pod_prop * size_prop = spa_pod_find_prop ( p -> param , NULL , SPA_FORMAT_VIDEO_size );
702
+ if (! size_prop )
681
703
continue ;
682
704
683
- if (this_resolution .width != resolution -> width || this_resolution .height != resolution -> height )
705
+ uint32_t n_sizes ;
706
+ const struct spa_rectangle * sizes =
707
+ get_values_from_pod (& size_prop -> value , SPA_TYPE_Rectangle , & n_sizes );
708
+ if (!sizes )
709
+ continue ;
710
+
711
+ bool resolution_found = false;
712
+
713
+ for (size_t i = 0 ; i < n_sizes ; i ++ ) {
714
+ resolution_found =
715
+ (sizes [i ].width == resolution -> width && sizes [i ].height == resolution -> height );
716
+ if (resolution_found )
717
+ break ;
718
+ }
719
+
720
+ if (!resolution_found )
684
721
continue ;
685
722
686
- prop = spa_pod_find_prop (p -> param , NULL , SPA_FORMAT_VIDEO_framerate );
687
- if (!prop )
723
+ const struct spa_pod_prop * fr_prop = spa_pod_find_prop (p -> param , NULL , SPA_FORMAT_VIDEO_framerate );
724
+ if (!fr_prop )
688
725
continue ;
689
726
690
- framerate_pod = spa_pod_get_values ( & prop -> value , & n_framerates , & choice ) ;
691
- if ( framerate_pod -> type != SPA_TYPE_Fraction ) {
692
- blog ( LOG_WARNING , "Framerate is not a fraction - something is wrong" );
727
+ uint32_t n_framerates ;
728
+ const struct spa_fraction * fr = get_values_from_pod ( & fr_prop -> value , SPA_TYPE_Fraction , & n_framerates );
729
+ if (! fr )
693
730
continue ;
694
- }
695
731
696
- framerate_values = SPA_POD_BODY (framerate_pod );
697
-
698
- switch (choice ) {
699
- case SPA_CHOICE_None :
700
- g_array_append_val (framerates , framerate_values [0 ]);
701
- break ;
702
- case SPA_CHOICE_Range :
703
- blog (LOG_WARNING , "Ranged framerates not supported" );
704
- break ;
705
- case SPA_CHOICE_Step :
706
- blog (LOG_WARNING , "Stepped framerates not supported" );
707
- break ;
708
- case SPA_CHOICE_Enum :
709
- /* i=0 is the default framerate, skip it */
710
- for (uint32_t i = 1 ; i < n_framerates ; i ++ )
711
- g_array_append_val (framerates , framerate_values [i ]);
712
- break ;
713
- default :
714
- break ;
715
- }
732
+ for (size_t i = 0 ; i < n_framerates ; i ++ )
733
+ g_array_append_val (framerates , fr [i ]);
716
734
}
717
735
718
736
g_array_sort (framerates , compare_framerates );
0 commit comments