当前位置: 首页 > news >正文

Linux PipeWire深度解析之pw_properties_add调用流程与实战(六十一)

简介:CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址:多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课🚀
专题四:Android15快速自定义与集成音效实战课🚀
专题五:Android15音频策略实战课🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例)🚀

人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮


🍉🍉🍉文章目录🍉🍉🍉

  • 🌻1.前言
      • 要点概括
  • 🌻2.应用场景与用法
    • 函数原型
    • 参数说明
    • 返回值
    • 应用场景
  • 🌻3.调用流程剖析
    • 🌻3.1核心步骤
    • 🌻3.2调用流程图
    • 🌻3.3生命周期图
  • 🌻4.实战应用案例
  • 🌻5.一句话总结

🌻1.前言

本篇目的:

Linux PipeWire深度解析之pw_properties_add调用流程与实战。

要点概括

  • 核心功能:把一个spa_dict中的属性追加到已有pw_properties中,只添加目标集合中尚不存在的key。

  • 工作机制:遍历输入dict,对每个key检查目标properties是否已有该key;不存在则复制key/value并写入,已存在则保持原值不变。

  • 典型用途:合并默认属性、补充对象创建参数、为Context、Stream、Module、Node等对象构造最终属性集合。

pw_properties_add的本质是“补充属性”,不是“覆盖属性”。它适合把一组默认配置或附加属性填入目标properties,但不会破坏目标对象里已经存在的属性。

它和pw_properties_update的区别非常关键。pw_properties_update用于更新属性,输入dict中的新值会覆盖已有key;而pw_properties_add只添加缺失key,已有key保持不变。

它和pw_properties_set也不同。pw_properties_set面向单个key/value操作;pw_properties_add面向一组spa_dict批量合并。它和pw_properties_add_keys也不同,add_keys只添加指定key列表中的属性,而pw_properties_add会遍历整个dict。

因此,pw_properties_add适合用在“默认值兜底”和“非破坏性合并”场景,而不适合用来强制修改已有属性。

🌻2.应用场景与用法

pw_properties_add

是PipeWireProperties API中用于向已有属性集合补充缺失key/value的接口。

它处在PipeWire对象创建前的属性准备阶段。PipeWire中的很多对象都会携带属性,例如Context属性、Module属性、Stream属性、Node属性、Device属性等。应用或模块通常会先创建一个pw_properties对象,再把来自配置文件、默认参数、外部dict或业务逻辑的属性合并进去。

pw_properties_add用于把dict中尚不存在于目标properties里的属性追加进去。

函数原型

intpw_properties_add(structpw_properties*oldprops,conststructspa_dict*dict);

参数说明

structpw_properties*oldprops;

oldprops表示目标属性集合。

该对象是被修改的一方。函数会检查dict中的每个key是否已经存在于oldprops中。如果不存在,就把该key/value添加到oldprops中;如果已经存在,则保留oldprops中的原值。

conststructspa_dict*dict;

dict表示输入属性字典。

它是属性来源,不是最终持有者。函数只从dict中读取key/value,并把符合条件的属性复制到oldprops中。调用完成后,目标properties拥有新增属性的生命周期,dict仍然由原调用方管理。

返回值

返回值类型为:

int

返回值表示成功添加到oldprops中的属性数量。

如果返回0,表示dict中的key在oldprops中都已经存在,或者没有可新增的属性。返回0不一定是错误,它通常表示本次合并没有产生变化。

应用场景

第一类场景是合并默认属性。

模块或应用创建对象时,通常会先准备一组业务属性,再追加一组默认属性。此时使用pw_properties_add可以保证业务属性优先级更高,默认属性只在缺失时补充。

第二类场景是创建PipeWire对象前整理参数。

例如创建Stream、加载Module、创建Context或构造Node前,可能需要把配置文件属性、环境属性、用户传入属性合并成一个最终properties。pw_properties_add适合做非破坏性合并。

第三类场景是模块内部属性继承。

