3.2 Caps:流经管线的媒体能力单


3.2 Caps:流经管线的媒体能力单

本节摘要:Caps(能力集)是 GStreamer 描述媒体格式的语言:一个媒体类型加一组字段,字段可取固定值、范围或枚举。它在管线里有三种身份——衬垫模板(出厂规格)、能力过滤器(人工约束)、协商结果(定格格式)。本节讲透语法与三种身份的转换,为下一节的协商机制备好词汇表。承接首航命令里打印的那行输出,通往全册所有涉及格式的讨论。

一行输出拆出一门语言

首航的详细输出里有这样一行:媒体类型是裸视频,排布 I420,宽 320 高 240,帧率每秒 30 帧,像素纵横比 1 比 1。把它拆开:斜杠前的部分是媒体类型(裸视频、编码视频、原始音频、容器流),冒号后是一组键值字段。字段取值有三种形态:固定值(宽 320)、范围(帧率从 1 到 60)、枚举(档位取基线、主流、高规格三者之一)。这套语法是管线的世界语——模板声明用它、过滤器约束用它、协商定格用它、日志打印也是它。

能力集的语法解剖

能力集的语法解剖

"任意"与"空集"这两个特殊值值得单独记。任意出现在解码装配器的源垫模板里——读完文件头之前,它不知道会吐什么,模板干脆宣称来者不拒;空集则出现在解封装器的动态衬垫上,意思是"我确实有一个垫,但能力未知,等我通报"。日志里看到这两个词,就知道管线正在等下一步信息,而不是出了故障。

动手写第一个能力过滤器

上一节的表达式里其实已经用过过滤器语法,只是没点名。感叹号之间插入一段能力集,就是给这一段管道人工约束

# 约束测试源的输出:宽高定格 六百四十乘三百六十 gst-launch-1.0 videotestsrc ! \ video/x-raw,width=640,height=360 ! autovideosink # 约束帧率范围与排布:多个字段逗号相连 gst-launch-1.0 v4l2src ! \ video/x-raw,format=YUY2,width=1280,height=720,framerate=30/1 ! \ videoconvert ! autovideosink

过滤器的价值在收紧协商空间。摄像头能输出十几种格式组合,不约束时协商结果随驱动心情而定;把宽高与帧率钉死,管线行为才可复现。反过来的代价也要清楚:约束写得越死,可用元件越少——约束了一个冷门排布,可能整条管线协商失败。写过滤器的分寸是只钉影响业务的字段(分辨率、帧率、档位),排布这类实现细节交给转换元件。

能力集的三种身份互查

三种身份在工具与代码里各有一套查询动作,整理成速查表。

身份 哪里看 典型形态 用途
衬垫模板 目录查询命令 范围与枚举 选元件前验接口
能力过滤器 表达式与代码 部分固定 收紧协商空间
协商结果 详细模式与日志 全固定 验证实际行为

代码里查询协商结果也是常事,比如渲染前确认真实的宽高。

// 取源垫当前能力集 未定格时可能为空指针 GstPad *pad = gst_element_get_static_pad(conv, "src"); GstCaps *caps = gst_pad_get_current_caps(pad); if (caps && gst_caps_is_fixed(caps)) { GstStructure *s = gst_caps_get_structure(caps, 0); gint width = 0, height = 0; gst_structure_get_int(s, "width", &width); gst_structure_get_int(s, "height", &height); g_print("当前协商定格为 宽 %d 高 %d\n", width, height); } gst_caps_unref(caps); gst_object_unref(pad);

⚠️ 常见坑:把模板当结果。目录里查到的宽高范围只是"可能",程序里真拿宽高去分配缓冲前,必须用当前能力集接口确认已定格且为固定形态,否则拿到的是空指针或未固定结构。

从语法到运算

能力集不只是描述语言,还是可运算的对象:两个能力集可以求交集(协商的核心动作)、可以判断是否固定、可以从范围里挑一个值(收敛动作)。下一节把这些运算放进协商流程里演一遍——谁先出牌、谁提建议、谁拍板定格,全流程配上真实日志。

常见媒体类型速查表

媒体类型 含义 典型字段 常在哪里见到
裸视频 未压缩帧 排布 宽高 帧率 解码器之后
编码视频 压缩码流 档位 级别 解码器之前 封装器内部
裸音频 未压缩采样 采样格式 采样率 声道 音频解码之后
编码音频 压缩音频流 档位 比特率 音频解码之前
容器流 封装格式 流结构 解封装器前后
传输负载 网络封装包 载荷类型 时钟速率 推拉流的网络段
应用数据 自定义数据 视实现而定 自定义元件之间

速查表的用法是先认类型再看字段:拿到一行协商日志,先读媒体类型定位自己在数据流的哪一段(压缩侧还是裸数据侧),再看字段判断规格。配合第三章 3.1 节的详细模式,任何管线的实际走线都能这样逐段读懂。

能力集运算的三问三答

能力集是可运算对象,三个高频运算对应三个日常问题。问:这两边能不能接——求交集,交集非空即能接(协商第一步的机器判据);问:这条能力集是不是已经定了——固定性判断,全字段定值才是真·结果,含范围就还没谈完(3.2 节"模板不是结果"的机器版);问:从范围里挑哪个值——收敛运算,按规则从多种可能里选一个(高值优先、靠近默认)。三问在程序里的入口都是衬垫或能力集对象上的现成接口,返回值即答案。

这三个运算是第三章与第八章的桥:协商失败的判据是"交集为空",协商完成的判据是"已固定",跳转后的重协商是"再走一遍收敛"。把三问答熟,第八章排错实录里的每一步日志你都能预判它接下来打印什么。

本节要点回顾

  • 语法骨架:媒体类型打头,字段键值跟随,逗号分隔;
  • 字段三形态:固定值、范围、枚举,分别表示定死、可能、清单;
  • 两个特殊值:任意是通配,空集是待通报,都不是故障;
  • 三种身份:模板验货、过滤器约束、结果验证,同一门语言三种用法;
  • 过滤器分寸:钉业务字段,放实现细节;
  • 模板不是结果:分配资源前必须确认已定格。

词汇表备齐,下一节进入协商现场:三步流程、两个方向、三类失败。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U