☰
Linux FFmpeg深度解析之avcodec_parameters_copy调用流程与实战(二十五)
2026/11/4 7:09:49 网站建设 项目流程

简介: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.前言

本篇目的:理解avcodec_parameters_copy()如何把一个AVCodecParameters对象的参数复制到另一个对象,并通过实战检查动态数据是否独立。

封装格式中的AVStream通过codecpar保存流的编码参数。转封装或创建过滤器链时,常常需要把一条流的参数复制到另一对象。

avcodec_parameters_copy()会先重置目标对象,再复制参数,并为外部数据分配独立存储。它不复制音视频帧,也不负责把参数写入容器。

源AVCodecParameters

avcodec_parameters_copy

重置目标对象

复制字段和动态数据

独立的目标参数对象

🌻2.应用场景和用法

2.1在参数对象之间复制编码信息

该接口适合复制源流的编解码参数到另一个AVCodecParameters,例如转封装时从输入流复制到输出流,或把参数复制到码流过滤器的输入参数对象。

场景复制目标复制后仍需处理的内容
转封装输入流codecpar到输出流codecpar根据输出容器要求处理codec_tag等字段
码流过滤器流参数到过滤器par_in初始化过滤器并处理其输出参数
参数快照当前参数对象到新分配的对象管理新对象的释放
初始化编码上下文不应直接用此函数使用avcodec_parameters_to_context()
2.2函数原型与返回语义
intavcodec_parameters_copy(AVCodecParameters*dst,constAVCodecParameters*src);
参数或返回值含义
dst已分配的目标参数对象
src要复制的源参数对象
返回值成功返回非负值,失败返回负的AVERROR错误码

函数会先释放目标对象已持有的动态数据,再复制结构字段。extradata、编码侧数据和AVChannelLayout等需要管理的内容会建立目标侧自己的存储。函数不接管源对象,也不改变源对象的所有权。

目标对象应由avcodec_parameters_alloc()创建,并在使用后通过avcodec_parameters_free()释放。若目标需要变成AVCodecContext,应使用avcodec_parameters_to_context();反向从上下文生成参数则使用avcodec_parameters_from_context()。

🌻3.调用流程剖析

3.1重置目标并复制字段

源码先调用内部重置逻辑清理目标对象,再把源结构中的字段复制到目标。随后将动态字段指针置空,避免目标对象沿用源对象的地址。

对于extradata,函数按extradata_size分配带输入缓冲区填充空间的新内存并复制字节。它还复制编码侧附加数据,并通过av_channel_layout_copy()建立独立声道布局。

源参数对象

清理目标旧数据

复制普通字段

深拷贝附加数据与声道布局

返回成功或AVERROR

复制不是合并:目标原有参数会被重置,之后由源对象的内容替代。实现先重置目标再读取源字段,因此源和目标必须是不同对象,不能把同一个指针同时作为dst和src。

3.2复制结果进入转封装或编码流程

转封装时,常见关系是in_stream->codecpar复制到out_stream->codecpar。复制成功后,应用还可能根据输出容器要求调整codec_tag,并设置输出流时间基,再写入容器头。

参数复制本身不执行码流转换。若编码格式、分辨率或采样格式需要改变,应进入解码、处理和重新编码流程,而不是只复制参数对象。

🌻4.实战案例

4.1准备源参数和目标对象

案例构造AAC音频参数,设置采样率、码率、声道布局和两字节AudioSpecificConfig,再分别分配源对象与目标对象。

4.2执行深拷贝并检查字段

调用avcodec_parameters_copy()后检查返回值、基本字段、声道布局和extradata内容。目标extradata应有自己的分配空间,释放目标对象不会释放源对象的数据。

4.3完整代码
#include<libavcodec/codec_par.h>#include<libavcodec/avcodec.h>#include<libavutil/mem.h>#include<string.h>intmain(void){AVCodecParameters*src=NULL;AVCodecParameters*dst=NULL;intret=1;constuint8_taac_config[2]={0x12,0x10};src=avcodec_parameters_alloc();dst=avcodec_parameters_alloc();if(src==NULL||dst==NULL)gotodone;/* 设置源对象的基本AAC音频参数 */src->codec_type=AVMEDIA_TYPE_AUDIO;src->codec_id=AV_CODEC_ID_AAC;src->format=AV_SAMPLE_FMT_FLTP;src->sample_rate=44100;src->bit_rate=128000;av_channel_layout_default(&src->ch_layout,2);/* 准备带FFmpeg要求填充空间的codec extradata */src->extradata=av_mallocz(sizeof(aac_config)+AV_INPUT_BUFFER_PADDING_SIZE);if(src->extradata==NULL)gotodone;memcpy(src->extradata,aac_config,sizeof(aac_config));src->extradata_size=sizeof(aac_config);/* 将源参数复制到独立目标对象 */if(avcodec_parameters_copy(dst,src)<0)gotodone;/* 检查普通字段和动态extradata是否正确复制 */if(dst->codec_id!=src->codec_id||dst->sample_rate!=src->sample_rate||dst->bit_rate!=src->bit_rate||dst->extradata_size!=src->extradata_size||dst->extradata==src->extradata||memcmp(dst->extradata,src->extradata,src->extradata_size)!=0)gotodone;ret=0;done:/* 两个参数对象分别拥有各自的动态数据 */avcodec_parameters_free(&dst);avcodec_parameters_free(&src);returnret;}

🌻5.总结

avcodec_parameters_copy()重置目标并复制源参数,为动态字段建立独立存储,不处理音视频帧或容器写入。

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

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

立即咨询