Linux Pulseaudio深度解析之pa_stream_cancel_write用流程与实战(三十)
简介: CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列【原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

🍉🍉🍉文章目录🍉🍉🍉
🌻1. 前言
本篇目的:Linux PulseAudio 深度解析之 pa_stream_cancel_write 调用流程与实战。
要点概括
- 核心功能:取消一次尚未提交的 Stream 写缓冲操作。
- 工作机制:释放通过
pa_stream_begin_write获取的共享内存写入区域,并丢弃未提交的数据。
🌻2. 用法与应用场景
pa_stream_cancel_write
是 PulseAudio 零拷贝写入模型中的重要接口之一。
在 PulseAudio 中:
pa_stream_begin_write
用于申请共享内存写缓冲区pa_stream_write
用于真正提交数据pa_stream_cancel_write
用于放弃当前写操作
因此:
它本质是“撤销本次写入事务”。
函数原型
void pa_stream_cancel_write(
pa_stream *s);
参数说明
s:
需要取消写入操作的 pa_stream
返回值
无返回值
应用场景
1. begin_write 后数据生成失败
例如:
pa_stream_begin_write(...)
成功后:
- PCM 解码失败
- 数据生成失败
- 音频帧非法
此时需要:
pa_stream_cancel_write(stream);
放弃本次写缓冲。
2. 用户中断播放
例如:
- 用户点击停止
- 用户切歌
- 用户关闭播放器
当前未提交的数据:
需要立即丢弃。
3. 音频同步失败
例如:
- 时间戳错误
- 音频时钟漂移
- A/V Sync 失败
当前 Buffer 不再有效:
需要取消写入。
🌻3. 调用流程剖析
🌻3.1 核心步骤
1. 应用层申请写缓冲区
pa_stream_begin_write(
stream,
&data,
&size);
2. libpulse 分配共享内存区域
内部会:
- 分配 SHM Buffer
- 返回可写内存指针
例如:
data
3. 应用层决定放弃写入
例如:
- 数据异常
- 用户停止播放
- 解码失败
此时:
不再调用 pa_stream_write
4. 调用 cancel_write
pa_stream_cancel_write(stream);
5. libpulse 释放 Buffer
内部会:
- 回收共享内存区域
- 清空 pending write 状态
- 丢弃当前未提交数据
🌻3.2 调用流程图
🌻3.3 Cancel Write 生命周期图
🌻4. 实战应用案例
#include <pulse/pulseaudio.h>
#include <stdio.h>
void write_pcm_data(pa_stream *stream) {
void *data = NULL;
size_t size = 4096;
/*
* 申请共享内存写缓冲
*/
if (pa_stream_begin_write(
stream,
&data,
&size) < 0) {
fprintf(stderr,
"begin_write failed\n");
return;
}
/*
* 模拟 PCM 解码失败
*/
int decode_failed = 1;
if (decode_failed) {
printf("PCM decode failed\n");
/*
* 放弃本次写入
*/
pa_stream_cancel_write(stream);
return;
}
/*
* 正常写入
*/
pa_stream_write(
stream,
data,
size,
NULL,
0,
PA_SEEK_RELATIVE);
}
int main() {
pa_stream *stream;
/*
* 假设 stream 已 READY
*/
write_pcm_data(stream);
return 0;
}
🌻5. 源码层核心原理
pa_stream_cancel_write
在 libpulse 中核心逻辑是:
回收当前 pending write buffer。
内部逻辑类似:
void pa_stream_cancel_write(
pa_stream *s) {
pa_assert(s);
if (s->write_memblock) {
pa_memblock_unref(
s->write_memblock);
s->write_memblock = NULL;
}
}
你会发现:
它本质是在:
- 回收 memblock
- 清理 pending write
- 放弃当前 SHM Buffer
并不会:
- 向服务端提交数据
- 播放 PCM
- 发送 write packet
因此:
pa_stream_cancel_write
本质属于:
“零拷贝写入撤销接口”。
🌻6. 一句话总结
pa_stream_cancel_write
本质上是:
“撤销一次尚未提交的音频写事务”。
它负责:
- 放弃当前 Buffer
- 回收 SHM 内存
- 丢弃无效 PCM 数据
- 保持 Stream 写入状态一致性
是 PulseAudio 零拷贝写入模型中的核心安全接口之一。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)