Linux PipeWire深度解析之pw_stream_dequeue_buffer调用流程与实战(八)

发布时间:2026/7/15 20:16:53

Linux PipeWire深度解析之pw_stream_dequeue_buffer调用流程与实战(八) 简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1. 前言要点概括2. 应用场景与用法函数原型参数说明返回值应用场景3. 调用流程剖析3.1 核心步骤1. process 回调触发2. 应用层取出 Buffer3. 判断 Buffer 是否为空4. 获取 spa_buffer5. 访问数据区6. 处理音频数据7. 更新 chunk 信息8. 重新提交 Buffer3.2 调用流程图3.3 Buffer 出队处理生命周期图4. 实战应用案例5. 一句话总结1. 前言本篇目的Linux PipeWire 深度解析之pw_stream_dequeue_buffer调用流程与实战。要点概括核心功能从pw_stream的可用 Buffer 队列中取出一个pw_buffer用于音频数据读写。工作机制PipeWire 在process回调中通知应用处理数据应用调用pw_stream_dequeue_buffer()取出 Buffer处理完成后再调用pw_stream_queue_buffer()重新提交。典型用途音频播放、音频采集、低延迟处理、音频数据搬运、实时音频算法处理。2. 应用场景与用法pw_stream_dequeue_buffer()是 PipeWire Stream 数据处理链路中的核心接口。在 PipeWire 中播放流、录音流、Filter 流、虚拟设备流最终都会围绕pw_stream和pw_buffer完成数据交换。而该接口用于从 Stream 的可用 Buffer 队列中取出一个 Buffer供应用读写音频数据。函数原型structpw_buffer*pw_stream_dequeue_buffer(structpw_stream*stream);参数说明stream:目标 pw_stream 对象返回值返回structpw_buffer*对象如果当前没有可用 Buffer则返回NULL调用者拿到pw_buffer后需要访问其中的spa_buffer、spa_data、chunk等字段完成数据处理。应用场景pw_stream_dequeue_buffer()常见应用场景主要有三类。第一类是音频播放数据填充。应用在process回调中调用该接口取出一个可写 Buffer然后把 PCM 数据写入buffer-datas[0].data再设置chunk-offset、chunk-stride、chunk-size等字段最后调用pw_stream_queue_buffer()重新提交给 PipeWire用于后续播放。第二类是音频采集数据读取。录音程序在process回调中调用该接口取出一个包含输入数据的 Buffer从spa_buffer中读取采集到的 PCM 数据然后送入编码器、降噪算法、唤醒算法、文件写入模块或网络传输模块处理完成后再把 Buffer 归还给 PipeWire。第三类是实时音频处理。在低延迟音频链路中应用通常不会额外拷贝大量数据而是在process回调里直接 dequeue Buffer、处理音频帧、更新 chunk 信息、queue Buffer。这样的模式适合回声消除、混音、音效处理、语音增强、车载音频链路调试等场景。3. 调用流程剖析3.1 核心步骤1. process 回调触发PipeWire 在 Stream 需要处理数据时触发process(...)应用通常在该回调中处理 Buffer。2. 应用层取出 Bufferpw_stream_dequeue_buffer(stream);表示从 Stream 的可用 Buffer 队列中取出一个 pw_buffer3. 判断 Buffer 是否为空if(!b)return;如果没有可用 Buffer当前回调直接返回。4. 获取 spa_bufferstructspa_buffer*bufb-buffer;pw_buffer是 PipeWire 层 Buffer 封装。真正承载数据的是spa_buffer5. 访问数据区常见访问路径buf-datas[0].data用于获取实际音频数据地址。6. 处理音频数据播放方向向 Buffer 写入 PCM 数据采集方向从 Buffer 读取 PCM 数据7. 更新 chunk 信息常见字段包括chunk-offset chunk-stride chunk-size这些字段描述当前 Buffer 中有效数据的位置、步进和大小。8. 重新提交 Buffer处理完成后必须调用pw_stream_queue_buffer(stream,b);把 Buffer 重新提交给 PipeWire。3.2 调用流程图3.3 Buffer 出队处理生命周期图4. 实战应用案例#includepipewire/pipewire.h#includestdio.h#includestring.hstaticvoidon_process(void*userdata){structpw_stream*stream;structpw_buffer*b;structspa_buffer*buf;structspa_data*data;uint32_tn_frames;uint32_tstride;streamuserdata;bpw_stream_dequeue_buffer(stream);if(!b){printf(out of buffers\n);return;}bufb-buffer;if(!buf||buf-n_datas0){pw_stream_queue_buffer(stream,b);return;}databuf-datas[0];if(!data-data||!data-chunk){pw_stream_queue_buffer(stream,b);return;}/* * 示例假设双声道 float32 PCM */stridesizeof(float)*2;/* * 示例写入 1024 帧静音数据 */n_frames1024;memset(data-data,0,n_frames*stride);data-chunk-offset0;data-chunk-stridestride;data-chunk-sizen_frames*stride;pw_stream_queue_buffer(stream,b);}staticconststructpw_stream_eventsstream_events{PW_VERSION_STREAM_EVENTS,.processon_process,};voidsetup_stream_process_callback(structpw_stream*stream,structspa_hook*listener){pw_stream_add_listener(stream,listener,stream_events,stream);}intmain(){structpw_stream*stream;structspa_hookstream_listener;/* * 假设 PipeWire 已初始化 * 假设 stream 已创建并连接成功 */setup_stream_process_callback(stream,stream_listener);return0;}5. 一句话总结pw_stream_dequeue_buffer()本质上是“从 PipeWire Stream 的可用队列中取出一个 Buffer用于当前 process 回调的数据处理”。它负责连接 PipeWire 的实时调度回调与应用层音频数据读写逻辑是播放、录音、Filter、低延迟音频处理和实时音频算法链路中非常核心的 Buffer 操作接口之一。

相关新闻