ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Linux PipeWire深度解析之pw_stream_trigger_process调用流程与实战(五十五)

Linux PipeWire深度解析之pw_stream_trigger_process调用流程与实战(五十五)

简介: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_stream_trigger_process调用流程与实战。

要点概括

  • 核心功能:主动触发PipeWireStream进入一次process处理流程。

  • 工作机制:应用在需要处理媒体数据时调用该函数,请求PipeWire调度该Stream的process回调。

  • 典型用途:主动驱动型播放、事件触发型媒体生产、按需唤醒Stream处理、配合PW_STREAM_FLAG_TRIGGER控制处理节奏。

pw_stream_trigger_process的本质不是“处理Buffer”,而是“触发处理”。它不会分配Buffer,不会提交Buffer,也不会直接替代pw_stream_dequeue_buffer和pw_stream_queue_buffer。

在PipeWireStream模型中,真正的数据读写仍然发生在process回调内部。应用通常在process回调中调用pw_stream_dequeue_buffer取出Buffer,读写媒体数据后再调用pw_stream_queue_buffer提交或归还Buffer。pw_stream_trigger_process只负责告诉PipeWire:当前Stream需要进入一次处理路径。

它和pw_stream_dequeue_buffer的区别是:dequeue_buffer负责取出Buffer,trigger_process负责触发process处理机会。

它和pw_stream_queue_buffer的区别是:queue_buffer负责提交Buffer,trigger_process负责唤醒或请求处理流程。

它也不是同步播放接口。调用pw_stream_trigger_process不代表音频已经播放完成,也不代表视频帧已经显示完成,只表示应用请求PipeWire调度该Stream的处理回调。

🌻2.应用场景与用法

pw_stream_trigger_process

是PipeWireStream API中用于主动触发Stream处理过程的接口。

它位于Stream控制路径,而不是Buffer数据路径。应用创建Stream、注册process回调、连接目标Node之后,可以在业务侧数据到达、定时器触发、上游状态变化或手动驱动场景中调用该函数,请求PipeWire触发该Stream的process事件。

pw_stream_trigger_process用于主动请求PipeWire触发指定Stream的process处理流程。

函数原型

voidpw_stream_trigger_process(structpw_stream*stream);

参数说明

structpw_stream*stream;

stream表示需要触发处理的PipeWireStream对象。

该Stream通常已经完成创建、事件注册和连接。调用该函数前,应用应保证stream仍然有效,不能在Stream已经销毁、断开或生命周期不确定时继续触发。

返回值

该函数没有返回值。

工程上不能通过返回值判断process是否已经执行,也不能把它理解成同步完成接口。它的语义是触发处理请求,实际process回调何时执行,取决于Stream状态、PipeWire调度上下文、图运行状态以及应用是否正确配置触发模式。

应用场景

第一类场景是主动驱动型播放。

普通播放流通常由PipeWire图调度持续驱动。主动驱动型播放则更适合“有数据才处理”的场景,例如网络音频、解码器按包输出、业务侧环形缓冲区有数据后再触发处理。此时应用可以在数据到达后调用pw_stream_trigger_process,让process回调进入填充Buffer流程。

第二类场景是事件触发型媒体源。

某些媒体源不是固定周期连续产生数据,而是由外部事件驱动。例如按键音、提示音、短音效、一次性视频帧、测试源触发等。应用可以在事件发生时触发Stream处理,而不是让Stream持续空转。

第三类场景是配合PW_STREAM_FLAG_TRIGGER控制处理节奏。

当Stream采用触发式处理模式时,process回调不再完全依赖默认连续调度,而是由应用侧调用pw_stream_trigger_process推动处理。这样可以减少无效回调,也方便应用把处理节奏和业务数据状态绑定。

第四类场景是低延迟链路中的按需唤醒。

在实时音频、虚拟设备、音频桥接、车载提示音、DSP链路等场景中,应用可能希望在上游数据准备好后立即推动Stream处理。pw_stream_trigger_process可以作为应用侧到PipeWire处理路径之间的触发点。

🌻3.调用流程剖析

