Linux PipeWire深度解析之pw_context_connect_fd调用流程与实战(二十五)
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1. 前言要点概括2. 应用场景与用法函数原型参数说明返回值应用场景3. 调用流程剖析3.1 核心步骤1. 创建Main Loop2. 创建Context3. 创建Unix Domain Socket4. 连接PipeWire Socket5. 调用pw_context_connect_fd6. 创建协议连接7. 创建pw_core代理8. 将Socket接入pw_loop9. 返回pw_core10. 断开连接3.2 调用流程图3.3 Core FD连接生命周期图4. 实战应用案例5. 一句话总结按相同结构整理如下。1. 前言本篇目的Linux PipeWire 深度解析之pw_context_connect_fd调用流程与实战。要点概括核心功能使用一个已经连接到 PipeWire Server 的 Socket FD为指定pw_context创建远端 Core 连接。工作机制应用先获得已连接的 Unix Domain Socket FD再调用pw_context_connect_fd()PipeWire 基于该 FD 创建协议连接和本地pw_core代理并把 Socket 事件接入底层pw_loop。典型用途自定义 PipeWire 连接、跨进程传递连接 FD、容器或沙箱连接、接管已有 PipeWire Socket。2. 应用场景与用法pw_context_connect_fd()是 PipeWire Core 连接体系中的底层连接接口。通常情况下应用调用pw_context_connect()由 PipeWire 根据 Remote Name 自动查找并连接 PipeWire Server。而pw_context_connect_fd()要求应用提前准备一个已经连接的 Socket FD再把该 FD 交给 PipeWire 建立 Core 连接。该接口用于使用指定的已连接 Socket FD把pw_context连接到 PipeWire 实例并返回对应的pw_core对象。函数成功后传入的 FD 由 PipeWire Core 连接管理Core 断开或连接失败时该 Socket 会被自动关闭。传入的properties所有权也会被函数接管。(PipeWire)函数原型structpw_core*pw_context_connect_fd(structpw_context*context,intfd,structpw_properties*properties,size_tuser_data_size);参数说明context:由pw_context_new()创建的Context对象 fd:已经连接到PipeWire Server的Socket FD properties:Core连接使用的属性 可以传入NULL所有权由函数接管 user_data_size:附加在pw_core对象后的用户数据大小 不需要用户数据时传入0返回值成功:返回structpw_core指针 失败:返回NULL并设置errno返回的pw_core是客户端侧对远端 PipeWire Core 的代理对象后续可以注册 Core Listener、获取 Registry、创建远端对象或执行同步操作。(PipeWire)应用场景pw_context_connect_fd()常见应用场景主要有三类。第一类是使用自定义连接逻辑。部分应用不希望由pw_context_connect()自动查找默认 PipeWire Socket而是需要自行决定连接路径、Socket 类型或连接时机。应用可以先创建并连接 Unix Domain Socket再把得到的 FD 交给pw_context_connect_fd()。第二类是跨进程传递 PipeWire 连接。在 Broker、Portal、容器或沙箱系统中普通应用可能没有权限直接访问 PipeWire Runtime Socket。具有权限的管理进程可以建立连接再通过 Unix Socket 的SCM_RIGHTS机制把连接 FD 传递给目标进程目标进程使用pw_context_connect_fd()接管连接。第三类是测试与连接复用。在开发 PipeWire 协议测试工具、代理程序或自定义连接管理组件时可以显式控制 Socket 的建立过程再通过该接口创建pw_core。这样可以独立验证 Socket 连接、Core 协议通信和 Main Loop 事件处理。3. 调用流程剖析3.1 核心步骤1. 创建Main Loop应用首先创建structpw_main_loop*main_loop;main_looppw_main_loop_new(NULL);生成pw_main_loop对象。2. 创建Context获取底层pw_loop并创建pw_contextstructpw_context*context;contextpw_context_new(pw_main_loop_get_loop(main_loop),NULL,0);生成pw_context对象。3. 创建Unix Domain Socket应用创建 Socketfdsocket(AF_UNIX,SOCK_STREAM,0);此时只生成 Socket FD还没有与 PipeWire Server 建立连接。4. 连接PipeWire SocketPipeWire 默认 Remote Name 通常为pipewire-0Socket 通常位于$XDG_RUNTIME_DIR/pipewire-0应用调用connect(fd,...);连接成功后得到一个已经连接到 PipeWire Server 的 Socket FD。5. 调用pw_context_connect_fd应用执行corepw_context_connect_fd(context,fd,properties,0);其中传入pw_context Connected Socket FD pw_properties user_data_size6. 创建协议连接pw_context_connect_fd()基于传入 FD 创建 PipeWire Protocol Native 客户端连接。该连接负责协议消息编码与解码 Socket数据收发 对象ID管理 Proxy事件分发 Core错误处理7. 创建pw_core代理连接建立后客户端生成structpw_core该对象表示远端 PipeWire Server Core 在客户端中的代理。后续可以执行pw_core_add_listener() pw_core_get_registry() pw_core_sync() pw_core_create_object()8. 将Socket接入pw_loopPipeWire 把 Socket FD 注册到底层事件循环。运行pw_main_loop_run(main_loop);后底层pw_loop监听 Socket 可读、错误和断开事件并分发 Core、Registry 和 Proxy 回调。9. 返回pw_core连接创建成功后core!NULL应用保存该对象并注册 Core Listener 或获取 Registry。10. 断开连接不再使用时调用pw_core_disconnect(core);该操作会断开并销毁 Core 连接同时自动关闭此前传给pw_context_connect_fd()的 Socket FD。(PipeWire)3.2 调用流程图3.3 Core FD连接生命周期图4. 实战应用案例#includepipewire/pipewire.h// PipeWire核心API#includeerrno.h#includestddef.h#includestdio.h#includestdlib.h#includestring.h#includesys/socket.h// socket、connect#includesys/un.h// sockaddr_un#includeunistd.h// closestructapp_data{structpw_main_loop*main_loop;// 主循环对象structpw_context*context;// PipeWire Contextstructpw_core*core;// 远端Core代理structspa_hookcore_listener;// Core事件监听器};staticvoidcore_done_cb(void*userdata,uint32_tid,intseq){structapp_data*datauserdata;printf(core done: id%u seq%d\n,id,seq);pw_main_loop_quit(data-main_loop);}staticvoidcore_error_cb(void*userdata,uint32_tid,intseq,intresult,constchar*message){structapp_data*datauserdata;fprintf(stderr,core error: id%u seq%d result%d message%s\n,id,seq,result,message);pw_main_loop_quit(data-main_loop);}staticconststructpw_core_eventscore_events{PW_VERSION_CORE_EVENTS,.donecore_done_cb,.errorcore_error_cb,};staticintconnect_pipewire_socket(void){structsockaddr_unaddress{0};constchar*runtime_dir;intfd;runtime_dirgetenv(XDG_RUNTIME_DIR);if(!runtime_dir){fprintf(stderr,XDG_RUNTIME_DIR is not set\n);return-1;}fdsocket(AF_UNIX,SOCK_STREAM,0);if(fd0){fprintf(stderr,socket failed: %s\n,strerror(errno));return-1;}address.sun_familyAF_UNIX;if(snprintf(address.sun_path,sizeof(address.sun_path),%s/pipewire-0,runtime_dir)(int)sizeof(address.sun_path)){fprintf(stderr,PipeWire socket path is too long\n);close(fd);return-1;}if(connect(fd,(structsockaddr*)address,sizeof(address))0){fprintf(stderr,connect failed: %s\n,strerror(errno));close(fd);return-1;}returnfd;}intmain(intargc,char*argv[]){structapp_datadata{0};structpw_properties*properties;intfd;intseq;intresult;pw_init(argc,argv);// 初始化PipeWire环境data.main_looppw_main_loop_new(NULL);// 创建Main Loopif(!data.main_loop){fprintf(stderr,pw_main_loop_new failed\n);pw_deinit();returnEXIT_FAILURE;}data.contextpw_context_new(pw_main_loop_get_loop(data.main_loop),NULL,0);// 创建Contextif(!data.context){fprintf(stderr,pw_context_new failed\n);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}fdconnect_pipewire_socket();// 建立Unix Socket连接if(fd0){pw_context_destroy(data.context);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}propertiespw_properties_new(PW_KEY_APP_NAME,pw_context_connect_fd_demo,NULL);// 创建Core连接属性data.corepw_context_connect_fd(data.context,fd,properties,0);// 使用已连接FD创建Core连接if(!data.core){fprintf(stderr,pw_context_connect_fd failed: %s\n,strerror(errno));/* * connect_fd失败时FD也由PipeWire关闭 * 此处不再调用close(fd)。 */pw_context_destroy(data.context);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}pw_core_add_listener(data.core,data.core_listener,core_events,data);// 注册Core事件监听器seqpw_core_sync(data.core,PW_ID_CORE,0);// 请求一次Core同步if(seq0){fprintf(stderr,pw_core_sync failed: %d\n,seq);pw_core_disconnect(data.core);pw_context_destroy(data.context);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}resultpw_main_loop_run(data.main_loop);// 运行事件循环spa_hook_remove(data.core_listener);// 移除Core监听器pw_core_disconnect(data.core);// 断开Core并自动关闭FDpw_context_destroy(data.context);// 销毁Contextpw_main_loop_destroy(data.main_loop);// 销毁Main Looppw_deinit();// 释放PipeWire资源returnresult0?EXIT_FAILURE:EXIT_SUCCESS;}5. 一句话总结pw_context_connect_fd()本质上是“使用一个已经连接到 PipeWire Server 的 Socket FD为pw_context创建远端pw_core连接”。它负责接管 Socket FD、建立 PipeWire Native Protocol 通信、创建客户端 Core 代理并把连接事件接入底层pw_loop是自定义连接、跨进程 FD 传递、容器接入和 PipeWire 代理程序中的核心连接接口。

