use { crate::video::drm::{ DrmError, DrmMaster, DrmObject, DrmProperty, DrmPropertyDefinition, DrmPropertyType, }, ahash::AHashMap, bstr::{BString, ByteSlice}, std::rc::Rc, }; #[derive(Debug)] pub struct DefaultProperty { pub name: &'static str, pub prop: DrmProperty, pub value: u64, } #[derive(Copy, Clone)] pub(super) enum DefaultValue { Fixed(u64), Enum(&'static str), Bitmask(&'static [&'static str]), RangeMax, } pub(super) fn create_default_properties( props: &CollectedProperties, defaults: &[(&'static str, DefaultValue)], ) -> Vec { let mut res = vec![]; let mut defaults = defaults.iter(); 'outer: loop { let Some(&(name, def)) = defaults.next() else { break; }; if let Some((definition, _)) = props.props.get(name.as_bytes().as_bstr()) { let value = match def { DefaultValue::Fixed(v) => v, DefaultValue::Enum(e) => match &definition.ty { DrmPropertyType::Enum { values, bitmask: false, } => match values.iter().find(|v| v.name == e) { None => continue, Some(v) => v.value, }, _ => continue, }, DefaultValue::Bitmask(e) => match &definition.ty { DrmPropertyType::Enum { values, bitmask: true, } => { let mut res = 0; for &e in e { match values.iter().find(|v| v.name == e) { None => continue 'outer, Some(v) => res |= 1 << v.value, } } res } _ => continue, }, DefaultValue::RangeMax => match &definition.ty { DrmPropertyType::Range { max, .. } => *max, DrmPropertyType::SignedRange { max, .. } => *max as u64, _ => continue, }, }; res.push(DefaultProperty { name, prop: definition.id, value, }); } } res } pub(super) fn collect_properties( master: &Rc, t: T, ) -> Result { let mut props = AHashMap::new(); for prop in master.get_properties(t)? { let def = master.get_property(prop.id)?; props.insert(def.name.clone(), (def, prop.value)); } Ok(CollectedProperties { props }) } pub(super) fn collect_untyped_properties( master: &Rc, t: T, props: &mut AHashMap, ) -> Result<(), DrmError> { props.clear(); for prop in master.get_properties(t)? { props.insert(prop.id, prop.value); } Ok(()) } pub(super) struct CollectedProperties { pub(super) props: AHashMap, } impl CollectedProperties { pub(super) fn get(&self, name: &str) -> Result, DrmError> { match self.props.get(name.as_bytes().as_bstr()) { Some((def, value)) => Ok(TypedProperty { id: def.id, value: *value, }), _ => Err(DrmError::MissingProperty(name.to_string().into_boxed_str())), } } pub(super) fn to_untyped(&self) -> AHashMap { let mut res = AHashMap::new(); for (def, val) in self.props.values() { res.insert(def.id, *val); } res } } #[derive(Copy, Clone, Debug)] pub struct TypedProperty { pub id: DrmProperty, pub value: T, } impl TypedProperty { pub(super) fn map(self, f: F) -> TypedProperty where F: FnOnce(T) -> U, { TypedProperty { id: self.id, value: f(self.value), } } }