@@ -535,6 +535,28 @@ static int compare_resolutions(gconstpointer a, gconstpointer b)
535535 return 0 ;
536536}
537537
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+
538560static void resolution_list (struct camera_device * dev , uint32_t pixelformat , obs_property_t * prop )
539561{
540562 g_autoptr (GArray ) resolutions = NULL ;
@@ -546,7 +568,6 @@ static void resolution_list(struct camera_device *dev, uint32_t pixelformat, obs
546568 spa_list_for_each (p , & dev -> param_list , link )
547569 {
548570 struct obs_pw_video_format obs_pw_video_format ;
549- struct spa_rectangle resolution ;
550571 uint32_t media_type , media_subtype , format ;
551572
552573 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
570591 if (obs_pw_video_format .video_format != pixelformat )
571592 continue ;
572593
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 )
575602 continue ;
576603
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 ]);
578606 }
579607
580608 g_array_sort (resolutions , compare_resolutions );
@@ -644,15 +672,9 @@ static void framerate_list(struct camera_device *dev, uint32_t pixelformat, cons
644672
645673 spa_list_for_each (p , & dev -> param_list , link )
646674 {
647- const struct spa_fraction * framerate_values ;
648675 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 ;
653676 uint32_t media_subtype ;
654677 uint32_t media_type ;
655- uint32_t n_framerates ;
656678 uint32_t format ;
657679
658680 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
676698 if (obs_pw_video_format .video_format != pixelformat )
677699 continue ;
678700
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 )
681703 continue ;
682704
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 )
684721 continue ;
685722
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 )
688725 continue ;
689726
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 )
693730 continue ;
694- }
695731
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 ]);
716734 }
717735
718736 g_array_sort (framerates , compare_framerates );
0 commit comments