资讯动态

Linux PipeWire深度解析之pw_stream_get_properties调用流程与实战(四十七)

发布时间:2026/8/5 11:25:55 来源:尧图企业网站定制
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1. 前言要点概括2. 应用场景与用法函数原型参数说明返回值应用场景3. 调用流程剖析3.1 核心步骤1. 创建 Stream 属性表2. 创建 PipeWire Stream3. Stream 进入连接或运行阶段4. 调用 pw_stream_get_properties5. 返回 Stream 内部属性表6. 读取目标属性键值7. 根据属性执行策略判断8. Stream 销毁后属性指针失效3.2 调用流程图3.3 生命周期图4. 实战应用案例5. 一句话总结1. 前言本篇目的Linux PipeWire 深度解析之pw_stream_get_properties调用流程与实战。要点概括核心功能获取pw_stream对象当前保存的属性表用于读取 Stream 的媒体类型、媒体角色、节点名称、应用信息等属性。工作机制pw_stream_get_properties()从 Stream 内部直接返回struct pw_properties指针调用者再通过pw_properties_get()读取具体键值。典型用途Stream 创建后属性确认、回调中读取媒体信息、调试音频流分类、根据media.role或media.category执行业务策略。2. 应用场景与用法pw_stream_get_properties()是 PipeWire Stream 属性查询中的基础接口。应用创建 Stream 时通常会通过pw_properties_new()设置一组属性pw_properties_new(PW_KEY_MEDIA_TYPE,Audio,PW_KEY_MEDIA_CATEGORY,Playback,PW_KEY_MEDIA_ROLE,Music,NULL);这些属性会跟随 Stream 一起保存用于描述该流的媒体类型、媒体类别、业务角色、节点名称和应用信息。当程序需要读取这些属性时可以调用propspw_stream_get_properties(stream);而该接口用于获取当前pw_stream内部保存的属性表指针使调用者可以读取 Stream 的属性键值。需要注意pw_stream_get_properties()只负责返回 Stream 内部属性表不会复制属性对象也不会向 PipeWire Server 查询远程属性。函数原型conststructpw_properties*pw_stream_get_properties(structpw_stream*stream);参数说明stream:由pw_stream_new()或pw_stream_new_simple()创建的 Stream 对象返回值查询成功:返回 Stream 当前保存的 properties 指针 查询失败:返回NULL返回值类型为conststructpw_properties*表示调用者应当只读访问该属性表。调用者可以通过pw_properties_get(props,key);读取具体属性值。应用场景pw_stream_get_properties()常见应用场景主要有三类。第一类是 Stream 创建后的属性确认。应用创建播放流或录音流时通常会设置media.type、media.category、media.role、node.name等属性。创建完成后可以通过pw_stream_get_properties()读取属性表确认当前 Stream 的媒体描述是否符合预期。第二类是回调中的业务判断。在 Stream 状态变化、参数变化或处理流程中业务模块可以读取 Stream 属性根据media.role判断当前流是音乐、通话、通知还是导航语音再决定是否进入对应的音频策略分支。第三类是调试与问题定位。音频流路由错误、Stream 分类异常、策略未生效时可以通过该接口读取 Stream 属性确认应用传入的属性是否正确避免把路由问题误判为 PipeWire Server 或 WirePlumber 策略问题。3. 调用流程剖析3.1 核心步骤1. 创建 Stream 属性表应用首先创建 Stream 属性表propspw_properties_new(PW_KEY_MEDIA_TYPE,Audio,PW_KEY_MEDIA_CATEGORY,Playback,PW_KEY_MEDIA_ROLE,Music,PW_KEY_NODE_NAME,demo.playback,NULL);该属性表用于描述 Stream 的媒体属性和业务身份。常见属性包括media.type: 媒体类型例如 Audio media.category: 媒体类别例如 Playback 或 Capture media.role: 媒体角色例如 Music、Communication、Notification node.name: PipeWire 图中的节点名称2. 创建 PipeWire Stream应用通过属性表创建 Streamstreampw_stream_new_simple(pw_main_loop_get_loop(main_loop),demo-stream,props,stream_events,data);创建过程中属性表会与pw_stream对象绑定。从业务视角看关系可以表示为pw_stream └── properties ├── media.type ├── media.category ├── media.role └── node.name3. Stream 进入连接或运行阶段应用可以继续调用pw_stream_connect(stream,PW_DIRECTION_OUTPUT,PW_ID_ANY,flags,params,n_params);此时 Stream 会进入连接流程并逐步参与 PipeWire 图中的节点创建、端口协商和参数协商。pw_stream_get_properties()本身不依赖 Stream 必须处于运行状态只要 Stream 对象有效就可以读取其属性。4. 调用 pw_stream_get_properties应用或回调中执行propspw_stream_get_properties(stream);该调用直接进入 PipeWire Stream API。这是一个本地同步查询不需要等待 Main Loop也不会向 PipeWire Server 发送新的请求。5. 返回 Stream 内部属性表pw_stream_get_properties()返回 Stream 当前保存的属性表指针。逻辑上可以理解为returnstream-properties;这里返回的是内部对象指针不是属性表副本。因此调用者不应该修改或释放该返回值。6. 读取目标属性键值调用者拿到属性表后通过pw_properties_get()读取具体键值media_typepw_properties_get(props,PW_KEY_MEDIA_TYPE);media_rolepw_properties_get(props,PW_KEY_MEDIA_ROLE);如果目标键不存在则pw_properties_get()返回NULL。7. 根据属性执行策略判断读取属性后业务模块可以根据不同字段进入不同处理逻辑if(media_rolespa_streq(media_role,Music)){/* * 音乐流策略 */}例如Music: 普通音乐播放 Communication: 语音通话 Notification: 系统提示音 Movie: 视频播放这些属性通常会影响后续路由策略、音量策略、优先级策略和调试判断。8. Stream 销毁后属性指针失效当 Stream 被销毁后pw_stream_destroy(stream);之前通过pw_stream_get_properties()获取的属性指针也随之失效。应用不能在 Stream 销毁后继续访问该指针。3.2 调用流程图3.3 生命周期图4. 实战应用案例#includepipewire/pipewire.h// PipeWire核心API#includestdio.h#includestdlib.h#includestring.hstructapp_data{structpw_main_loop*main_loop;structpw_stream*stream;constchar*media_type;constchar*media_category;constchar*media_role;constchar*node_name;};staticvoidread_stream_properties(structapp_data*data){conststructpw_properties*props;propspw_stream_get_properties(data-stream);if(!props){return;}data-media_typepw_properties_get(props,PW_KEY_MEDIA_TYPE);data-media_categorypw_properties_get(props,PW_KEY_MEDIA_CATEGORY);data-media_rolepw_properties_get(props,PW_KEY_MEDIA_ROLE);data-node_namepw_properties_get(props,PW_KEY_NODE_NAME);}staticvoidstream_state_changed_cb(void*userdata,enumpw_stream_stateold_state,enumpw_stream_statestate,constchar*error){structapp_data*datauserdata;read_stream_properties(data);if(statePW_STREAM_STATE_ERROR){pw_main_loop_quit(data-main_loop);}}staticconststructpw_stream_eventsstream_events{PW_VERSION_STREAM_EVENTS,.state_changedstream_state_changed_cb,};intmain(intargc,char*argv[]){structapp_datadata{0};structpw_properties*props;intresultEXIT_FAILURE;pw_init(argc,argv);data.main_looppw_main_loop_new(NULL);if(!data.main_loop){pw_deinit();returnEXIT_FAILURE;}propspw_properties_new(PW_KEY_MEDIA_TYPE,Audio,PW_KEY_MEDIA_CATEGORY,Playback,PW_KEY_MEDIA_ROLE,Music,PW_KEY_NODE_NAME,demo.playback.stream,NULL);data.streampw_stream_new_simple(pw_main_loop_get_loop(data.main_loop),demo-playback-stream,props,stream_events,data);if(!data.stream){pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}read_stream_properties(data);if(data.media_typestrcmp(data.media_type,Audio)0){resultEXIT_SUCCESS;}pw_stream_destroy(data.stream);pw_main_loop_destroy(data.main_loop);pw_deinit();returnresult;}5. 一句话总结pw_stream_get_properties()本质上是“返回 PipeWire Stream 内部保存的属性表指针使调用者可以读取该流的媒体描述和业务属性”。它负责获取 Stream 当前属性但不负责创建属性对象、复制属性表、更新远程节点属性或管理属性生命周期是 PipeWire Stream 创建、调试、策略判断和音频流分类中的基础接口。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价