AVFilter - 流媒体过滤器

流媒体过滤器 - AVFilter


函数说明

  • 函数名称 : avfilter_graph_alloc
  • 功能 : 相当于合拢所有过滤器的统一上下文

avfilter_init_str参数选项:

  • **abuffersink ( 媒体数据最终出口 ) **
keyvalue typevalue 选项默认值解释
NULLNULLNULLNULLNULL
  • aformat ( 将媒体数据进行格式化 )
keyvalue typevalue 选项默认值解释
sample_fmtsSTRING0格式化后的采样格式
sample_ratesSTRING0格式化后的采样率
channel_layoutsSTRING0格式化后的声道布局
  • amix ( 混音处 ):
keyvalue typevalue 选项默认值解释
inputsINTINT16_T_MAX2输入音频数
durationINT0 ~ 200 ~ longest (以最长输入为准)
1 ~ shortest (以最短输入为准)
2 ~ first (以首个输入为准)
dropout_transitionFLOATINT32_T_MAX2.0当输入流结束时,用于音量重新正规化的转换时间(以秒为单位)
weightsSTRING0“1 1”为每个输入设置权重
normalizeBOOLture or falsetrue规模的输入
  • abuffer ( 媒体数据入口 )
keyvalue typevalue 选项默认值解释
time_baseAV_OPT_TYPE_RATIONALINT32_T_MAX0时间基
sample_rateINTINT32_T_MAX0输入采样率
sample_fmtAV_OPT_TYPE_SAMPLE_FMT-1 ~ INT32_T_MAX-1输入采样格式
channel_layoutSTRING输入声道布局
channelsINTINT32_T_MXA0声道数
  • volume ( 调节媒体数据音量等参数 )
keyvalue typevalue 选项默认值解释
volumeSTRING1.0设置音量调节表达式 1.0 = 100%
precisionINT0 ~ 21选择数学精度
0 ~ fixed (select 8-bit fixed-point)
1 ~ float (select 32-bit fixed-point)
2 ~ double (select 64-bit fixed-point)
evalINT0 ~ 10specify when to evaluate expressions
0 ~ once (eval volume expression once)
1 ~ frame (eval volume expression per-frame)
replaygainINT0 ~ 30Apply replaygain side data when present
0 ~ drop (replaygain side data is dropped)
1 ~ ignore (replaygain side data is ignored)
2 ~ track (track gain is preferred)
3 ~ album (album gain is preferred)
replaygain_preampDOUBLE-15.0 ~ 15.00.0Apply replaygain pre-amplification
replaygain_noclipBOOLtrue or falsetrueApply replaygain clipping prevention

音频功能流程

  • 混音流程 :
  • AvFilterContext流程 :
abuffer
volume/*可选调节流音量*/
aMix
abuffer
aformat
abuffersink
  • 初始化AVFilter流程 :
avfilter_graph_alloc
avfilter_get_by_name
avfilter_graph_alloc_filter
avfilter_init_str
avfilter_link

  • 实例:

  • 混音:
//本实例不做任何异常判断

//核心 使用过滤器必备
AVFilterGraph * pFilterGraph = avfilter_graph_alloc();

/***************** 查找获取相应的过滤器 *****************/ 
//abuffersink - 音频出口
const AVFilter* pFilterABuffsink = avfilter_get_by_name("abuffersink");

//aformat - 对音频进行重新格式化
const AVFilter* pFilterAFormat = avfilter_get_by_name("aformat");

//amix - 将音频数据混音汇总
const AVFilter* pFilterAMix = avfilter_get_by_name("amix");

//abuffer - 音频入口
const AVFilter* pFilterABuffer = avfilter_get_by_name("abuffer");

//volume - 音频音量调整
const AVFilter* pFilterVolume = avfilter_get_by_name("volume");



/************ 根据相应过滤器创建过滤器实例 ************/ 
//abuffersink实例
AVFilterContext* pFilterCtxABuffSink = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffsink, "sink");

//aformat实例
AVFilterContext* pFilterCtxAFormat = avfilter_graph_alloc_filter(pFilterGraph, pFilterAFormat, "format");

//amix实例
AVFilterContext* pFilterCtxAMix = avfilter_graph_alloc_filter(pFilterGraph, pFilterAMix, "mix");

