@ -28,7 +28,10 @@
# include "libavutil/common.h"
# include "libavutil/eval.h"
# include "libavutil/float_dsp.h"
# include "libavutil/intreadwrite.h"
# include "libavutil/opt.h"
# include "libavutil/replaygain.h"
# include "audio.h"
# include "avfilter.h"
# include "formats.h"
@ -70,7 +73,13 @@ static const AVOption volume_options[] = {
{ " eval " , " specify when to evaluate expressions " , OFFSET ( eval_mode ) , AV_OPT_TYPE_INT , { . i64 = EVAL_MODE_ONCE } , 0 , EVAL_MODE_NB - 1 , . flags = A | F , " eval " } ,
{ " once " , " eval volume expression once " , 0 , AV_OPT_TYPE_CONST , { . i64 = EVAL_MODE_ONCE } , . flags = A | F , . unit = " eval " } ,
{ " frame " , " eval volume expression per-frame " , 0 , AV_OPT_TYPE_CONST , { . i64 = EVAL_MODE_FRAME } , . flags = A | F , . unit = " eval " } ,
{ NULL }
{ " replaygain " , " Apply replaygain side data when present " ,
OFFSET ( replaygain ) , AV_OPT_TYPE_INT , { . i64 = REPLAYGAIN_DROP } , REPLAYGAIN_DROP , REPLAYGAIN_ALBUM , A , " replaygain " } ,
{ " drop " , " replaygain side data is dropped " , 0 , AV_OPT_TYPE_CONST , { . i64 = REPLAYGAIN_DROP } , 0 , 0 , A , " replaygain " } ,
{ " ignore " , " replaygain side data is ignored " , 0 , AV_OPT_TYPE_CONST , { . i64 = REPLAYGAIN_IGNORE } , 0 , 0 , A , " replaygain " } ,
{ " track " , " track gain is preferred " , 0 , AV_OPT_TYPE_CONST , { . i64 = REPLAYGAIN_TRACK } , 0 , 0 , A , " replaygain " } ,
{ " album " , " album gain is preferred " , 0 , AV_OPT_TYPE_CONST , { . i64 = REPLAYGAIN_ALBUM } , 0 , 0 , A , " replaygain " } ,
{ NULL } ,
} ;
AVFILTER_DEFINE_CLASS ( volume ) ;
@ -325,8 +334,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
int nb_samples = buf - > nb_samples ;
AVFrame * out_buf ;
int64_t pos ;
AVFrameSideData * sd = av_frame_get_side_data ( buf , AV_FRAME_DATA_REPLAYGAIN ) ;
int ret ;
if ( sd & & vol - > replaygain ! = REPLAYGAIN_IGNORE ) {
if ( vol - > replaygain ! = REPLAYGAIN_DROP ) {
AVReplayGain * replaygain = ( AVReplayGain * ) sd - > data ;
int32_t gain ;
float g ;
if ( vol - > replaygain = = REPLAYGAIN_TRACK & &
replaygain - > track_gain ! = INT32_MIN )
gain = replaygain - > track_gain ;
else if ( replaygain - > album_gain ! = INT32_MIN )
gain = replaygain - > album_gain ;
else {
av_log ( inlink - > dst , AV_LOG_WARNING , " Both ReplayGain gain "
" values are unknown. \n " ) ;
gain = 100000 ;
}
g = gain / 100000.0f ;
av_log ( inlink - > dst , AV_LOG_VERBOSE ,
" Using gain %f dB from replaygain side data. \n " , g ) ;
vol - > volume = pow ( 10 , g / 20 ) ;
vol - > volume_i = ( int ) ( vol - > volume * 256 + 0.5 ) ;
volume_init ( vol ) ;
}
av_frame_remove_side_data ( buf , AV_FRAME_DATA_REPLAYGAIN ) ;
}
if ( isnan ( vol - > var_values [ VAR_STARTPTS ] ) ) {
vol - > var_values [ VAR_STARTPTS ] = TS2D ( buf - > pts ) ;
vol - > var_values [ VAR_STARTT ] = TS2T ( buf - > pts , inlink - > time_base ) ;