news 2026/10/23 4:56:29

Linux Gstreamer深度解析之gst_audio_meta_get_info调用流程与实战(八十九)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux Gstreamer深度解析之gst_audio_meta_get_info调用流程与实战(八十九)

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

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

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

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


🍉🍉🍉文章目录🍉🍉🍉

      • 🌻1.前言
      • 🌻2.应用场景和用法
        • 2.1获取音频元信息描述
        • 2.2函数原型与返回语义
      • 🌻3.调用流程剖析
        • 3.1一次性创建并注册描述对象
        • 3.2描述对象与Buffer实例的关系
      • 🌻4.实战案例
        • 4.1准备音频Buffer和描述对象
        • 4.2获取描述并添加Meta实例
        • 4.3完整代码
      • 🌻5.总结

🌻1.前言

本篇目的:理解gst_audio_meta_get_info()如何注册并返回GstAudioMeta对应的GstMetaInfo,梳理元信息描述对象与Buffer中元信息实例的关系,并通过代码观察两者如何配合。

GstAudioMeta描述音频Buffer的数据布局,例如音频格式、有效样本数和各声道平面的偏移。gst_audio_meta_get_info()返回的是这个Meta类型的描述信息,不会创建GstAudioMeta实例,也不会修改Buffer。

把实例添加到Buffer的工作由gst_buffer_add_audio_meta()完成。理解这两个接口的边界,可以避免把“注册元信息类型”和“给Buffer附加元信息”混为一谈。

音频Meta类型

gst_audio_meta_get_info

注册并返回GstMetaInfo

gst_buffer_add_audio_meta

Buffer持有GstAudioMeta实例

🌻2.应用场景和用法

2.1获取音频元信息描述

gst_audio_meta_get_info()主要供GStreamer的Meta系统和相关API取得GstAudioMeta的类型描述。这个描述包含Meta的API类型、名称、实例大小,以及实例初始化、释放、复制和序列化等处理函数。

场景获取描述信息的作用后续动作
添加音频布局Meta让Meta系统识别GstAudioMeta类型调用gst_buffer_add_audio_meta()
查询Buffer中的音频Meta使用对应API类型查找Meta实例调用gst_buffer_get_audio_meta()
复制Buffer提供Meta复制处理函数GStreamer在支持的复制操作中调用transform函数
序列化音频Meta提供序列化和反序列化处理函数Meta系统按注册信息执行对应操作

GstAudioMeta常用于非交错音频。非交错数据中,每个声道分别存放,Buffer需要知道每个声道平面从哪个字节偏移开始。交错音频则通常由音频Caps和Buffer布局表达,不需要额外的平面偏移数组。

2.2函数原型与返回语义

函数原型如下:

constGstMetaInfo*gst_audio_meta_get_info(void);

函数没有输入参数,返回进程内注册的GstMetaInfo指针。第一次调用时,它会创建并注册描述对象;后续调用返回同一个静态描述对象。实现使用g_once_init_enter()和g_once_init_leave()保护初始化过程。

调用该函数不会分配Buffer中的Meta实例。Buffer需要可写,才能通过gst_buffer_add_audio_meta()添加实例。添加接口返回的GstAudioMeta由Buffer持有,调用者不应单独释放它。

几个相关接口的职责如下:

接口职责
gst_audio_meta_get_info()获取GstAudioMeta的注册描述
GST_AUDIO_META_INFO调用gst_audio_meta_get_info()的便捷宏
gst_audio_meta_api_get_type()获取音频Meta的API类型
gst_buffer_add_audio_meta()为Buffer创建并初始化GstAudioMeta实例
gst_buffer_get_audio_meta()从Buffer查找已有的GstAudioMeta实例

🌻3.调用流程剖析

3.1一次性创建并注册描述对象

gst_audio_meta_get_info()内部保存一个静态的GstMetaInfo指针。第一次进入时,函数创建描述对象,将GstAudioMeta的初始化、释放、复制、序列化和反序列化函数关联到该对象,再将描述信息注册到Meta系统。

if(g_once_init_enter((GstMetaInfo**)&audio_meta_info)){GstMetaInfo*info=gst_meta_info_new(GST_AUDIO_META_API_TYPE,"GstAudioMeta",sizeof(GstAudioMeta));info->init_func=gst_audio_meta_init;info->free_func=gst_audio_meta_free;info->transform_func=gst_audio_meta_transform;info->serialize_func=gst_audio_meta_serialize;info->deserialize_func=gst_audio_meta_deserialize;audio_meta_info=gst_meta_info_register(info);g_once_init_leave((GstMetaInfo**)&audio_meta_info,(GstMetaInfo*)audio_meta_info);}

描述对象注册后,函数返回静态指针。后续调用不再重复创建或注册。这里的GstMetaInfo是Meta类型的说明和操作表,不是附着在某个Buffer上的音频数据。

否

是

调用获取接口

描述对象已注册

创建GstMetaInfo

关联Meta处理函数

注册并保存静态指针

返回已保存指针

返回描述对象

3.2描述对象与Buffer实例的关系

添加实例时,gst_buffer_add_audio_meta()使用GST_AUDIO_META_INFO把Meta实例附加到Buffer,再将调用者提供的GstAudioInfo和样本数写入实例。非交错布局还会保存或计算声道偏移。

