☰
Linux Gstreamer深度解析之gst_audio_encoder_get_frame_max调用流程与实战(五十九)
2026/10/6 2:44:47 网站建设 项目流程

简介: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基类使用配置组织输入数据
      • 🌻4.实战案例
        • 4.1准备编码器配置
        • 4.2设置参数并查询
        • 4.3完整代码
      • 🌻5.总结

🌻1.前言

本篇目的:理解gst_audio_encoder_get_frame_max()读取的配置值是什么,分析它如何影响GstAudioEncoder向子类提交输入数据,并通过最小C程序查询该值。

音频编码器子类可以设置每次交给handle_frame()处理的输入数据大小。固定输入样本数时,如果上游一次送来多个完整编码单元,基类可以把若干单元合并后再交给子类处理。

gst_audio_encoder_get_frame_max()用于查询当前配置的最大处理单元数。它只读取配置,不会设置批量大小,也不会读取或编码PCM数据。

GstAudioEncoder对象

读取frame_max配置

返回当前最大处理单元数

基类据此组织输入样本

向handle_frame提交输入

🌻2.应用场景和用法

2.1查询编码器输入批量配置

frame_max用于控制基类一次最多把多少个完整输入单元交给编码器子类处理。它只有在frame_samples_min和frame_samples_max相等时,才参与基类的批量组织逻辑。

场景查询目的需要关注的配置
固定帧长编码确认每次handle_frame()最多收到多少个完整单元frame_samples_min、frame_samples_max、frame_max
编码器调试判断多份PCM样本为何被合并后提交输入缓存中的可用字节数和frame_max
格式重新协商确认set_format()重新配置后的当前值在子类设置参数后再次查询
默认配置排查判断当前是否设置了批量上限查询结果为0时检查格式配置阶段

frame_max表示可合并处理的单元数量,不是每个单元包含的PCM样本数,也不是编码后的输出帧数。每个单元的样本数由frame_samples_min和frame_samples_max描述。

2.2函数原型与返回语义

函数原型如下:

gintgst_audio_encoder_get_frame_max(GstAudioEncoder*enc);
参数或返回值含义
enc有效的GstAudioEncoder对象
返回值当前配置的最大处理单元数

最小调用方式如下:

gint frame_max;frame_max=gst_audio_encoder_get_frame_max(encoder);

该函数直接读取编码器私有上下文中的frame_max字段,不修改编码器状态,也不分配对象。传入无效对象时,函数通过参数检查并返回0;有效对象的初始值或尚未配置时也可能是0,因此不能只凭0判断调用失败。

配置通常由编码器子类在set_format()中完成。若要求每个处理单元具有固定样本数,应先将最小和最大样本数设为相同值,再设置最大单元数:

gst_audio_encoder_set_frame_samples_min(encoder,1024);gst_audio_encoder_set_frame_samples_max(encoder,1024);gst_audio_encoder_set_frame_max(encoder,3);

gst_audio_encoder_set_frame_max()的值会在基类调用子类set_format()前重置为0。因此,子类应在每次格式配置时重新设置;需要确认生效值时,再调用gst_audio_encoder_get_frame_max()查询。

相邻接口职责如下:

接口职责
gst_audio_encoder_set_frame_samples_min()设置每个处理单元至少需要的每声道样本数
gst_audio_encoder_set_frame_samples_max()设置每个处理单元最多需要的每声道样本数
gst_audio_encoder_set_frame_max()设置基类一次最多合并多少个完整处理单元
gst_audio_encoder_get_frame_max()读取当前最大处理单元数
gst_audio_encoder_finish_frame()提交编码输出,并告知基类已处理的输入样本数

🌻3.调用流程剖析

3.1读取基类上下文中的配置值

gst_audio_encoder_get_frame_max()的实现很短,核心动作是检查对象类型后返回上下文中的frame_max:

gintgst_audio_encoder_get_frame_max(GstAudioEncoder*enc){g_return_val_if_fail(GST_IS_AUDIO_ENCODER(enc),0);returnenc->priv->ctx.frame_max;}

这里没有计算输入数据大小,也没有对配置值做转换。返回值反映的是当前保存的配置。

基类在处理新的输入格式时,会先把frame_samples_min、frame_samples_max和frame_max等参数重置,再调用子类的set_format()。子类需要在这个回调中重新设置参数,随后查询才能读到新格式对应的值。

否

是

调用get_frame_max

检查AudioEncoder对象

对象是否合法

返回0

读取ctx.frame_max

返回配置值

3.2基类使用配置组织输入数据

