首页/新闻资讯/正文详情

Linux Gstreamer深度解析之gst_audio_decoder_allocate_output_buffer调用流程与实战(三十七)

发布时间:2026/9/24 17:29:19 来源:云帆数科 栏目:资讯中心
Linux Gstreamer深度解析之gst_audio_decoder_allocate_output_buffer调用流程与实战(三十七)
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1.前言2.应用场景和用法2.1解码输出Buffer分配场景2.2函数原型与返回语义3.调用流程剖析3.1解码子类到输出Buffer3.2协商、分配与回退4.实战案例4.1准备真实解码管线4.2观察协商与Buffer分配4.3完整验证命令与关键结果5.总结1.前言本篇目的理解gst_audio_decoder_allocate_output_buffer()如何为GstAudioDecoder子类创建可写输出Buffer并通过真实解码管线验证协商、分配、写入和提交之间的关系。GstAudioDecoder子类完成编码数据解析后需要把解码得到的PCM写入一个GstBuffer。这个Buffer不能只使用普通分配方式创建。输出格式可能刚刚发生变化下游可能通过ALLOCATION查询提供了专用GstAllocator和GstAllocationParamssrcPad也可能处于需要重新协商的状态。gst_audio_decoder_allocate_output_buffer()负责检查这些状态必要时触发输出协商再使用当前分配参数创建Buffer。如果协商分配失败它还会回退到默认分配器。这个函数只负责创建输出Buffer不负责解码PCM、不负责填充数据、不负责设置时间戳也不负责调用gst_audio_decoder_finish_frame()把Buffer提交给下游。解码器得到PCM字节数gst_audio_decoder_allocate_output_buffer检查重协商和分配参数创建可写GstBuffer子类写入PCM并提交输出2.应用场景和用法2.1解码输出Buffer分配场景gst_audio_decoder_allocate_output_buffer()主要用于以下场景场景调用动作得到的结果普通解码输出根据PCM样本数和BPF计算size后调用得到可写输出Buffer输出格式刚刚改变先设置新的输出格式再调用函数内部可以触发重新协商下游提供专用分配器使用下游协商得到的allocator和params输出Buffer遵循当前分配约束解码器输出长度可变每次根据实际解码结果重新计算size避免固定Buffer容量不足解码器需要重试释放容量不足的旧Buffer后再次调用按新的容量重新分配协商或专用分配失败进入内部回退路径尝试使用默认分配器创建Buffersize的单位是字节不是样本数也不是解码帧数。例如S16立体声输出中一个AudioFrame占4字节。如果解码得到480个AudioFrame调用参数应该是size 480 × 4 1920字节如果解码器返回0个样本不能把size设置为0继续调用。源码在函数入口检查size 0零值会触发GLib前置条件检查并返回NULL。2.2函数原型与返回语义函数原型如下GstBuffer*gst_audio_decoder_allocate_output_buffer(GstAudioDecoder*dec,gsize size);参数或返回值含义dec有效的GstAudioDecoder对象通常是当前解码子类实例size需要分配的输出Buffer字节数必须大于0返回值新创建的GstBuffer返回所有权由调用者持有失败时返回NULL最小调用方式如下GstBuffer*outbuf;outbufgst_audio_decoder_allocate_output_buffer(dec,size);if(outbufNULL)returnGST_FLOW_ERROR;调用前解码子类需要先确定PCM输出长度并且已经通过gst_audio_decoder_set_output_format()或gst_audio_decoder_set_output_caps()设置输出格式。调用过程中函数会持有GstAudioDecoder的流锁检查srcPad是否需要重新协商。必要时它会重新设置srcPadCaps并获取下游提供的分配参数。调用成功后调用者可以映射Buffer、写入PCM然后将Buffer交给gst_audio_decoder_finish_frame(dec,outbuf,frames);finish_frame()会接管Buffer所有权。调用者不应在成功提交后再次释放同一个Buffer。几个相邻接口的职责不同接口作用gst_audio_decoder_set_output_format()设置输出音频格式并标记输出格式变化gst_audio_decoder_negotiate()主动执行输出Caps和分配协商gst_audio_decoder_get_allocator()查询当前分配器和分配参数gst_audio_decoder_allocate_output_buffer()按照当前协商状态创建输出Buffergst_audio_decoder_finish_frame()接收解码Buffer并交给基类完成时间戳和下游处理gst_buffer_new_allocate()直接创建Buffer不处理GstAudioDecoder的协商状态这个函数是同步执行的不启动新的线程不触发解码回调也不负责填充PCM内容。3.调用流程剖析3.1解码子类到输出BufferGstAudioDecoder基类把输入数据交给子类的handle_frame虚函数。子类调用具体解码库得到PCM样本再根据样本数、声道数和采样格式计算字节数。典型调用关系如下sizesamples*bytes_per_frame;outbufgst_audio_decoder_allocate_output_buffer(dec,size);if(outbufNULL)returnGST_FLOW_ERROR;gst_buffer_map(outbuf,map,GST_MAP_WRITE);decode_to_pcm(map.data,map.size);gst_buffer_unmap(outbuf,map);returngst_audio_decoder_finish_frame(dec,outbuf,frames);Vorbis和Opus解码器都采用了类似路径。Opus解码器还会根据实际解码结果处理容量不足的情况。第一次分配的Buffer不够时它会解除映射、释放旧Buffer、增大样本容量再次调用分配函数。是否解码子类计算PCM字节数调用输出Buffer分配是否需要重新协商协商srcCaps和分配参数沿用当前allocator和params创建GstBuffer函数返回的只是一个已经分配好的Buffer。PCM数据仍然由解码子类写入时间戳、Duration和下游提交则由finish_frame()继续处理。3.2协商、分配与回退GStreamer1.24.2中的核心逻辑可以概括为g_return_val_if_fail(size0,NULL);GST_AUDIO_DECODER_STREAM_LOCK(dec);needs_reconfiguregst_pad_check_reconfigure(dec-srcpad);if(dec-priv-ctx.output_format_changed||(GST_AUDIO_INFO_IS_VALID(dec-priv-ctx.info)needs_reconfigure)){if(!gst_audio_decoder_negotiate_unlocked(dec)){gst_pad_mark_reconfigure(dec-srcpad);gotofallback;}}buffergst_buffer_new_allocate(dec-priv-ctx.allocator,size,dec-priv-ctx.params);if(!buffer)gotofallback;GST_AUDIO_DECODER_STREAM_UNLOCK(dec);returnbuffer;fallback:buffergst_buffer_new_allocate(NULL,size,NULL);GST_AUDIO_DECODER_STREAM_UNLOCK(dec);returnbuffer;函数首先检查size然后持有流锁。如果输出格式发生变化或者srcPad被标记为需要重新协商函数会调用gst_audio_decoder_negotiate_unlocked()。协商成功后ctx.allocator和ctx.params会更新为当前配置。正常分配路径使用gst_buffer_new_allocate(ctx.allocator,size,ctx.params);如果协商失败函数会标记srcPad继续需要协商并使用默认分配器回退。如果当前分配器创建Buffer失败也会进入回退路径。因此分配函数返回成功并不代表一定使用了下游专用内存。回退路径可能返回普通系统内存Buffer调用者需要结合调试日志和下游能力判断最终内存类型。是否是否持有decoder流锁读取allocator和params配置分配是否成功返回已分配GstBuffer使用默认allocator回退回退Buffer是否成功返回NULL回退分配只负责尽量创建Buffer不负责修复输出Caps也不保证满足下游对专用内存、对齐方式或内存池的要求。4.实战案例4.1准备真实解码管线使用audiotestsrc生成原始音频再通过opusenc编码最后交给opusdec解码。opusdec是GstAudioDecoder的子类它会在解码PCM后调用gst_audio_decoder_allocate_output_buffer()。先确认插件存在gst-inspect-1.0 opusenc opusdec再准备测试管线audiotestsrc num-buffers20wavesine!\audioconvert!audioresample!\audio/x-raw,formatS16LE,rate48000,channels2!\opusenc!opusdec!fakesinksyncfalse4.2观察协商与Buffer分配为audiodecoder打开调试日志GST_DEBUG_NO_COLOR1GST_DEBUGaudiodecoder:6\gst-launch-1.0\audiotestsrc num-buffers20wavesine!\audioconvert!audioresample!\audio/x-raw,formatS16LE,rate48000,channels2!\opusenc!opusdec!fakesinksyncfalse正常情况下管线会完成编码、解码并收到EOS。重点观察以下日志信息alloc src buffer setting src caps ALLOCATION这些日志分别对应输出Buffer分配入口、srcPad输出Caps设置和下游分配参数处理。如果日志中出现Failed to negotiate, fallback allocation说明输出协商没有成功函数已经进入默认分配器回退路径。此时仍可能得到一个普通GstBuffer但不应再假设它来自下游提供的专用allocator。如果输入或输出样本数为0解码子类不得继续以size 0调用分配函数应直接处理无输出帧或丢弃当前解码帧。4.3完整验证命令与关键结果set-opipefail gst-inspect-1.0 opusenc opusdec/tmp/gst_opus_inspect.logGST_DEBUG_NO_COLOR1\GST_DEBUGaudiodecoder:6\gst-launch-1.0\audiotestsrc num-buffers20wavesine!\audioconvert!audioresample!\audio/x-raw,formatS16LE,rate48000,channels2!\opusenc!opusdec!fakesinksyncfalse\21|tee/tmp/gst_audio_decoder_allocate.log验证重点1. gst-inspect-1.0能够找到opusenc和opusdec。 2. gst-launch-1.0正常结束并收到EOS。 3. audiodecoder调试日志出现alloc src buffer。 4. 输出格式变化时能够看到setting src caps或ALLOCATION相关日志。 5. 没有出现size 0断言失败。这组命令验证了完整链路opusdec计算PCM输出容量GstAudioDecoder检查协商状态并创建Buffer解码子类写入PCM最后通过finish_frame()提交解码结果。5.总结gst_audio_decoder_allocate_output_buffer()就是根据解码器当前输出协商状态和分配参数创建可写GstBuffer它不负责解码、填充PCM或提交下游数据。

