)
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1. 前言要点概括2. 用法与应用场景函数原型参数说明回调函数原型应用场景1. 等待 Stream READY2. 监听 Stream FAILED3. 监听 Stream TERMINATED3. 调用流程剖析3.1 核心步骤1. 应用层注册回调2. libpulse 保存回调指针3. Stream 状态发生变化4. libpulse 内部触发回调5. 应用层处理状态3.2 调用流程图3.3 Stream 状态回调生命周期图4. 实战应用案例5. 源码层核心原理6. 一句话总结1. 前言本篇目的Linux PulseAudio 深度解析之pa_stream_set_state_callback调用流程与实战。要点概括核心功能为pa_stream注册状态变化回调函数。工作机制当 Stream 生命周期状态发生变化时由 libpulse 内部异步触发应用层回调。2. 用法与应用场景pa_stream_set_state_callback是 PulseAudio 异步模型中的核心接口之一。在 PulseAudio 中Stream 创建是异步的服务端响应是异步的状态切换也是异步的因此应用程序必须依赖状态回调机制感知 Stream 生命周期变化。函数原型voidpa_stream_set_state_callback(pa_stream*s,pa_stream_notify_cb_tcb,void*userdata);参数说明s:需要注册状态回调的 pa_stream cb:状态变化回调函数 userdata:用户自定义私有数据回调函数原型typedefvoid(*pa_stream_notify_cb_t)(pa_stream*p,void*userdata);应用场景1. 等待 Stream READYif(pa_stream_get_state(s)PA_STREAM_READY)典型用途开始写音频数据启动录音启动播放流程2. 监听 Stream FAILEDif(pa_stream_get_state(s)PA_STREAM_FAILED)用于输出错误日志自动重连资源清理3. 监听 Stream TERMINATEDif(pa_stream_get_state(s)PA_STREAM_TERMINATED)用于释放 Stream停止主循环回收资源3. 调用流程剖析3.1 核心步骤1. 应用层注册回调应用程序调用pa_stream_set_state_callback(stream,stream_state_callback,userdata);2. libpulse 保存回调指针libpulse 内部会保存回调函数指针userdata 指针本质类似stream-state_callbackcb;stream-state_userdatauserdata;3. Stream 状态发生变化例如connect 成功connect 失败disconnect服务端异常退出都会导致stream-state发生变化。4. libpulse 内部触发回调当状态变化时libpulse 内部自动执行stream-state_callback(stream,userdata);5. 应用层处理状态应用层通常switch(pa_stream_get_state(s))处理READYFAILEDTERMINATED等状态。3.2 调用流程图是Application应用程序调用 pa_stream_set_state_callbacklibpulse 保存 callbackStream 生命周期继续运行状态是否变化?libpulse 更新 stream-state触发 state_callback应用层收到状态通知当前状态PA_STREAM_READYPA_STREAM_FAILEDPA_STREAM_TERMINATED允许 write错误处理资源释放3.3 Stream 状态回调生命周期图pa_stream_new注册 state_callbackconnect_playbackPA_STREAM_CREATING服务端 ACKPA_STREAM_READY触发 READY 回调服务端异常PA_STREAM_FAILED触发 FAILED 回调pa_stream_disconnectPA_STREAM_TERMINATED触发 TERMINATED 回调4. 实战应用案例#includepulse/pulseaudio.h#includestdio.hstaticconstchar*stream_state_to_string(pa_stream_state_tstate){switch(state){casePA_STREAM_UNCONNECTED:returnPA_STREAM_UNCONNECTED;casePA_STREAM_CREATING:returnPA_STREAM_CREATING;casePA_STREAM_READY:returnPA_STREAM_READY;casePA_STREAM_FAILED:returnPA_STREAM_FAILED;casePA_STREAM_TERMINATED:returnPA_STREAM_TERMINATED;default:returnUNKNOWN;}}/* * Stream 状态回调 */voidstream_state_callback(pa_stream*s,void*userdata){pa_stream_state_tstate;statepa_stream_get_state(s);printf(Stream State %s\n,stream_state_to_string(state));switch(state){casePA_STREAM_READY:printf(Stream 已 READY\n);break;casePA_STREAM_FAILED:fprintf(stderr,Stream FAILED\n);break;casePA_STREAM_TERMINATED:printf(Stream TERMINATED\n);break;default:break;}}intmain(){pa_stream*stream;/* * 假设 stream 已创建 */pa_stream_set_state_callback(stream,stream_state_callback,NULL);return0;}5. 源码层核心原理pa_stream_set_state_callback在 libpulse 中本质非常简单。内部逻辑类似voidpa_stream_set_state_callback(pa_stream*s,pa_stream_notify_cb_tcb,void*userdata){pa_assert(s);s-state_callbackcb;s-state_userdatauserdata;}你会发现它本质只是保存函数指针。真正触发回调的位置通常发生在pa_stream_set_state()内部。当stream-state发生变化后libpulse 自动调用s-state_callback(s,userdata);因此它是整个 PulseAudio 异步事件机制中的核心基础设施之一。6. 一句话总结pa_stream_set_state_callback本质上是“给 Stream 生命周期安装监听器”。它负责感知 READY感知 FAILED感知 TERMINATED驱动整个应用层异步状态机是 libpulse 异步架构中最核心的回调机制之一。