Meta实例的复制、释放和序列化行为来自注册时关联的处理函数。复制整个Buffer时,gst_audio_meta_transform()会在目标Buffer上重新添加音频Meta;释放实例时,gst_audio_meta_free()负责释放动态分配的偏移数组。

因此,读取gst_audio_meta_get_info()只能确认Meta类型描述已经注册。要确认某个Buffer是否实际携带音频布局信息,还需要调用gst_buffer_get_audio_meta()并检查返回的实例。

🌻4.实战案例

4.1准备音频Buffer和描述对象

案例创建一个S16LE、48kHz、双声道的Buffer,包含128个样本帧。每帧包含两个声道的样本,交错布局所需空间为512字节。

4.2获取描述并添加Meta实例

程序先调用gst_audio_meta_get_info()取得注册描述,再调用gst_buffer_add_audio_meta()向Buffer添加实例。添加完成后,通过gst_buffer_get_audio_meta()重新查询,并检查实例引用的描述对象和样本数量。

4.3完整代码
#include<gst/gst.h>#include<gst/audio/audio.h>intmain(intargc,char*argv[]){GstAudioInfo audio_info;GstBuffer*buffer;GstAudioMeta*audio_meta;constGstMetaInfo*meta_info;gsize samples=128;gsize buffer_size;intresult=1;gst_init(&argc,&argv);/* 设置Buffer对应的采样格式、采样率和声道数 */if(!gst_audio_info_set_format(&audio_info,GST_AUDIO_FORMAT_S16,48000,2,NULL))return1;/* 为128个双声道样本帧分配交错音频空间 */buffer_size=samples*GST_AUDIO_INFO_BPF(&audio_info);buffer=gst_buffer_new_allocate(NULL,buffer_size,NULL);if(buffer==NULL)return1;/* 获取GstAudioMeta的注册描述,不会在此处创建Meta实例 */meta_info=gst_audio_meta_get_info();if(meta_info!=GST_AUDIO_META_INFO)gotodone;/* 将音频格式与样本数作为Meta实例附加到Buffer */audio_meta=gst_buffer_add_audio_meta(buffer,&audio_info,samples,NULL);if(audio_meta==NULL)gotodone;/* 从Buffer查询实例,确认Meta描述和样本数 */audio_meta=gst_buffer_get_audio_meta(buffer);if(audio_meta!=NULL&&audio_meta->meta.info==meta_info&&audio_meta->samples==samples)result=0;done:gst_buffer_unref(buffer);returnresult;}

🌻5.总结

gst_audio_meta_get_info()负责一次性注册并返回GstAudioMeta类型描述,Buffer中的实际音频布局信息由添加接口创建为Meta实例。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 4:56:07

VS Code Agent技巧,再也不要复制粘贴了

我在 VS Code 里跟 AI Agent 聊代码&#xff0c;聊到一半&#xff0c;它给我的某个函数里有一段写得不太对。我想针对那一小段追问&#xff1a;“这里为什么不用缓存&#xff1f;”。于是我做了什么呢&#xff1f; 我用鼠标选中那段代码&#xff0c;按 CtrlC&#xff0c;打开对…

作者头像 李华
网站建设 2026/10/23 4:54:34

企业GEO优化需求差异与解决方案全解析

1. 企业规模与GEO优化需求差异解析不同体量的企业在GEO优化需求上存在显著差异&#xff0c;这直接决定了服务商的选择策略。我们以员工规模为基准划分四类企业时&#xff0c;会发现其技术需求和预算分配呈现阶梯式变化。**微型企业&#xff08;1-10人&#xff09;**通常面临的最…

作者头像 李华
网站建设 2026/10/23 4:53:03

LFM脉冲压缩雷达仿真:从信号生成到距离像的完整实现

简介&#xff1a;本资源是一套面向雷达信号处理初学者与Matlab实践者的线性调频&#xff08;LFM&#xff09;脉冲压缩雷达完整仿真教学包&#xff0c;聚焦于理解匹配滤波原理、提升距离分辨力与信噪比等核心雷达性能指标。资源包含21个文件&#xff0c;涵盖10张关键原理图&…

作者头像 李华
网站建设 2026/10/23 4:52:30

BrushNet 图像修复实践指南:用最小示例跑通文本引导修复

BrushNet 图像修复实践指南&#xff1a;用最小示例跑通文本引导修复 【免费下载链接】BrushNet [ECCV 2024] The official implementation of paper "BrushNet: A Plug-and-Play Image Inpainting Model with Decomposed Dual-Branch Diffusion" 项目地址: https:/…

作者头像 李华
网站建设 2026/10/23 4:51:23

Flutter应用更新全流程指南与实战经验

1. Flutter应用更新概述作为一款跨平台移动应用框架&#xff0c;Flutter凭借其高效的开发体验和出色的性能表现&#xff0c;已经成为众多开发者的首选。当我们在Google Play商店成功发布Flutter应用后&#xff0c;后续的版本更新迭代是不可避免的。不同于首次发布&#xff0c;应…

作者头像 李华
网站建设 2026/10/23 4:49:12

基于 Java Spring Boot 的萌宠宠物相亲系统设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华