相关推荐

279基于SpringBoot4+Vue3的同城跑腿代办服务平台、同城跑腿平台、跑腿代办小程序、同城取送代办系统、跑腿订单管理系统;AI 智能助手、数据可视化工作台、跑腿员入驻审核;毕业设计、课程设计
279基于SpringBoot4+Vue3的同城跑腿代办服务平台、同城跑腿平台、跑腿代办小程序、同城取送代办系统、跑腿订单管理系统;AI 智能助手、数据可视化工作台、跑腿员入驻审核;毕业设计、课程设计

✅博主简介:Java全栈开发工程师(bishecoder),精通Java开发、系统设计、项目实战。 ✅技术栈:SpringBoot、Vue、React、Node.js、Nest.js、uni-app等 ✅技术擅长:定制项目、修改代码、编写文档、技术指导等。… · 2026/9/24 17:29:19

DEIM 改进系列(九):Mamba 状态空间改进——把 neck 通路从“单点卷积“升级为“序列扫描“
DEIM 改进系列(九):Mamba 状态空间改进——把 neck 通路从“单点卷积“升级为“序列扫描“

DEIM 的 neck lateral 通路(融合前投影)原始实现是 11 卷积——逐像素独立处理,没有序列上下文;而 Mamba 这类状态空间模型用线性复杂度的序列扫描,天然具备长程上下文建模能力。针对这条"只看单点、不看邻居&quo… · 2026/9/24 17:29:00