模块可能从外部传入一个spa_dict,再把其中没有被本地配置覆盖的属性补充到对象属性中。这样既能保留本地显式配置,又能继承上层默认配置。

第四类场景是避免误覆盖关键属性。

有些key可能已经被前面逻辑明确设置,例如node.name、media.class、application.name、stream.name等。使用pw_properties_add可以避免后续默认属性覆盖这些关键值。

🌻3.调用流程剖析

🌻3.1核心步骤

1.调用方准备目标pw_properties对象。

2.调用方准备输入spa_dict,dict中包含待补充的key/value属性。

3.调用pw_properties_add(oldprops,dict)。

4.函数遍历dict中的每个spa_dict_item。

5.对每个item取出key和value。

6.检查oldprops中是否已经存在相同key。

7.如果key已经存在,保持oldprops中的原值不变。

8.如果key不存在,把该key/value复制并添加到oldprops中。

9.每成功添加一个新属性,内部新增计数加1。

10.遍历完成后返回新增属性数量。

🌻3.2调用流程图

🌻3.3生命周期图

🌻4.实战应用案例

下面以“Stream属性默认值补充”为例,说明pw_properties_add的实际使用方式。

假设应用已经显式设置了stream.name和media.type,同时希望补充一组默认属性,但不能覆盖应用已经设置的属性。

#include<pipewire/pipewire.h>staticstructpw_properties*create_stream_props(void){structpw_properties*props;props=pw_properties_new(PW_KEY_MEDIA_TYPE,"Audio",PW_KEY_MEDIA_CATEGORY,"Playback",PW_KEY_MEDIA_ROLE,"Music",PW_KEY_STREAM_NAME,"user-music-stream",NULL);returnprops;}

上面这组属性可以理解为应用自己的显式配置。它表示这是一个音频播放流,角色是音乐,Stream名称由应用指定。

接下来准备一组默认属性:

staticconststructspa_dict_itemdefault_items[]={{PW_KEY_APP_NAME,"pipewire-demo"},{PW_KEY_MEDIA_TYPE,"Audio"},{PW_KEY_MEDIA_CATEGORY,"Playback"},{PW_KEY_NODE_NAME,"demo-node"},};staticconststructspa_dictdefault_dict={SPA_DICT_FLAG_SORTED,SPA_N_ELEMENTS(default_items),default_items,};

这里default_dict中也包含media.type和media.category。由于props里已经有这两个key,pw_properties_add不会覆盖它们。

staticvoidadd_default_props(structpw_properties*props){intadded;added=pw_properties_add(props,&default_dict);(void)added;}

调用完成后,props中的属性集合会变成:

media.type=Audio media.category=Playback media.role=Music stream.name=user-music-stream application.name=pipewire-demo node.name=demo-node

其中media.type和media.category来自原始props,不会被default_dict重新覆盖。application.name和node.name原来不存在,因此会被添加进去。

这就是pw_properties_add最典型的工程价值:让“显式配置”优先,让“默认配置”兜底。

如果把这里换成pw_properties_update,语义就变了。update会把dict中的同名key更新到props中,更适合“后来的配置覆盖前面的配置”这种场景。

staticvoidupdate_props(structpw_properties*props){pw_properties_update(props,&default_dict);}

在工程代码中,add和update不能随便互换。

如果你的目标是“缺什么补什么”,使用pw_properties_add。

如果你的目标是“以新配置为准”,使用pw_properties_update。

如果你的目标是“只改一个key”,使用pw_properties_set。

如果你的目标是“只添加指定key集合”,使用pw_properties_add_keys。

再看一个更贴近PipeWire对象创建的场景:

