@ -30,11 +30,38 @@
# include "libavutil/mathematics.h"
# include "libavutil/opt.h"
# include "libavutil/parseutils.h"
# include "libavutil/pixdesc.h"
# include "avfilter.h"
# include "internal.h"
# include "video.h"
static const char * const var_names [ ] = {
" PI " ,
" PHI " ,
" E " ,
" w " ,
" h " ,
" a " , " dar " ,
" sar " ,
" hsub " ,
" vsub " ,
NULL
} ;
enum var_name {
VAR_PI ,
VAR_PHI ,
VAR_E ,
VAR_W ,
VAR_H ,
VAR_A , VAR_DAR ,
VAR_SAR ,
VAR_HSUB ,
VAR_VSUB ,
VARS_NB
} ;
typedef struct {
const AVClass * class ;
AVRational dar ;
@ -43,7 +70,7 @@ typedef struct {
# if FF_API_OLD_FILTER_OPTS
float aspect_den ;
# endif
char * ratio_st r ;
char * ratio_exp r ;
} AspectContext ;
static av_cold int init ( AVFilterContext * ctx )
@ -52,28 +79,20 @@ static av_cold int init(AVFilterContext *ctx)
int ret ;
# if FF_API_OLD_FILTER_OPTS
if ( s - > ratio_st r & & s - > aspect_den > 0 ) {
if ( s - > ratio_exp r & & s - > aspect_den > 0 ) {
double num ;
av_log ( ctx , AV_LOG_WARNING ,
" num:den syntax is deprecated, please use num/den or named options instead \n " ) ;
ret = av_expr_parse_and_eval ( & num , s - > ratio_st r , NULL , NULL ,
ret = av_expr_parse_and_eval ( & num , s - > ratio_exp r , NULL , NULL ,
NULL , NULL , NULL , NULL , NULL , 0 , ctx ) ;
if ( ret < 0 ) {
av_log ( ctx , AV_LOG_ERROR , " Unable to parse ratio numerator \" %s \" \n " , s - > ratio_st r ) ;
av_log ( ctx , AV_LOG_ERROR , " Unable to parse ratio numerator \" %s \" \n " , s - > ratio_exp r ) ;
return AVERROR ( EINVAL ) ;
}
s - > sar = s - > dar = av_d2q ( num / s - > aspect_den , s - > max ) ;
} else
# endif
if ( s - > ratio_str ) {
ret = av_parse_ratio ( & s - > sar , s - > ratio_str , s - > max , 0 , ctx ) ;
if ( ret < 0 | | s - > sar . num < 0 | | s - > sar . den < = 0 ) {
av_log ( ctx , AV_LOG_ERROR ,
" Invalid string '%s' for aspect ratio \n " , s - > ratio_str ) ;
return AVERROR ( EINVAL ) ;
}
s - > dar = s - > sar ;
}
# endif
return 0 ;
}
@ -97,6 +116,48 @@ static inline void compute_dar(AVRational *dar, AVRational sar, int w, int h)
}
}
static int get_aspect_ratio ( AVFilterLink * inlink , AVRational * aspect_ratio )
{
AVFilterContext * ctx = inlink - > dst ;
AspectContext * s = inlink - > dst - > priv ;
const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get ( inlink - > format ) ;
double var_values [ VARS_NB ] , res ;
int ret ;
var_values [ VAR_PI ] = M_PI ;
var_values [ VAR_PHI ] = M_PHI ;
var_values [ VAR_E ] = M_E ;
var_values [ VAR_W ] = inlink - > w ;
var_values [ VAR_H ] = inlink - > h ;
var_values [ VAR_A ] = ( double ) inlink - > w / inlink - > h ;
var_values [ VAR_SAR ] = inlink - > sample_aspect_ratio . num ?
( double ) inlink - > sample_aspect_ratio . num / inlink - > sample_aspect_ratio . den : 1 ;
var_values [ VAR_DAR ] = var_values [ VAR_A ] * var_values [ VAR_SAR ] ;
var_values [ VAR_HSUB ] = 1 < < desc - > log2_chroma_w ;
var_values [ VAR_VSUB ] = 1 < < desc - > log2_chroma_h ;
/* evaluate new aspect ratio*/
ret = av_expr_parse_and_eval ( & res , s - > ratio_expr ,
var_names , var_values ,
NULL , NULL , NULL , NULL , NULL , 0 , ctx ) ;
if ( ret < 0 ) {
ret = av_parse_ratio ( aspect_ratio , s - > ratio_expr , s - > max , 0 , ctx ) ;
} else
* aspect_ratio = av_d2q ( res , s - > max ) ;
if ( ret < 0 ) {
av_log ( ctx , AV_LOG_ERROR ,
" Error when evaluating the expression '%s' \n " , s - > ratio_expr ) ;
return ret ;
}
if ( aspect_ratio - > num < 0 | | aspect_ratio - > den < = 0 ) {
av_log ( ctx , AV_LOG_ERROR ,
" Invalid string '%s' for aspect ratio \n " , s - > ratio_expr ) ;
return AVERROR ( EINVAL ) ;
}
return 0 ;
}
# if CONFIG_SETDAR_FILTER
static int setdar_config_props ( AVFilterLink * inlink )
@ -105,6 +166,16 @@ static int setdar_config_props(AVFilterLink *inlink)
AVRational dar ;
AVRational old_dar ;
AVRational old_sar = inlink - > sample_aspect_ratio ;
int ret ;
# if FF_API_OLD_FILTER_OPTS
if ( ! ( s - > ratio_expr & & s - > aspect_den > 0 ) ) {
# endif
if ( ( ret = get_aspect_ratio ( inlink , & s - > dar ) ) )
return ret ;
# if FF_API_OLD_FILTER_OPTS
}
# endif
if ( s - > dar . num & & s - > dar . den ) {
av_reduce ( & s - > sar . num , & s - > sar . den ,
@ -126,9 +197,9 @@ static int setdar_config_props(AVFilterLink *inlink)
}
static const AVOption setdar_options [ ] = {
{ " dar " , " set display aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " ratio " , " set display aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " r " , " set display aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " dar " , " set display aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " ratio " , " set display aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " r " , " set display aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
# if FF_API_OLD_FILTER_OPTS
{ " dar_den " , NULL , OFFSET ( aspect_den ) , AV_OPT_TYPE_FLOAT , { . dbl = 0 } , 0 , FLT_MAX , FLAGS } ,
# endif
@ -175,6 +246,16 @@ static int setsar_config_props(AVFilterLink *inlink)
AspectContext * s = inlink - > dst - > priv ;
AVRational old_sar = inlink - > sample_aspect_ratio ;
AVRational old_dar , dar ;
int ret ;
# if FF_API_OLD_FILTER_OPTS
if ( ! ( s - > ratio_expr & & s - > aspect_den > 0 ) ) {
# endif
if ( ( ret = get_aspect_ratio ( inlink , & s - > sar ) ) )
return ret ;
# if FF_API_OLD_FILTER_OPTS
}
# endif
inlink - > sample_aspect_ratio = s - > sar ;
@ -188,9 +269,9 @@ static int setsar_config_props(AVFilterLink *inlink)
}
static const AVOption setsar_options [ ] = {
{ " sar " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " ratio " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " r " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_st r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " sar " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " ratio " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
{ " r " , " set sample (pixel) aspect ratio " , OFFSET ( ratio_exp r ) , AV_OPT_TYPE_STRING , { . str = " 0 " } , . flags = FLAGS } ,
# if FF_API_OLD_FILTER_OPTS
{ " sar_den " , NULL , OFFSET ( aspect_den ) , AV_OPT_TYPE_FLOAT , { . dbl = 0 } , 0 , FLT_MAX , FLAGS } ,
# endif