AVFilter - 流媒体过滤器

文章目录
**流媒体过滤器 - AVFilter**
**函数说明** :
**函数名称** : **avfilter_graph_alloc**
**功能** : 相当于合拢所有过滤器的统一上下文
**avfilter_init_str参数选项**:
**abuffersink ( 媒体数据最终出口 ) **
**aformat ( 将媒体数据进行格式化 )**
**amix ( 混音处 )**:
**abuffer ( 媒体数据入口 )**
**volume ( 调节媒体数据音量等参数 )**
**音频功能流程** :
**混音流程** :
**AvFilterContext流程** :
**初始化AVFilter流程** :
**实例**:
**混音**:
流媒体过滤器 - AVFilter

函数说明 :

  • 函数名称 : avfilter_graph_alloc

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

avfilter_init_str参数选项:

  • **abuffersink ( 媒体数据最终出口 ) **

key value type value 选项 默认值 解释
NULL NULL NULL NULL NULL
  • aformat ( 将媒体数据进行格式化 )

  • key value type value 选项 默认值 解释
    sample_fmts STRING 0 格式化后的采样格式
    sample_rates STRING 0 格式化后的采样率
    channel_layouts STRING 0 格式化后的声道布局
  • amix ( 混音处 ):

key value type value 选项 默认值 解释
inputs INT INT16_T_MAX 2 输入音频数
duration INT 0 ~ 2 0 0 ~ longest (以最长输入为准)
1 ~ shortest (以最短输入为准)
2 ~ first (以首个输入为准)
dropout_transition FLOAT INT32_T_MAX 2.0 当输入流结束时,用于音量重新正规化的转换时间(以秒为单位)
weights STRING 0 “1 1” 为每个输入设置权重
normalize BOOL ture or false true 规模的输入
  • abuffer ( 媒体数据入口 )

key value type value 选项 默认值 解释
time_base AV_OPT_TYPE_RATIONAL INT32_T_MAX 0
时间基
sample_rate INT INT32_T_MAX 0
输入采样率
sample_fmt AV_OPT_TYPE_SAMPLE_FMT -1 ~ INT32_T_MAX -1
输入采样格式
channel_layout STRING
输入声道布局
channels INT INT32_T_MXA 0
声道数
  • volume ( 调节媒体数据音量等参数 )

key value type value 选项 默认值 解释
volume STRING 1.0 设置音量调节表达式 1.0 = 100%
precision INT 0 ~ 2 1 选择数学精度
0 ~ fixed (select 8-bit fixed-point)
1 ~ float (select 32-bit fixed-point)
2 ~ double (select 64-bit fixed-point)
eval INT 0 ~ 1 0 specify when to evaluate expressions
0 ~ once (eval volume expression once)
1 ~ frame (eval volume expression per-frame)
replaygain INT 0 ~ 3 0 Apply 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_preamp DOUBLE -15.0 ~ 15.0 0.0 Apply replaygain pre-amplification
replaygain_noclip BOOL true or false true Apply replaygain clipping prevention

音频功能流程 :

  • 混音流程 :

  • AvFilterContext流程 :

  • 初始化AVFilter流程 :
  • 实例:

  • 混音:

  • //本实例不做任何异常判断
    
    //核心 使用过滤器必备
    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;
            }
            
            /***
            *   将数据写入输出文件
            ***/
            
        }
    
    }
    
    
    
    
    

猜你喜欢

转载自blog.csdn.net/qq_39436605/article/details/131723122