mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: libcamera: source: handle enum controls better
If the `libcamera::ControlInfo` object explicitly lists the values of a
control, then use those values when adding `SPA_PROP_INFO_type` to
construct an enumerated choice object.
(cherry picked from commit e379267274)
			
			
This commit is contained in:
		
							parent
							
								
									b8bbcfdb96
								
							
						
					
					
						commit
						9b638d37d1
					
				
					 1 changed files with 77 additions and 30 deletions
				
			
		| 
						 | 
					@ -741,6 +741,32 @@ uint32_t prop_id_to_control(uint32_t prop_id)
 | 
				
			||||||
	return SPA_ID_INVALID;
 | 
						return SPA_ID_INVALID;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]]
 | 
				
			||||||
 | 
					bool control_value_to_pod(spa_pod_builder& b, const libcamera::ControlValue& cv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (cv.isArray())
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (cv.type()) {
 | 
				
			||||||
 | 
						case libcamera::ControlTypeBool: {
 | 
				
			||||||
 | 
							spa_pod_builder_bool(&b, cv.get<bool>());
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						case libcamera::ControlTypeInteger32: {
 | 
				
			||||||
 | 
							spa_pod_builder_int(&b, cv.get<int32_t>());
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						case libcamera::ControlTypeFloat: {
 | 
				
			||||||
 | 
							spa_pod_builder_float(&b, cv.get<float>());
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
[[nodiscard]]
 | 
					[[nodiscard]]
 | 
				
			||||||
std::array<T, 3> control_info_to_range(const libcamera::ControlInfo& cinfo)
 | 
					std::array<T, 3> control_info_to_range(const libcamera::ControlInfo& cinfo)
 | 
				
			||||||
| 
						 | 
					@ -774,41 +800,62 @@ spa_pod *control_details_to_pod(spa_pod_builder& b,
 | 
				
			||||||
			SPA_PROP_INFO_description, SPA_POD_String(cid.name().c_str()),
 | 
								SPA_PROP_INFO_description, SPA_POD_String(cid.name().c_str()),
 | 
				
			||||||
			0);
 | 
								0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cid.type()) {
 | 
						if (cinfo.values().empty()) {
 | 
				
			||||||
	case ControlTypeBool: {
 | 
							switch (cid.type()) {
 | 
				
			||||||
		auto min = cinfo.min().get<bool>();
 | 
							case ControlTypeBool: {
 | 
				
			||||||
		auto max = cinfo.max().get<bool>();
 | 
								auto min = cinfo.min().get<bool>();
 | 
				
			||||||
		auto def = !cinfo.def().isNone()
 | 
								auto max = cinfo.max().get<bool>();
 | 
				
			||||||
			? cinfo.def().get<bool>()
 | 
								auto def = !cinfo.def().isNone()
 | 
				
			||||||
			: min;
 | 
									? cinfo.def().get<bool>()
 | 
				
			||||||
 | 
									: min;
 | 
				
			||||||
 | 
								spa_pod_frame f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
 | 
				
			||||||
 | 
								spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
 | 
				
			||||||
 | 
								spa_pod_builder_bool(&b, def);
 | 
				
			||||||
 | 
								spa_pod_builder_bool(&b, min);
 | 
				
			||||||
 | 
								if (max != min)
 | 
				
			||||||
 | 
									spa_pod_builder_bool(&b, max);
 | 
				
			||||||
 | 
								spa_pod_builder_pop(&b, &f);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							case ControlTypeFloat: {
 | 
				
			||||||
 | 
								auto [ min, max, def ] = control_info_to_range<float>(cinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								spa_pod_builder_add(&b,
 | 
				
			||||||
 | 
										SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
 | 
				
			||||||
 | 
												def, min, max),
 | 
				
			||||||
 | 
										0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							case ControlTypeInteger32: {
 | 
				
			||||||
 | 
								auto [ min, max, def ] = control_info_to_range<int32_t>(cinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								spa_pod_builder_add(&b,
 | 
				
			||||||
 | 
										SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
 | 
				
			||||||
 | 
												def, min, max),
 | 
				
			||||||
 | 
										0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return nullptr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
		spa_pod_frame f;
 | 
							spa_pod_frame f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
 | 
							spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
 | 
				
			||||||
		spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
 | 
							spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
 | 
				
			||||||
		spa_pod_builder_bool(&b, def);
 | 
					
 | 
				
			||||||
		spa_pod_builder_bool(&b, min);
 | 
							if (!control_value_to_pod(b, cinfo.def()))
 | 
				
			||||||
		if (max != min)
 | 
								return nullptr;
 | 
				
			||||||
			spa_pod_builder_bool(&b, max);
 | 
					
 | 
				
			||||||
 | 
							for (const auto& cv : cinfo.values()) {
 | 
				
			||||||
 | 
								if (!control_value_to_pod(b, cv))
 | 
				
			||||||
 | 
									return nullptr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_pod_builder_pop(&b, &f);
 | 
							spa_pod_builder_pop(&b, &f);
 | 
				
			||||||
	} break;
 | 
					 | 
				
			||||||
	case ControlTypeFloat: {
 | 
					 | 
				
			||||||
		auto [ min, max, def ] = control_info_to_range<float>(cinfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		spa_pod_builder_add(&b,
 | 
					 | 
				
			||||||
				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
 | 
					 | 
				
			||||||
						def, min, max),
 | 
					 | 
				
			||||||
				0);
 | 
					 | 
				
			||||||
	} break;
 | 
					 | 
				
			||||||
	case ControlTypeInteger32: {
 | 
					 | 
				
			||||||
		auto [ min, max, def ] = control_info_to_range<int32_t>(cinfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		spa_pod_builder_add(&b,
 | 
					 | 
				
			||||||
				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
 | 
					 | 
				
			||||||
						def, min, max),
 | 
					 | 
				
			||||||
				0);
 | 
					 | 
				
			||||||
	} break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nullptr;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return reinterpret_cast<spa_pod *>(spa_pod_builder_pop(&b, &f));
 | 
						return reinterpret_cast<spa_pod *>(spa_pod_builder_pop(&b, &f));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue