本节摘要:管线里流动的不只是媒体数据。数据缓冲承载带时间戳的媒体内容顺流而下;事件沿衬垫双向穿行,宣告流开始、段开始、流结束等控制信息;查询反向逆流而上,询问位置、时长、可跳转性。三种流量各走各的车道、各有各的语法。本节把三者讲透并合并原查询机制的内容,是播放器交互功能的机制底座,第三章在此通水验收。
把一段管道放大看:数据车道最忙,缓冲一个接一个顺流而下;事件车道时而下行(能力集通报、段开始)时而上行(流结束、冲刷请求);查询车道基本逆流而上,下游向上游打听"现在播到哪了、总共多长、能不能跳"。三种流量的核心差异在方向与时机:缓冲随播放持续流动;事件在关键时刻出现;查询按需发起、有问必答。

缓冲是媒体数据的集装箱,箱体上贴着四张关键标签。显示时间戳:这一帧该在什么时刻呈现;解码时间戳:该在什么时刻解码(编码顺序与显示顺序不同时两者不同);时长:这一帧持续多久;偏移:在媒体流里的序号位置。此外还有一组标志位,其中两个直接关联第五章:无同步标志告诉汇元件"这帧别等对时、尽快出"(低延迟推流的关键),间断标志标示时间轴上出现了断层(跳转后必出现,汇要清空等待)。
缓冲的管理沿用引用计数,且支持"一箱多格":一个缓冲可以挂多块内存,对应视频的多个平面(亮度一格、色度一格)。零拷贝场景下,内存块还能指向显存——第七章的硬件加速全靠这个设计。
// 变换元件里收到一帧 检查间断标志 决定是否清空内部缓存 GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER(info); if (GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)) { reset_internal_state(self); // 时间轴断了 状态复位 } // 元数据只读 不改数据本身 g_print("帧序 偏移是 %ld 时间戳是 %ld\n", GST_BUFFER_OFFSET(buf), GST_BUFFER_PTS(buf));
事件是管线的控制报文。一次正常播放里,事件按固定顺序出场:流开始(数据车道开通前打头阵)→ 段开始(宣告时间轴基准与播放速率,跳转后重新下发)→ 数据缓冲鱼贯而入 → 流结束(最后一帧之后,宣告水放完了)。两个特殊事件要单独认识:冲刷开始与冲刷结束成对出现,跳转时先冲掉管道里在途的旧数据,再从新位置续流;能力集通报则随重协商出现(上一节已见)。
程序里对流结束事件的正确响应不是收到就退出,而是等汇元件把它消费完、再从总线上收流结束消息——事件是管线内部的通告,消息才是递给应用程序的正式文书,第四章把这个分工讲全。
# 用假汇观察事件流:丢弃数据但打印到达的缓冲与事件摘要 gst-launch-1.0 videotestsrc num-buffers=50 ! fakesink dump=true # 终端按序打印五十个缓冲 前后各有一次事件与段信息
查询由下游(通常是应用程序经汇元件)发起,逆流而上,能答的元件作答,不能答的继续上抛。日常高频四问:位置(现在播到哪)、时长(总共多长)、可跳转性(支不支持跳转、精度如何)、延迟(这条管线 inherent 延迟多大)。播放器的进度条、拖动响应、直播模式判断,全部建立在这四问上。
// 三问合一段:位置 时长 可跳转 gint64 pos = -1, dur = -1; gst_element_query_position(pipeline, GST_FORMAT_TIME, &pos); gst_element_query_duration(pipeline, GST_FORMAT_TIME, &dur); GstQuery *q = gst_query_new_seeking(GST_FORMAT_TIME); if (gst_element_query(pipeline, q)) { gboolean can_seek = FALSE; gst_query_parse_seeking(q, NULL, &can_seek, NULL, NULL); g_print("可跳转与否 %d\n", can_seek); } gst_query_unref(q);
查询的返回要判有效:直播流答不出时长、假汇答不出位置,都是正常现象而非错误。做界面时把"答不出"设计成常态(进度条隐藏或显示直播态),比硬把无效值当零处理专业得多。
⚠️ 常见坑:用查询返回失败当崩溃信号。弱网下位置查询偶发失败是正常的,重试即可;把它当致命错误直接停管线,是播放器"莫名退出"的一类隐蔽来源。
| 流量 | 方向 | 时机 | 高频成员 | 程序员接口 |
|---|---|---|---|---|
| 缓冲 | 下行 | 持续 | 帧与采样包 | 探针与元件内处理 |
| 事件 | 双向 | 关键节点 | 流开始 段开始 流结束 冲刷 | 衬垫事件回调 |
| 查询 | 上行 | 按需 | 位置 时长 跳转 延迟 | 元件查询接口 |
💡 关键直觉:缓冲是货,事件是调度令,查询是巡查单。货看时间戳,令看顺序,单看应答——三者混着理解,播放器的进度条逻辑永远理不顺。
到这里,通水阶段的知识闭环完成:会铺管(3.1)、懂水质单(3.2)、知谈判(3.3)、明流量(3.4)。自检两题:详细模式的一行输出里能指出哪些字段是协商定格的;流结束事件与流结束消息的区别是什么。答得上,说明你已经能"看懂水的语言"。
水的语言读完了,第四章接管运行时:状态机、总线、动态接线,主线播放器在此浇筑成型。