ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

Linux Gstreamer深度解析之gst_audio_encoder_get_frame_max调用流程与实战(五十九) 简介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_maxgst_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_maxgintgst_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设置参数并查询程序创建编码器对象后依次执行以下操作将每个处理单元的最小样本数和最大样本数都设置为1024。调用gst_audio_encoder_set_frame_max()设置最大单元数为3。调用gst_audio_encoder_get_frame_max()读取当前值并与期望值比较。生产编码器应在set_format()中设置这些参数。示例在对象创建后直接设置是为了集中展示Getter和Setter读取同一上下文配置的过程。4.3完整代码#includegst/gst.h#includegst/audio/audio.htypedefstruct_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_classGST_AUDIO_ENCODER_CLASS(klass);/* GstAudioEncoder子类需要提供帧处理回调 */encoder_class-handle_frameframe_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对象 */encoderGST_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_mingst_audio_encoder_get_frame_samples_min(encoder);frame_samples_maxgst_audio_encoder_get_frame_samples_max(encoder);frame_maxgst_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当前配置的最大处理单元数供子类确认基类的输入批量组织参数。
返回列表