查询函数本身只读配置。真正使用frame_max的是基类的输入处理逻辑:基类从输入适配器中查看已有数据,并依据每个处理单元的样本数,计算本次交给handle_frame()的数据长度。

当frame_samples_min与frame_samples_max相等且大于0时,输入数据可以按固定大小划分。如果frame_max大于1,基类最多合并指定数量的完整单元;如果frame_max为0,基类可以把当前缓存中可组成的完整单元一起提交。值为1时,每次按一个单元处理。

例如,S16立体声每个样本帧占4字节。若每个处理单元包含1024个每声道样本,则一个单元占:

1024 × 4 = 4096字节

当frame_max为3且缓存中至少有3个完整单元时,基类最多提交3个单元,即12288字节。子类随后在handle_frame()中处理输入,并通过gst_audio_encoder_finish_frame()提交编码结果。

是

否

输入数据进入适配器

读取每单元样本数

最小和最大样本数相等

根据frame_max限制完整单元数

按现有样本范围组织输入

向handle_frame提交输入

🌻4.实战案例

4.1准备编码器配置

案例创建一个最小GstAudioEncoder子类,用来观察frame_max的设置和读取。

编码器将每个处理单元配置为1024个每声道样本,并将最大合并单元数设置为3。这样,查询接口应返回3。示例不启动完整音频管线,重点验证配置接口之间的关系。

4.2设置参数并查询

程序创建编码器对象后,依次执行以下操作:

  1. 将每个处理单元的最小样本数和最大样本数都设置为1024。
  2. 调用gst_audio_encoder_set_frame_max()设置最大单元数为3。
  3. 调用gst_audio_encoder_get_frame_max()读取当前值,并与期望值比较。

生产编码器应在set_format()中设置这些参数。示例在对象创建后直接设置,是为了集中展示Getter和Setter读取同一上下文配置的过程。

4.3完整代码
#include<gst/gst.h>#include<gst/audio/audio.h>typedefstruct_FrameMaxDemo{GstAudioEncoder parent;}FrameMaxDemo;typedefstruct_FrameMaxDemoClass{GstAudioEncoderClass parent_class;}FrameMaxDemoClass;staticvoidframe_max_demo_class_init(FrameMaxDemoClass*klass);staticvoidframe_max_demo_init(FrameMaxDemo*self);G_DEFINE_TYPE(FrameMaxDemo,frame_max_demo,GST_TYPE_AUDIO_ENCODER);/* 最小处理回调,本案例只查询配置,不执行真实编码 */staticGstFlowReturnframe_max_demo_handle_frame(GstAudioEncoder*encoder,GstBuffer*buffer){(void)encoder;(void)buffer;returnGST_FLOW_OK;}staticvoidframe_max_demo_class_init(FrameMaxDemoClass*klass){GstAudioEncoderClass*encoder_class=GST_AUDIO_ENCODER_CLASS(klass);/* GstAudioEncoder子类需要提供帧处理回调 */encoder_class->handle_frame=frame_max_demo_handle_frame;}staticvoidframe_max_demo_init(FrameMaxDemo*self){(void)self;}intmain(intargc,char*argv[]){GstAudioEncoder*encoder;gint frame_samples_min;gint frame_samples_max;gint frame_max;gst_init(&argc,&argv);/* 创建自定义GstAudioEncoder对象 */encoder=GST_AUDIO_ENCODER(g_object_new(frame_max_demo_get_type(),NULL));/* 固定每个处理单元的每声道样本数 */gst_audio_encoder_set_frame_samples_min(encoder,1024);gst_audio_encoder_set_frame_samples_max(encoder,1024);/* 设置一次最多合并处理3个完整单元 */gst_audio_encoder_set_frame_max(encoder,3);/* 读取基类当前保存的三个配置值 */frame_samples_min=gst_audio_encoder_get_frame_samples_min(encoder);frame_samples_max=gst_audio_encoder_get_frame_samples_max(encoder);frame_max=gst_audio_encoder_get_frame_max(encoder);g_print("frame_samples_min: %d\n",frame_samples_min);g_print("frame_samples_max: %d\n",frame_samples_max);g_print("frame_max: %d\n",frame_max);/* 最小值和最大值相等时,frame_max才用于固定单元的批量组织 */if(frame_samples_min!=frame_samples_max||frame_max!=3){gst_object_unref(encoder);return1;}gst_object_unref(encoder);return0;}

🌻5.总结

gst_audio_encoder_get_frame_max()就是读取GstAudioEncoder当前配置的最大处理单元数,供子类确认基类的输入批量组织参数。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询