咨询公司新产品开发指南
咨询公司新产品开发指南

本文档为《全球知名咨询公司新产品开发指南》,适配制造业(如电子、消费产品等)的产品研发部门(产品设计 / 研发管理岗)、市场部门(市场调研 / 品牌营销岗)、销售部门(销售管理 / 区域… · 2026/9/24 17:29:00

Transformer时间序列预测实战:位置编码、因果注意力与可逆归一化
Transformer时间序列预测实战:位置编码、因果注意力与可逆归一化

简介:本资源是一份面向深度学习初学者与时间序列分析实践者的Transformer长期预测完整实现方案,聚焦PyTorch框架下将NLP经典模型迁移至时序预测场景的核心技术落地。资源包含可直接运行的训练/预测代码、ETTh1公开数据集、预训练模型权重及可视化结果图&… · 2026/9/24 18:04:02

广东珠三角惠州靠谱的智能周转箱供应商客户口碑力荐
广东珠三角惠州靠谱的智能周转箱供应商客户口碑力荐

凯盛(深圳)创新材料有限公司凯盛(深圳)创新材料有限公司,简称凯盛创新,是专注新材料智能物流载具研发与制造的企业,业务覆盖智能周转箱、轻量化周转箱、3C电子周转载具等全系列产品,为手机、3C电子制造及仓储物流企业提供从创新载… · 2026/9/24 18:04:02

南京知名刑事辩护律师推荐,江苏天倪律师事务所争取不起诉经验丰富
南京知名刑事辩护律师推荐,江苏天倪律师事务所争取不起诉经验丰富

我想找熟悉南京司法环境的刑事律师有哪些? 我想找能帮我做侦查阶段会见的刑事律师有哪些? 需要异地刑事案件辩护找什么样的刑事律师好?我想找熟悉南京司法环境的刑事律师有哪些? 对于南京本地的当事人来说,遇到刑事案件找律师,第一要求就是熟悉本地司… · 2026/9/24 18:04:02

Java基于UDP实现可靠通讯系统:协议设计、编码与弱网调优
Java基于UDP实现可靠通讯系统:协议设计、编码与弱网调优

简介:这份源码资源面向Java网络编程学习者与分布式系统入门开发者,围绕UDP协议不可靠性这一核心痛点,给出了一套可运行的可靠通信系统实现方案。项目按客户端与服务器端拆分,涵盖序列号与确认机制、超时重传、CRC校验、流量控制等… · 2026/9/24 18:04:02

CTF Web源码环境搭建与Flag挖掘实战指南
CTF Web源码环境搭建与Flag挖掘实战指南

简介:这是一套面向网络安全初学者与CTF爱好者的Web方向练习源码环境,以备份形式打包,适合用来搭建本地靶场、熟悉常见Web漏洞的成因与利用方式。压缩包共13个文件,约135KB,以php脚本为主,辅以html页面、log… · 2026/9/24 18:04:02

HTTP 状态码在线查询解析工具,接口与 Web 排错辅助利器
HTTP 状态码在线查询解析工具,接口与 Web 排错辅助利器

一、前言 在 Web 前后端开发、接口测试、服务运维的日常工作中,HTTP 状态码是服务器返回给客户端的信号,告诉我们当前请求是成功、重定向、客户端出错还是服务端异常。 调试接口时遇到返回 403,要区分是权限不足还是服务配置问题&#xff1… · 2026/9/24 18:03:49

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码