structstream_config{constchar*app_name;constchar*node_name;constchar*stream_name;};staticstructpw_properties*build_playback_properties(conststructstream_config*config,conststructspa_dict*extra){structpw_properties*props;props=pw_properties_new(PW_KEY_MEDIA_TYPE,"Audio",PW_KEY_MEDIA_CATEGORY,"Playback",PW_KEY_MEDIA_ROLE,"Music",PW_KEY_STREAM_NAME,config->stream_name,PW_KEY_NODE_NAME,config->node_name,PW_KEY_APP_NAME,config->app_name,NULL);if(extra!=NULL)pw_properties_add(props,extra);returnprops;}

这个函数的关键点是:config中的属性是主配置,extra只是补充配置。extra中如果包含同名key,不会覆盖config已经设置的值。

这种写法适合封装库、音频中间件、测试工具和模块代码。上层调用者可以传入额外属性,但不能意外覆盖核心属性。

如果业务确实允许外部属性覆盖默认值,顺序应反过来设计,或者直接使用pw_properties_update。属性合并的接口选择,本质上就是属性优先级设计。

🌻5.一句话总结

pw_properties_add是PipeWireProperties的非破坏性批量合并接口:它只把spa_dict中目标properties尚不存在的key/value添加进去,适合做默认属性补充和对象创建前的属性兜底。

http://www.jsqmd.com/news/1392285/

相关文章:

  • MySQL 8.0 MVCC 原理:从 Undo Log 隐式字段到 ReadView 视界判定
  • 2026大金空调配件服务商哪家好?大金空调配件公司推荐与系统改造服务商甄选英东制冷 随着国内商用楼宇、产业园、商业综合体 - 栗子测评
  • fSpy-Blender 插件实测:3 分钟让 Blender 相机精准对齐照片透视,附安装教程与避坑指南
  • 软考 系统架构设计师历年真题集萃(320)—— 2026年5月系统架构设计师真题13
  • 深入解析电子商务网站前台建设:打造高转化率的线上 storefront 实战指南
  • 永嘉网站建设几年才见效?资深从业者揭秘低成本高效获客真相
  • 一套键盘鼠标控制三台电脑:Input Leap 开源 KVM 软件快速上手
  • NeurlPS 2025 | CHOICE:大型视觉-语言模型的遥感能力评估
  • 【Perplexity手机版生成的表格怎么复制下来】?这个“世纪难题”终于被 AI 导出鸭 终结了
  • OpCore-Simplify 上手实测:把 OpenCore EFI 一键生成从 8 小时压到 40 分钟
  • 2026 年青岛楼宇对讲 梯控 门禁道闸弱电工程施工问答 - LYL仔仔
  • 在Windows电脑上直接安装安卓应用:APK-Installer零基础实战指南
  • 注塑机数据采集联网分析作用
  • 恋活!HF Patch上手指南:一次安装,解决汉化、去码与模组缺失
  • Kubernetes Service 与 Deployment 关联与访问完整演示【20260812】
  • 建站小白必看:到底网站建设用什么程序才能既省钱又专业?揭秘底层逻辑与避坑指南
  • linux权限维持
  • PhotoRec数据恢复完整指南:免费开源工具从误删到分区损坏的全流程自救
  • 免搭建数据库!用几行 Python 代码打造轻量级自选股实时监控系统
  • Windows上3步搞定APK安装:不装模拟器、不敲命令,用开源工具APK Installer直接跑安卓应用
  • 基于微信小程序的在线维修服务平台系统毕业设计项目源码
  • 零基础实现 Windows 全局标题栏毛玻璃特效:DWMBlurGlass 安装与调优完整指南
  • IINA播放器快速上手指南:从安装到进阶,让Mac彻底告别播放难题
  • 2026 少儿线上外教一对一选课观察:跳出国籍执念,学习连续性远比噱头重要
  • 相机缓冲数据三种数据格式(数组、指针new、vector)
  • 多学科优化软件:工程设计的智能加速器
  • 第3篇:企业级CAS单点登录实战-技术架构设计方案
  • 一个关键结果节点怎样完成:AI、专业能力与人机协同的生产结构
  • 3分钟上手BiliTools:B站资源下载的免费跨平台工具箱
  • 远程操作手机的软件 远程app下载