简介:CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址:多媒体系统工程师系列【原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课🚀
专题四:Android15快速自定义与集成音效实战课🚀
专题五:Android15音频策略实战课🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例)🚀
人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2.应用场景和用法
- 2.1描述压缩音频的首尾裁剪
- 2.2函数原型与返回语义
- 🌻3.调用流程剖析
- 3.1验证格式并创建Meta实例
- 3.2裁剪Meta随Buffer传递
- 🌻4.实战案例
- 4.1准备带音频数据的Buffer
- 4.2添加Meta并重新查询
- 4.3完整代码
- 🌻5.总结
🌻1.前言
本篇目的:理解
gst_buffer_add_audio_clipping_meta()如何把音频裁剪信息附加到GstBuffer,分析Meta字段的含义和处理边界,并通过代码验证Buffer携带的裁剪样本数。
压缩音频的首帧可能包含编码器或解码器延迟产生的无效样本,末帧也可能带有用于填满编码帧的尾部填充。单靠Buffer字节长度无法表达这些样本应当从首尾裁掉多少。
gst_buffer_add_audio_clipping_meta()把裁剪格式、起始裁剪量和结束裁剪量记录为GstAudioClippingMeta。它只附加元数据,不会删除音频字节、修改Buffer时长,也不会自动执行裁剪。
🌻2.应用场景和用法
2.1描述压缩音频的首尾裁剪
GstAudioClippingMeta适合在不改动Buffer数据的情况下,随Buffer传递需要裁掉的首尾音频量。
| 场景 | 写入的信息 | 后续作用 |
|---|---|---|
| 解码器输出包含前置延迟 | 记录起始裁剪量 | 下游排除开头无效样本 |
| 编码末帧包含填充 | 记录结束裁剪量 | 下游还原有效音频长度 |
| 容器Demuxer输出数据 | 根据容器时间或样本边界计算首尾裁剪量 | 支持精确时长和无缝拼接 |
| 多段压缩音频拼接 | 保留每段边界上的裁剪信息 | 避免延迟与填充成为可听内容 |
gst_buffer_add_audio_clipping_meta()只保存描述值。实际消费者需要读取Meta,并结合其format解释start和end。当使用GST_FORMAT_DEFAULT时,这两个数值表示样本数。
2.2函数原型与返回语义
函数原型如下:
GstAudioClippingMeta*gst_buffer_add_audio_clipping_meta(GstBuffer*buffer,GstFormat format,guint64 start,guint64 end);| 参数或返回值 | 含义 |
|---|---|
buffer | 要附加Meta的Buffer,必须允许修改 |
format | start和end使用的单位,不能是GST_FORMAT_UNDEFINED |
start | 从Buffer开头裁掉的量 |
end | 从Buffer结尾裁掉的量 |
| 返回值 | 附加到Buffer上的Meta实例,由Buffer持有 |
实现只检查format不是GST_FORMAT_UNDEFINED,然后通过gst_buffer_add_meta()创建Meta实例并写入三个字段。它不检查裁剪量是否超过Buffer中的有效样本数,也不会修改Buffer的时长和数据。
调用者无需单独释放返回的GstAudioClippingMeta。释放其所属的GstBuffer时,Meta也会随之释放。读取已有裁剪信息使用gst_buffer_get_audio_clipping_meta()。
🌻3.调用流程剖析
3.1验证格式并创建Meta实例
函数首先检查format。如果格式是GST_FORMAT_UNDEFINED,就返回NULL。格式有效时,函数通过GST_AUDIO_CLIPPING_META_INFO取得Meta类型描述,并调用gst_buffer_add_meta()向Buffer添加实例。
新实例初始化时,Meta回调先把格式设为GST_FORMAT_UNDEFINED、首尾裁剪量设为0。添加函数随后覆盖这些默认值,写入调用者传入的format、start和end,最后返回实例指针。
3.2裁剪Meta随Buffer传递
这个Meta描述裁剪意图,真正如何处理取决于下游元素。容器Demuxer可以根据编码延迟或末尾填充计算裁剪样本数,再将它们附加到输出Buffer。其他元素读取Meta后,可以据此调整有效样本范围或时长。
Meta的复制回调支持整Buffer复制,并把相同的format、start和end添加到目标Buffer。对Buffer区域进行局部复制时,当前实现返回失败;它也没有自动换算重采样后的裁剪量。因此,裁剪Meta不能被当作已经修改音频数据的标记。
🌻4.实战案例
4.1准备带音频数据的Buffer
案例创建一个4096字节的测试Buffer,并把裁剪单位设为GST_FORMAT_DEFAULT。本例登记开头120个样本和结尾80个样本需要裁掉。
4.2添加Meta并重新查询
程序调用gst_buffer_add_audio_clipping_meta()后,再通过gst_buffer_get_audio_clipping_meta()读取同一个Buffer上的Meta实例。验证字段值只说明裁剪描述成功附加,不代表Buffer字节已经被裁剪。
4.3完整代码
#include<gst/gst.h>#include<gst/audio/audio.h>intmain(intargc,char*argv[]){GstBuffer*buffer;GstAudioClippingMeta*clipping_meta;guint64 start=120;guint64 end=80;intresult=1;gst_init(&argc,&argv);/* 创建测试Buffer,数据内容不由裁剪Meta自动修改 */buffer=gst_buffer_new_allocate(NULL,4096,NULL);if(buffer==NULL)return1;/* 将首尾裁剪量按样本数记录到Buffer */clipping_meta=gst_buffer_add_audio_clipping_meta(buffer,GST_FORMAT_DEFAULT,start,end);if(clipping_meta==NULL)gotodone;/* 从Buffer取回Meta,检查单位和首尾裁剪值 */clipping_meta=gst_buffer_get_audio_clipping_meta(buffer);if(clipping_meta!=NULL&&clipping_meta->format==GST_FORMAT_DEFAULT&&clipping_meta->start==start&&clipping_meta->end==end)result=0;done:gst_buffer_unref(buffer);returnresult;}🌻5.总结
gst_buffer_add_audio_clipping_meta()把裁剪单位和首尾裁剪量附加到GstBuffer,供后续元素解释处理,但不会自行修改Buffer数据或时长。