@ -35,6 +35,7 @@
# define OFFSET(x) offsetof(TInterlaceContext, x)
# define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
# define TINTERLACE_FLAG_VLPF 01
# define TINTERLACE_FLAG_EXACT_TB 2
static const AVOption tinterlace_options [ ] = {
{ " mode " , " select interlace mode " , OFFSET ( mode ) , AV_OPT_TYPE_INT , { . i64 = MODE_MERGE } , 0 , MODE_NB - 1 , FLAGS , " mode " } ,
@ -49,6 +50,7 @@ static const AVOption tinterlace_options[] = {
{ " flags " , " set flags " , OFFSET ( flags ) , AV_OPT_TYPE_FLAGS , { . i64 = 0 } , 0 , INT_MAX , 0 , " flags " } ,
{ " low_pass_filter " , " enable vertical low-pass filter " , 0 , AV_OPT_TYPE_CONST , { . i64 = TINTERLACE_FLAG_VLPF } , INT_MIN , INT_MAX , FLAGS , " flags " } ,
{ " vlpf " , " enable vertical low-pass filter " , 0 , AV_OPT_TYPE_CONST , { . i64 = TINTERLACE_FLAG_VLPF } , INT_MIN , INT_MAX , FLAGS , " flags " } ,
{ " exact_tb " , " force a timebase which can represent timestamps exactly " , 0 , AV_OPT_TYPE_CONST , { . i64 = TINTERLACE_FLAG_EXACT_TB } , INT_MIN , INT_MAX , FLAGS , " flags " } ,
{ NULL }
} ;
@ -62,6 +64,12 @@ static const enum AVPixelFormat full_scale_yuvj_pix_fmts[] = {
FULL_SCALE_YUVJ_FORMATS , AV_PIX_FMT_NONE
} ;
static const AVRational standard_tbs [ ] = {
{ 1 , 25 } ,
{ 1 , 30 } ,
{ 1001 , 30000 } ,
} ;
static int query_formats ( AVFilterContext * ctx )
{
static const enum AVPixelFormat pix_fmts [ ] = {
@ -104,6 +112,7 @@ static int config_out_props(AVFilterLink *outlink)
AVFilterLink * inlink = outlink - > src - > inputs [ 0 ] ;
const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get ( outlink - > format ) ;
TInterlaceContext * tinterlace = ctx - > priv ;
int i ;
tinterlace - > vsub = desc - > log2_chroma_h ;
outlink - > flags | = FF_LINK_FLAG_REQUEST_LOOP ;
@ -135,13 +144,23 @@ static int config_out_props(AVFilterLink *outlink)
tinterlace - > mode ) ;
tinterlace - > flags & = ~ TINTERLACE_FLAG_VLPF ;
}
tinterlace - > preout_time_base = inlink - > time_base ;
if ( tinterlace - > mode = = MODE_INTERLACEX2 ) {
outlink - > time_base . num = inlink - > time_base . num ;
outlink - > time_base . den = inlink - > time_base . den * 2 ;
tinterlace - > preout_time_base . den * = 2 ;
outlink - > frame_rate = av_mul_q ( inlink - > frame_rate , ( AVRational ) { 2 , 1 } ) ;
outlink - > time_base = av_mul_q ( inlink - > time_base , ( AVRational ) { 1 , 2 } ) ;
} else if ( tinterlace - > mode ! = MODE_PAD ) {
outlink - > frame_rate = av_mul_q ( inlink - > frame_rate , ( AVRational ) { 1 , 2 } ) ;
outlink - > time_base = av_mul_q ( inlink - > time_base , ( AVRational ) { 2 , 1 } ) ;
}
for ( i = 0 ; i < FF_ARRAY_ELEMS ( standard_tbs ) ; i + + ) {
if ( ! av_cmp_q ( standard_tbs [ i ] , outlink - > time_base ) )
break ;
}
if ( i = = FF_ARRAY_ELEMS ( standard_tbs ) | |
( tinterlace - > flags & TINTERLACE_FLAG_EXACT_TB ) )
outlink - > time_base = tinterlace - > preout_time_base ;
if ( tinterlace - > flags & TINTERLACE_FLAG_VLPF ) {
tinterlace - > lowpass_line = lowpass_line_c ;
@ -326,6 +345,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
if ( cur - > pts ! = AV_NOPTS_VALUE )
out - > pts = cur - > pts * 2 ;
out - > pts = av_rescale_q ( out - > pts , tinterlace - > preout_time_base , outlink - > time_base ) ;
if ( ( ret = ff_filter_frame ( outlink , out ) ) < 0 )
return ret ;
@ -359,6 +379,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
av_assert0 ( 0 ) ;
}
out - > pts = av_rescale_q ( out - > pts , tinterlace - > preout_time_base , outlink - > time_base ) ;
ret = ff_filter_frame ( outlink , out ) ;
tinterlace - > frame + + ;