🌻3.1核心步骤

1.应用创建pw_stream对象。

2.应用注册process事件回调。

3.应用设置媒体格式、方向、参数和Stream连接标志。

4.应用调用pw_stream_connect连接到PipeWire图中的目标Node。

5.Stream完成协商后进入可处理状态。

6.外部事件到达,例如上游数据准备完成、定时器触发、业务状态变化。

7.应用调用pw_stream_trigger_process主动触发该Stream处理。

8.PipeWire接收触发请求,并在合适的调度上下文中触发process事件。

9.process回调被执行。

10.应用在process回调中调用pw_stream_dequeue_buffer取出Buffer。

11.应用根据Stream方向读写媒体数据。

12.应用调用pw_stream_queue_buffer提交或归还Buffer。

13.Buffer重新进入Stream队列,等待后续图调度或下一次触发。

🌻3.2调用流程图

🌻3.3生命周期图

🌻4.实战应用案例

下面以“事件触发型音频播放”为例,说明pw_stream_trigger_process的典型用法。

这个场景中,音频数据不是一直连续产生,而是上游业务模块在某个时刻写入环形缓冲区。应用检测到有新PCM数据后,调用pw_stream_trigger_process触发Stream进入process回调。process回调中再完成Buffer取出、PCM填充和Buffer提交。

structapp_data{structpw_stream*stream;structring_buffer*ring;uint32_tframe_size;};staticuint32_tread_pcm_from_ring(structring_buffer*ring,void*dst,uint32_tmax_bytes){/* * 实际项目中,这里从业务侧环形缓冲区读取PCM数据。 * 可能来自解码器、网络接收、提示音缓存或DSP输出。 */return0;}staticvoidon_process(void*userdata){structapp_data*app=userdata;structpw_buffer*b;structspa_buffer*buf;structspa_data*data;uint32_tn_bytes;b=pw_stream_dequeue_buffer(app->stream);if(b==NULL)return;buf=b->buffer;data=&buf->datas[0];if(data->data==NULL||data->chunk==NULL){pw_stream_queue_buffer(app->stream,b);return;}n_bytes=read_pcm_from_ring(app->ring,data->data,data->maxsize);data->chunk->offset=0;data->chunk->size=n_bytes;data->chunk->stride=app->frame_size;pw_stream_queue_buffer(app->stream,b);}

当上游数据到达时,应用调用触发函数:

staticvoidon_pcm_data_ready(structapp_data*app){if(app==NULL||app->stream==NULL)return;pw_stream_trigger_process(app->stream);}

这个案例中,pw_stream_trigger_process不是写数据的位置。它只是把“上游数据已经准备好”这个业务事件转换成PipeWireStream的处理请求。

真正的数据路径仍然是:

pw_stream_dequeue_buffer()填写或读取Buffer数据pw_stream_queue_buffer()

工程开发中要特别注意四个边界。

第一,trigger_process不能替代process回调。
应用不应该在触发函数外部直接操作Stream内部Buffer。Buffer读写仍然应放在process回调中完成。

第二,trigger_process不能替代queue_buffer。
触发处理只是让process有机会执行,Buffer处理完成后仍然必须通过pw_stream_queue_buffer提交或归还。

第三,不要在Stream生命周期结束后触发。
如果Stream已经destroy、disconnect或状态不确定,继续调用pw_stream_trigger_process会破坏对象生命周期边界。

第四,不要把它理解为固定周期驱动器。
固定周期由PipeWire图调度、Driver节点和Quantum节奏决定。pw_stream_trigger_process更适合应用侧主动触发处理,而不是替代整个图调度机制。

在音频播放场景中,pw_stream_trigger_process常用于“数据来了再处理”。
在采集或视频场景中,它也可以用于手动推进处理流程,但依然要遵守Stream方向、Buffer所有权和process回调边界。

🌻5.一句话总结

pw_stream_trigger_process是PipeWireStream控制路径中的主动触发接口:它不处理Buffer本身,而是请求PipeWire触发该Stream的process回调,让应用在正确的回调上下文中完成dequeue、读写和queue流程。

返回列表