相关新闻

我与 IT 这三十年:2009,代码开始在广场上生长

我与 IT 这三十年:2009,代码开始在广场上生长

2008 年写的是手机平台。到了 2009 年,另一个变化开始变得清楚:协作方式变了。 GitHub 是 2008 年上线的,但很多人的真正感知是在随后几年逐渐建立起来的。它不是第一个代码托管网站,也不是第一个版本控制工具。SourceForge、Goo…

2026/8/28 15:30:11 阅读更多 →
如何快速掌握Switch大气层系统:从安装到高级配置的完整教程

如何快速掌握Switch大气层系统:从安装到高级配置的完整教程

如何快速掌握Switch大气层系统:从安装到高级配置的完整教程 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 大气层系统(Atmosphere)是任天堂Switch上最强…

2026/8/25 21:34:10 阅读更多 →
3分钟快速解锁:终极免费QQ音乐解密转换器qmc-decoder使用指南

3分钟快速解锁:终极免费QQ音乐解密转换器qmc-decoder使用指南

3分钟快速解锁:终极免费QQ音乐解密转换器qmc-decoder使用指南 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 你是否曾遇到过这样的困扰?在QQ音乐精…

2026/8/28 23:53:17 阅读更多 →

最新新闻

法学专业学生亲测:AI写作论文工具能不能用?这4个场景真香