//abuffer - 入口0 实例
AVFilterContext* pFilterCtxABuffer_0 = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffer, "buffer0");

//abuffer - 入口1 实例
AVFilterContext* pFilterCtxABuffer_1 = avfilter_graph_alloc_filter(pFilterGraph, pFilterABuffer, "buffer1");

//volume - 控制入口0的音量 实例
AVFilterContext* pFilterCtxVolume_0 = avfilter_graph_alloc_filter(pFilterGraph, pFilterVolume, "volume0");


/****************** 参数选项设置 ********************/ 
//abuffersink - 参数设置
avfilter_init_str(pFilterCtxABuffSink, nullptr);

//aformat - 参数设置 - 采样率:44100 | 采样格式:f32 | 声道布局:双声道
avfilter_init_str(pFilterCtxAFormat, "sample_rates=44100:sample_fmts=flt:channel_layouts=0x3");

//amix - 参数设置 - 输入音频流数:2 | 持续时长:最长的音频为准 | dropout_transition:输入流结束时,容量重整时间
avfilter_init_str(pFilterCtxAMix, "inputs=2:duration=longest:dropout_transition=0");

//abuffer入口0 - 参数设置 - 采样率:44100 |  采样格式:s16 | 声道布局:双声道
avfilter_init_str(pFilterCtxABuffer_0, "sample_rate=44100:sample_fmt=s16:channel_layout=0x3");

//abuffer入口1 - 参数设置 - 采样率:48000 |  采样格式:flt | 声道布局:双声道
avfilter_init_str(pFilterCtxABuffer_1, "sample_rate=48000:sample_fmt=flt:channel_layout=0x3");

//volume 0 - 参数设置 - 音量 10%
avfilter_init_str(pFilterCtxVolume_0, "volume=0.1");


/************ 对目前个不相关的过滤器做连接 *************/ 

//abuffer入口0 -> volume0
avfilter_link(pFilterCtxABuffer_0, 0, pFilterCtxVolume_0, 0);

//volume0 -> amix 混音
avfilter_link(pFilterCtxVolume_0, 0, pFilterCtxAMix, 0);

//abuffer入口1 -> amix
avfilter_link(pFilterCtxABuffer_1, 0, pFilterCtxAMix, 1);

//amix -> aformat
avfilter_link(pFilterCtxAMix, 0, pFilterCtxAFormat, 0);

//aformat -> abuffersink
avfilter_link(pFilterCtxAFormat, 0, pFilterCtxABuffSink, 0);

//graph整合
avfilter_graph_config(pFilterGraph, nullptr);


bool bReadFileEnd_0 = false;
bool bReadFileEnd_1 = false;

AVFrame* pFrame_0 = av_frame_alloc();
AVFrame* pFrame_1 = av_frame_alloc();
AVFrame* pFrameOut = av_frame_alloc();

/******
*
*   打开文件、初始化avframe操作
*
******/



while(!bReadFileEnd_0 || !bReadFileEnd_1 )
{
    /******* 输入其一 *******/
    if(!bReadFileEnd_0)
    {
        /***
        *   读取 pcm 一帧数据
        ***/
        if(/* Read File End */) bReadFileEnd_0 = ture;
    }   

    /******* 输入其二 *******/
    if(!bReadFileEnd_1)
    {
        /***
        *   读取 pcm 一帧数据
        ***/
        if(/* Read File End */) bReadFileEnd_1 = ture;
    }
    
    
    /******* 只要其中一路还有数据就必须得传入数据 *******/
    //传入的数据流其一 - 通过abuffer0传入
    av_buffersrc_add_frame(pFilterCtxABuffer_0, bReadFileEnd_0 ? nullptr : pFrame_0);
    
    //传入的数据流其二 - 通过abuffer1传入
    av_buffersrc_add_frame(pFilterCtxABuffer_1, bReadFileEnd_1 ? nullptr : pFrame_1;


    /****** 读取混音后的数据 ******/
    while(true)
    {
        //从abuffersink中获取一帧数据
        if(av_buffersink_get_frame(pFilterCtxABuffSink, pFrameOut) < 0)
        {
            //读取失败则表示过滤器中已经不存在数据了,需要重新往里添加帧
            break;
        }
        
        /***
        *   将数据写入输出文件
        ***/
        
    }

}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值