)
简介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. 获取底层pw_loop3. 创建pw_context4. 调用pw_context_connect5. 准备连接属性6. 建立协议通信通道7. 创建并返回pw_core代理8. 注册监听并进入Main Loop3.2 调用流程图3.3 Context连接生命周期图4. 实战应用案例5. 一句话总结已按官方API定义核对pw_context_connect()用于连接PipeWire实例成功后返回远端Core对象代理后续可通过该对象注册Core监听器并获取Registry。(PipeWire)1. 前言本篇目的Linux PipeWire深度解析之pw_context_connect调用流程与实战。要点概括核心功能使用已经创建的pw_context连接PipeWire实例并获得对应的pw_core代理对象。工作机制pw_context_connect()根据Context和连接属性创建远端连接建立客户端与PipeWire Daemon之间的协议通信通道。典型用途连接PipeWire服务、监听Core状态、获取Registry、创建Stream和访问远端对象。2. 应用场景与用法pw_context_connect()是PipeWire客户端建立服务端连接的核心接口。应用首先通过pw_context_new()创建Context。Context负责管理客户端侧资源、模块、协议实现和远端连接能力但此时还没有获得可操作的远端Core对象。随后调用pw_context_connect(context,properties,user_data_size);建立与PipeWire实例之间的连接。而该接口用于基于pw_context创建远端连接并返回代表PipeWire Core的pw_core代理对象。连接成功后应用可以继续注册Core Listener、获取Registry、枚举全局对象、创建Stream以及绑定远端Node、Device、Port等对象。函数原型structpw_core*pw_context_connect(structpw_context*context,structpw_properties*properties,size_tuser_data_size);参数说明context:由pw_context_new()创建的Context对象 properties:连接属性可以传入NULLuser_data_size:为返回的pw_core对象分配的用户私有数据大小返回值成功:返回structpw_core对象 失败:返回NULL并设置errno返回的pw_core不是PipeWire Server内部Core对象本身而是客户端侧用于访问远端Core接口的代理对象。应用场景pw_context_connect()常见应用场景主要有三类。第一类是连接PipeWire服务。普通PipeWire客户端在创建Main Loop和Context后需要调用pw_context_connect()连接正在运行的PipeWire Daemon。只有成功获得pw_core后客户端才能继续与服务端交换协议消息。第二类是Registry对象枚举。音频设备管理工具、视频设备查看工具和节点监控程序可以在连接成功后通过pw_core_get_registry()获取Registry代理再注册Registry Listener接收Node、Device、Port、Link、Metadata等全局对象的新增和移除事件。第三类是音视频Stream创建。播放、录音、摄像头采集和视频输出程序在创建pw_stream前通常需要先建立Core连接。Stream后续通过该Core连接完成节点创建、参数协商、Buffer传递以及状态事件接收。3. 调用流程剖析3.1 核心步骤1. 创建Main Loop应用首先调用structpw_main_loop*main_loop;main_looppw_main_loop_new(NULL);创建pw_main_loop对象。2. 获取底层pw_loop通过structpw_loop*loop;looppw_main_loop_get_loop(main_loop);获取Main Loop内部维护的pw_loop对象。3. 创建pw_context应用调用structpw_context*context;contextpw_context_new(loop,NULL,0);创建pw_context对象。Context保存Main Loop、客户端资源、协议实现以及远端连接所需的运行环境。4. 调用pw_context_connect应用执行structpw_core*core;corepw_context_connect(context,NULL,0);其中context: 连接使用的Context properties: 连接属性 user_data_size: Core用户私有数据大小5. 准备连接属性pw_context_connect()读取传入的连接属性。连接属性可以用于指定远端PipeWire实例名称 客户端名称 客户端访问意图 其他连接参数当properties为NULL时接口使用默认连接配置。6. 建立协议通信通道Context根据连接配置选择远端连接方式并与PipeWire实例建立通信通道。该通道用于后续传递Core方法调用 Core事件 Registry事件 Proxy方法调用 Stream控制消息 参数协商消息7. 创建并返回pw_core代理连接建立后客户端获得structpw_core*core;该对象表示远端PipeWire Core的客户端代理。应用可以通过它调用pw_core_add_listener() pw_core_get_registry() pw_core_sync() pw_core_disconnect()8. 注册监听并进入Main Loop连接成功后应用通常继续注册Core Listener和Registry Listenerpw_core_add_listener(...);pw_core_get_registry(...);pw_registry_add_listener(...);最后调用pw_main_loop_run(main_loop);进入事件循环接收服务端发送的异步事件。3.2 调用流程图3.3 Context连接生命周期图4. 实战应用案例#includepipewire/pipewire.h// PipeWire核心API#includestdio.h#includestdlib.hstructapp_data{structpw_main_loop*main_loop;// 主循环对象structpw_context*context;// PipeWire Contextstructpw_core*core;// 远端Core代理structpw_registry*registry;// Registry代理structspa_hookcore_listener;// Core事件监听器structspa_hookregistry_listener;// Registry事件监听器};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?message:unknown);pw_main_loop_quit(data-main_loop);// Core发生错误后退出Main Loop}staticconststructpw_core_eventscore_events{PW_VERSION_CORE_EVENTS,.errorcore_error_cb,};staticvoidregistry_global_cb(void*userdata,uint32_tid,uint32_tpermissions,constchar*type,uint32_tversion,conststructspa_dict*properties){printf(global: id%u type%s version%u\n,id,type?type:unknown,version);}staticvoidregistry_global_remove_cb(void*userdata,uint32_tid){printf(global removed: id%u\n,id);}staticconststructpw_registry_eventsregistry_events{PW_VERSION_REGISTRY_EVENTS,.globalregistry_global_cb,.global_removeregistry_global_remove_cb,};intmain(intargc,char*argv[]){structapp_datadata{0};structpw_loop*loop;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;}looppw_main_loop_get_loop(data.main_loop);// 获取底层pw_loopdata.contextpw_context_new(loop,NULL,0);// 创建Contextif(!data.context){fprintf(stderr,pw_context_new failed\n);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}data.corepw_context_connect(data.context,NULL,0);// 连接PipeWire实例并返回Core代理if(!data.core){fprintf(stderr,pw_context_connect failed\n);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事件监听器data.registrypw_core_get_registry(data.core,PW_VERSION_REGISTRY,0);// 获取Registry代理if(!data.registry){fprintf(stderr,pw_core_get_registry failed\n);spa_hook_remove(data.core_listener);pw_core_disconnect(data.core);pw_context_destroy(data.context);pw_main_loop_destroy(data.main_loop);pw_deinit();returnEXIT_FAILURE;}pw_registry_add_listener(data.registry,data.registry_listener,registry_events,data);// 注册Registry事件监听器resultpw_main_loop_run(data.main_loop);// 启动事件循环spa_hook_remove(data.registry_listener);spa_hook_remove(data.core_listener);pw_proxy_destroy((structpw_proxy*)data.registry);// 销毁Registry代理pw_core_disconnect(data.core);// 断开Core连接pw_context_destroy(data.context);// 销毁Contextpw_main_loop_destroy(data.main_loop);// 销毁Main Looppw_deinit();// 释放PipeWire资源returnresult0?EXIT_FAILURE:EXIT_SUCCESS;}5. 一句话总结pw_context_connect()本质上是“基于pw_context连接PipeWire实例并返回用于访问远端Core的pw_core代理对象”。它负责建立客户端与PipeWire Daemon之间的协议通信通道是Core事件监听、Registry对象枚举、Stream创建和远端对象访问的连接入口。