法学专业学生亲测:AI写作论文工具能不能用?这4个场景真香

"用AI写论文算不算学术不端?"这个问题在法学专业的课堂上已经吵了三年。2026年,答案逐渐清晰:中国政法大学、华东政法大学等多所高校陆续出台规定,允许AI辅助写作但要求声明使用范围。作为一个刚刚用AI工具辅助完成学年…

2026/8/29 5:59:58 阅读更多 →
视频标注矩形框

视频标注矩形框

目录 标注后保存当前图片: label_mp4.py 标注后保存当前图片: import glob import os.path import shutil import sys import threading import time import jsonimport cv2 import os import numpy as np from PyQt5.QtCore import QLibraryInfoos.environ["QT_QPA_…

2026/8/29 5:59:58 阅读更多 →
2026年工科毕设AI生成能做到什么程度?电子信息工程专业实测

2026年工科毕设AI生成能做到什么程度?电子信息工程专业实测

"听说现在AI能直接生成整套毕业设计?"在电子信息工程专业的毕业群里,这个话题隔几天就被翻出来吵一次。2026年,大模型写代码、画电路框图、生成仿真脚本的能力突飞猛进,但"AI生成毕设"到底是神器还是陷阱&…

2026/8/29 5:59:58 阅读更多 →
C 语言宏定义二义性问题分析与规避方法

C 语言宏定义二义性问题分析与规避方法

一、文章切入问题在嵌入式开发日常工作中,开发者常为了消除函数调用开销、提升运行效率,选择用宏实现简单计算、硬件操作封装、通用工具逻辑等功能。很多时候宏相关的代码能顺利通过编译,但运行结果却不符合预期,甚至出现偶现崩溃…

2026/8/29 5:59:58 阅读更多 →
2026年8月24日-8月30日(gis引擎第一季+ue肉鸽蓝图转C++)

2026年8月24日-8月30日(gis引擎第一季+ue肉鸽蓝图转C++)

根据月计划,本周 8月24日-8月30日,GIS引擎1-19到2-1,UE每天肉鸽蓝图转C 有时间可以看socket视频和ue c视频 落实到天, 周一,gis引擎1-19UE每天肉鸽蓝图转C 周二,gis引擎1-20UE每天肉鸽蓝图转C 周三&#xf…

2026/8/29 5:59:58 阅读更多 →
多传感器融合避障系统实战:激光雷达点云聚类与视觉检测融合解析

多传感器融合避障系统实战:激光雷达点云聚类与视觉检测融合解析

简介:在机器人、无人机与无人车的自主避障场景中,单一传感器往往难以应对复杂环境——激光雷达虽能提供精确距离,却对玻璃、细杆等目标感知乏力;视觉虽能识别语义,却缺乏可靠的深度信息。多传感器融合技术通过优势互补…

2026/8/29 5:58:58 阅读更多 →

日新闻

etc目录下的profile.d文件目录设置环境变量和全局脚本shell

etc目录下的profile.d文件目录设置环境变量和全局脚本shell

一、设置环境变量etc目录下的profile.d文件目录 /etc/profile.d1、编写 vi test.sh文件内容# jdk变量 export ZHK_HOME/root export PATH$PATH:$ZHK_HOME/test # 可以取出来ZHK_HOME变量给ZZZ_HOME赋值 export ZZZ_HOME${ZHK_HOME}/test2、刷新 执行source /etc/profile 命令使…

2026/8/29 0:00:24 阅读更多 →
【JavaScript】内存管理-垃圾回收机制-内存泄露

【JavaScript】内存管理-垃圾回收机制-内存泄露

内存管理 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()。 而 JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。释放的过程称为垃圾回收。 整…

2026/8/29 0:00:24 阅读更多 →
Labgrid-MCP:为嵌入式硬件实验室接入AI Agent操控能力

Labgrid-MCP:为嵌入式硬件实验室接入AI Agent操控能力

Labgrid-MCP 的目标是把 MCP(Model Context Protocol)能力延伸到真实嵌入式硬件实验室:AI Agent 通过一个标准化的 MCP Server,就能查看目标板状态、控制上电断电、复位开发板、读取串口日志,甚至执行镜像刷写。对于经…

2026/8/29 0:00:24 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/28 11:23:26 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/28 23:05:07 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/28 19:47:53 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/29 4:34:53 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/28 17:43:04 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/29 2:05:18 阅读更多 →