)
简介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从RingBuffer读取音频信息3.2底层按采样率和BPF换算4.实战案例4.1准备RingBuffer音频信息4.2执行Frame、时间和字节换算4.3完整代码5.总结1.前言本篇目的理解gst_audio_ring_buffer_convert()如何依据RingBuffer中的音频格式信息换算时间、Frame和字节数并通过示例观察不同单位之间的转换关系。音频元素需要响应GST_QUERY_CONVERT把调用方提供的一个数值从源单位换算为目标单位。gst_audio_ring_buffer_convert()读取GstAudioRingBuffer中的GstAudioInfo完成单位换算并返回结果。它只转换数值不转换PCM数据也不执行重采样。源单位和值gst_audio_ring_buffer_convertRingBuffer中的GstAudioInfo按采样率和BPF换算目标单位和值或失败状态2.应用场景和用法2.1处理音频单位换算原始音频常用三种单位描述位置或长度单位含义示例GST_FORMAT_DEFAULT原始音频Frame数48000个FrameGST_FORMAT_BYTESPCM数据字节数192000字节GST_FORMAT_TIME时间长度1秒对于S16LE双声道音频每个采样点占2字节每个Frame包含两个声道因此BPF为4。采样率为48000Hz时48000个Frame对应1秒也对应192000字节。gst_audio_ring_buffer_convert()可用于音频Sink响应格式换算查询。应用或上游元素发起GST_QUERY_CONVERT后GstAudioBaseSink会从查询中取出源格式和值调用该接口换算成功时再把目标格式和值写回查询。2.2函数原型与返回语义gbooleangst_audio_ring_buffer_convert(GstAudioRingBuffer*buf,GstFormat src_fmt,gint64 src_val,GstFormat dest_fmt,gint64*dest_val);参数含义buf提供音频格式信息的RingBuffer对象src_fmt输入数值的单位src_val输入数值dest_fmt目标单位dest_val接收换算结果的输出地址函数会锁住buf使用buf-spec.info中的采样率和BPF调用gst_audio_info_convert()。成功返回TRUE失败返回FALSE。调用方必须传入有效的RingBuffer和dest_val地址。原始音频中GST_FORMAT_DEFAULT表示Frame数。支持的转换单位为GST_FORMAT_BYTES、GST_FORMAT_TIME和GST_FORMAT_DEFAULT。采样率或BPF尚未配置时跨单位换算会失败不支持的单位组合也会返回FALSE。如果源单位和目标单位相同或者src_val为-1函数会把源值直接写入目标地址并返回成功。字节换算为Frame时会按整数除法处理不能整除的尾部字节不会组成完整Frame。相邻接口的职责不同接口职责gst_audio_ring_buffer_convert()基于RingBuffer中的音频信息换算数值单位gst_audio_info_convert()执行采样率、BPF参与的底层单位换算gst_query_parse_convert()从GST_QUERY_CONVERT中读取源单位和值gst_query_set_convert()将换算后的目标单位和值写回查询gst_audio_converter_samples()对PCM样本执行实际音频转换3.调用流程剖析3.1从RingBuffer读取音频信息gst_audio_ring_buffer_convert()本身没有复杂的格式分支。它先获取RingBuffer对象锁再把buf-spec.info、源单位、源值、目标单位和输出地址传给gst_audio_info_convert()最后释放对象锁并返回底层结果。GST_OBJECT_LOCK(buf);resgst_audio_info_convert(buf-spec.info,src_fmt,src_val,dest_fmt,dest_val);GST_OBJECT_UNLOCK(buf);这里的GstAudioInfo提供换算所需的采样率和BPF。函数不会检查或改变RingBuffer是否正在采集也不会访问环形缓冲区中的PCM内存。传入RingBuffer与单位参数获取对象锁读取spec中的GstAudioInfo调用音频信息换算释放对象锁并返回结果3.2底层按采样率和BPF换算底层换算函数根据源单位选择计算路径Frame转时间根据采样率换算。Frame转字节Frame数乘以BPF。字节转Frame字节数除以BPF。时间转Frame根据采样率换算到整数Frame。时间转字节先换算成Frame再乘以BPF。例如48kHz、S16LE双声道的音频中48000个Frame可换算为1秒或192000字节。反向从字节数换算Frame时如果字节数不是BPF的整数倍余数字节会被舍去。底层处理只接受受支持的单位组合。采样率或BPF为0时跨单位转换失败源、目标单位相同以及源值为-1则直接传递数值不需要进行比例计算。4.实战案例4.1准备RingBuffer音频信息示例创建一个测试用的GstAudioRingBuffer子类只用于承载GstAudioInfo不连接声卡。音频格式设为48kHz、S16LE、双声道因此每个Frame占4字节。4.2执行Frame、时间和字节换算示例执行两次换算将48000个Frame转换为时间结果应为GST_SECOND。将半秒转换为字节数结果应为96000字节。这些计算只验证单位换算关系不读取或改写PCM数据。4.3完整代码#includegst/gst.h#includegst/audio/audio.htypedefstruct_ConvertTestRingBuffer{GstAudioRingBuffer parent;}ConvertTestRingBuffer;typedefstruct_ConvertTestRingBufferClass{GstAudioRingBufferClass parent_class;}ConvertTestRingBufferClass;G_DEFINE_TYPE(ConvertTestRingBuffer,convert_test_ring_buffer,GST_TYPE_AUDIO_RING_BUFFER);staticvoidconvert_test_ring_buffer_class_init(ConvertTestRingBufferClass*klass){}staticvoidconvert_test_ring_buffer_init(ConvertTestRingBuffer*ring_buffer){}intmain(intargc,char*argv[]){ConvertTestRingBuffer*test_buffer;GstAudioRingBuffer*ring_buffer;GstAudioInfo*info;gint64 time_value-1;gint64 byte_value-1;gboolean frames_to_time;gboolean time_to_bytes;gboolean ok;gst_init(argc,argv);/* 创建测试RingBuffer供换算接口读取音频信息 */test_bufferg_object_new(convert_test_ring_buffer_get_type(),NULL);ring_bufferGST_AUDIO_RING_BUFFER(test_buffer);inforing_buffer-spec.info;/* 设置48kHz、S16LE、双声道音频格式 */gst_audio_info_init(info);if(!gst_audio_info_set_format(info,GST_AUDIO_FORMAT_S16,48000,2,NULL)){gst_object_unref(ring_buffer);return1;}/* 将48000个Frame换算为时间应得到1秒 */frames_to_timegst_audio_ring_buffer_convert(ring_buffer,GST_FORMAT_DEFAULT,48000,GST_FORMAT_TIME,time_value);/* 将半秒换算为字节应得到96000字节 */time_to_bytesgst_audio_ring_buffer_convert(ring_buffer,GST_FORMAT_TIME,GST_SECOND/2,GST_FORMAT_BYTES,byte_value);/* 检查两次换算是否成功并核对计算结果 */okframes_to_timetime_valueGST_SECONDtime_to_bytesbyte_value96000;gst_object_unref(ring_buffer);returnok?0:1;}5.总结gst_audio_ring_buffer_convert()根据RingBuffer保存的采样率和BPF换算音频单位数值不执行PCM转换或重采样。