简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻1. 前言

本篇目的:Linux PulseAudio 深度解析之 pa_stream_get_timing_info 调用流程与实战。

要点概括

  • 核心功能:获取当前 Stream 的时间信息(Timing Information)。
  • 工作机制:返回 libpulse 缓存的 pa_timing_info 结构体,用于计算播放延迟、缓冲区状态、设备时间戳等信息。

🌻2. 用法与应用场景

pa_stream_get_timing_info
是 PulseAudio 延迟控制体系中的核心接口之一。

在音频系统中:

  • 当前写入了多少数据
  • 设备已经播放了多少数据
  • 当前剩余多少延迟
  • 服务端缓冲区还有多少数据

都需要依赖:

pa_timing_info

结构体进行计算。

因此:

所有高精度音视频同步功能最终都会依赖 Timing Info。

函数原型

const pa_timing_info* pa_stream_get_timing_info(
        const pa_stream *s);

参数说明

s:
需要查询 Timing Info 的 pa_stream

返回值

返回 pa_timing_info 结构体指针

例如:

const pa_timing_info *info;

应用场景

1. 获取当前播放延迟

const pa_timing_info *info;

info =
    pa_stream_get_timing_info(stream);

用于:

  • 计算播放延迟
  • A/V 同步

2. 获取缓冲区状态

例如:

  • 当前 Buffer 剩余多少数据
  • 当前设备消费了多少数据

都依赖:

pa_timing_info

3. 音视频同步

例如:

  • 视频播放器
  • WebRTC
  • 音视频会议

都需要依据:

sink_usec

进行同步。


🌻3. 调用流程剖析

🌻3.1 核心步骤

1. 应用层调用
pa_stream_get_timing_info(stream);

2. libpulse 检查 stream 对象

内部首先检查:

  • stream 是否为空
  • stream 是否有效

3. 读取 stream->timing_info

libpulse 内部本质执行:

return &s->timing_info;

4. 返回 Timing Info

返回:

pa_timing_info

结构体。

例如:

write_index
read_index
sink_usec
transport_usec

等字段。


5. 应用层计算延迟

例如:

latency =
    info->sink_usec;

用于:

  • 延迟统计
  • 同步计算
  • Buffer 分析

🌻3.2 调用流程图

Application
应用程序

调用 pa_stream_get_timing_info

stream 是否有效?

返回 NULL

进入 libpulse

读取 stream->timing_info

返回 pa_timing_info

应用层获得 Timing Info

计算延迟

计算缓冲区

A/V 同步

🌻3.3 Timing Info 生命周期图

connect_playback

创建 Stream

服务端开始统计时间

更新 timing_info

客户端缓存 timing_info

调用
pa_stream_get_timing_info

获得 Timing Info

延迟计算

A/V 同步

缓冲区分析

🌻4. 实战应用案例

#include <pulse/pulseaudio.h>
#include <stdio.h>

void print_timing_info(
        pa_stream *stream) {

    const pa_timing_info *info;

    info =
        pa_stream_get_timing_info(stream);

    if (!info) {

        printf("timing info is NULL\n");
        return;
    }

    printf("write_index      = %lld\n",
           (long long)info->write_index);

    printf("read_index       = %lld\n",
           (long long)info->read_index);

    printf("sink_usec        = %llu us\n",
           (unsigned long long)
           info->sink_usec);

    printf("transport_usec   = %llu us\n",
           (unsigned long long)
           info->transport_usec);
}

void latency_demo(
        pa_stream *stream) {

    const pa_timing_info *info;

    info =
        pa_stream_get_timing_info(stream);

    if (!info)
        return;

    printf("Current latency = %llu us\n",
           (unsigned long long)
           info->sink_usec);
}

int main() {

    pa_stream *stream;

    /*
     * 假设 stream 已 connect 成功
     */

    print_timing_info(stream);

    latency_demo(stream);

    return 0;
}

🌻5. 源码层核心原理

pa_stream_get_timing_info
在 libpulse 中本质非常简单。

内部逻辑类似:

const pa_timing_info*
pa_stream_get_timing_info(
        const pa_stream *s) {

    pa_assert(s);

    return &s->timing_info;
}

你会发现:

它本质只是返回 stream->timing_info

并不会:

  • 发 Socket
  • 发协议包
  • 请求服务端
  • 做 IPC

真正的数据来源:

来自:

PA_COMMAND_REQUEST

以及:

pa_stream_update_timing_info()

同步过程。

服务端更新后:

libpulse 缓存:

stream->timing_info

因此:

pa_stream_get_timing_info
本质属于:

“Timing Info 本地缓存读取接口”。

🌻6. 一句话总结

pa_stream_get_timing_info
本质上是:

“获取当前 Stream 实时时间状态快照”。

它负责:

  • 获取播放延迟
  • 获取缓冲区状态
  • 支撑音视频同步
  • 支撑实时延迟分析

是 PulseAudio 延迟控制体系中的核心基础接口之一。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