2012-04-03 16:56:04 +03:00
/*
* Copyright ( C ) 2012 Michael Niedermayer < michaelni @ gmx . at >
*
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* FFmpeg is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2012-12-26 04:47:25 +03:00
# include <float.h> /* FLT_MAX */
2012-04-03 16:56:04 +03:00
# include "libavutil/common.h"
2012-12-26 04:47:25 +03:00
# include "libavutil/opt.h"
2012-06-16 12:47:46 +03:00
# include "internal.h"
2014-09-03 12:02:32 +03:00
# include "vf_idet.h"
2012-04-03 16:56:04 +03:00
2012-12-26 04:47:25 +03:00
# define OFFSET(x) offsetof(IDETContext, x)
# define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static const AVOption idet_options [ ] = {
2013-02-21 03:54:04 +03:00
{ " intl_thres " , " set interlacing threshold " , OFFSET ( interlace_threshold ) , AV_OPT_TYPE_FLOAT , { . dbl = 1.04 } , - 1 , FLT_MAX , FLAGS } ,
{ " prog_thres " , " set progressive threshold " , OFFSET ( progressive_threshold ) , AV_OPT_TYPE_FLOAT , { . dbl = 1.5 } , - 1 , FLT_MAX , FLAGS } ,
2014-11-02 14:49:34 +02:00
{ " rep_thres " , " set repeat threshold " , OFFSET ( repeat_threshold ) , AV_OPT_TYPE_FLOAT , { . dbl = 3.0 } , - 1 , FLT_MAX , FLAGS } ,
2014-11-03 07:30:51 +02:00
{ " half_life " , " half life of cumulative statistics " , OFFSET ( half_life ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.0 } , - 1 , INT_MAX , FLAGS } ,
2015-01-01 03:35:39 +02:00
{ " analyze_interlaced_flag " , " set number of frames to use to determine if the interlace flag is accurate " , OFFSET ( analyze_interlaced_flag ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , INT_MAX , FLAGS } ,
2012-12-26 04:47:25 +03:00
{ NULL }
} ;
AVFILTER_DEFINE_CLASS ( idet ) ;
2012-04-05 07:38:48 +03:00
static const char * type2str ( Type type )
{
switch ( type ) {
2014-11-01 13:10:15 +02:00
case TFF : return " tff " ;
case BFF : return " bff " ;
case PROGRESSIVE : return " progressive " ;
case UNDETERMINED : return " undetermined " ;
2012-04-05 07:38:48 +03:00
}
return NULL ;
}
2012-04-03 16:56:04 +03:00
2014-11-03 07:30:51 +02:00
# define PRECISION 1048576
static uint64_t uintpow ( uint64_t b , unsigned int e )
{
uint64_t r = 1 ;
while ( e - - ) r * = b ;
return r ;
}
static int av_dict_set_fxp ( AVDictionary * * pm , const char * key , uint64_t value , unsigned int digits ,
int flags )
{
char valuestr [ 44 ] ;
2014-11-03 18:14:29 +02:00
uint64_t print_precision = uintpow ( 10 , digits ) ;
value = av_rescale ( value , print_precision , PRECISION ) ;
2014-11-03 07:30:51 +02:00
snprintf ( valuestr , sizeof ( valuestr ) , " % " PRId64 " .%0* " PRId64 ,
2014-11-03 18:14:29 +02:00
value / print_precision , digits , value % print_precision ) ;
2014-11-03 07:30:51 +02:00
return av_dict_set ( pm , key , valuestr , flags ) ;
}
2014-11-02 14:49:34 +02:00
static const char * rep2str ( RepeatedField repeated_field )
{
switch ( repeated_field ) {
case REPEAT_NONE : return " neither " ;
case REPEAT_TOP : return " top " ;
case REPEAT_BOTTOM : return " bottom " ;
}
return NULL ;
}
2014-09-03 12:02:32 +03:00
int ff_idet_filter_line_c ( const uint8_t * a , const uint8_t * b , const uint8_t * c , int w )
2012-04-03 16:56:04 +03:00
{
int x ;
int ret = 0 ;
for ( x = 0 ; x < w ; x + + ) {
2013-02-21 03:49:56 +03:00
int v = ( * a + + + * c + + ) - 2 * * b + + ;
ret + = FFABS ( v ) ;
2012-04-03 16:56:04 +03:00
}
return ret ;
}
2014-09-09 15:38:58 +03:00
int ff_idet_filter_line_c_16bit ( const uint16_t * a , const uint16_t * b , const uint16_t * c , int w )
2012-04-03 16:56:04 +03:00
{
int x ;
int ret = 0 ;
for ( x = 0 ; x < w ; x + + ) {
2013-02-21 03:49:56 +03:00
int v = ( * a + + + * c + + ) - 2 * * b + + ;
ret + = FFABS ( v ) ;
2012-04-03 16:56:04 +03:00
}
return ret ;
}
static void filter ( AVFilterContext * ctx )
{
IDETContext * idet = ctx - > priv ;
int y , i ;
int64_t alpha [ 2 ] = { 0 } ;
int64_t delta = 0 ;
2014-11-02 14:49:34 +02:00
int64_t gamma [ 2 ] = { 0 } ;
2012-04-05 09:26:09 +03:00
Type type , best_type ;
2014-11-02 14:49:34 +02:00
RepeatedField repeat ;
2012-04-05 09:26:09 +03:00
int match = 0 ;
2017-04-22 10:57:18 +02:00
AVDictionary * * metadata = & idet - > cur - > metadata ;
2012-04-03 16:56:04 +03:00
for ( i = 0 ; i < idet - > csp - > nb_components ; i + + ) {
2013-03-10 03:30:30 +03:00
int w = idet - > cur - > width ;
int h = idet - > cur - > height ;
2012-04-03 16:56:04 +03:00
int refs = idet - > cur - > linesize [ i ] ;
if ( i & & i < 3 ) {
2016-01-27 17:19:38 +02:00
w = AV_CEIL_RSHIFT ( w , idet - > csp - > log2_chroma_w ) ;
h = AV_CEIL_RSHIFT ( h , idet - > csp - > log2_chroma_h ) ;
2012-04-03 16:56:04 +03:00
}
for ( y = 2 ; y < h - 2 ; y + + ) {
uint8_t * prev = & idet - > prev - > data [ i ] [ y * refs ] ;
uint8_t * cur = & idet - > cur - > data [ i ] [ y * refs ] ;
uint8_t * next = & idet - > next - > data [ i ] [ y * refs ] ;
alpha [ y & 1 ] + = idet - > filter_line ( cur - refs , prev , cur + refs , w ) ;
alpha [ ( y ^ 1 ) & 1 ] + = idet - > filter_line ( cur - refs , next , cur + refs , w ) ;
delta + = idet - > filter_line ( cur - refs , cur , cur + refs , w ) ;
2014-11-02 14:49:34 +02:00
gamma [ ( y ^ 1 ) & 1 ] + = idet - > filter_line ( cur , prev , cur , w ) ;
2012-04-03 16:56:04 +03:00
}
}
2012-10-19 20:35:31 +03:00
if ( alpha [ 0 ] > idet - > interlace_threshold * alpha [ 1 ] ) {
2012-04-05 07:23:53 +03:00
type = TFF ;
2012-10-19 20:35:31 +03:00
} else if ( alpha [ 1 ] > idet - > interlace_threshold * alpha [ 0 ] ) {
2012-04-05 07:23:53 +03:00
type = BFF ;
2012-10-19 20:35:31 +03:00
} else if ( alpha [ 1 ] > idet - > progressive_threshold * delta ) {
2014-09-19 15:52:55 +03:00
type = PROGRESSIVE ;
2012-04-05 07:23:53 +03:00
} else {
type = UNDETERMINED ;
}
2014-11-02 14:49:34 +02:00
if ( gamma [ 0 ] > idet - > repeat_threshold * gamma [ 1 ] ) {
repeat = REPEAT_TOP ;
} else if ( gamma [ 1 ] > idet - > repeat_threshold * gamma [ 0 ] ) {
repeat = REPEAT_BOTTOM ;
} else {
repeat = REPEAT_NONE ;
}
2012-04-05 09:26:09 +03:00
memmove ( idet - > history + 1 , idet - > history , HIST_SIZE - 1 ) ;
idet - > history [ 0 ] = type ;
best_type = UNDETERMINED ;
for ( i = 0 ; i < HIST_SIZE ; i + + ) {
if ( idet - > history [ i ] ! = UNDETERMINED ) {
if ( best_type = = UNDETERMINED )
best_type = idet - > history [ i ] ;
if ( idet - > history [ i ] = = best_type ) {
match + + ;
} else {
match = 0 ;
break ;
}
}
}
if ( idet - > last_type = = UNDETERMINED ) {
if ( match ) idet - > last_type = best_type ;
} else {
if ( match > 2 ) idet - > last_type = best_type ;
}
2012-04-05 07:33:40 +03:00
if ( idet - > last_type = = TFF ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2013-03-10 03:30:30 +03:00
idet - > cur - > top_field_first = 1 ;
idet - > cur - > interlaced_frame = 1 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
idet - > cur - > flags | = ( AV_FRAME_FLAG_INTERLACED | AV_FRAME_FLAG_TOP_FIELD_FIRST ) ;
2012-04-05 07:33:40 +03:00
} else if ( idet - > last_type = = BFF ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2013-03-10 03:30:30 +03:00
idet - > cur - > top_field_first = 0 ;
idet - > cur - > interlaced_frame = 1 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
idet - > cur - > flags & = ~ AV_FRAME_FLAG_TOP_FIELD_FIRST ;
idet - > cur - > flags | = AV_FRAME_FLAG_INTERLACED ;
2014-09-19 15:52:55 +03:00
} else if ( idet - > last_type = = PROGRESSIVE ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2013-03-10 03:30:30 +03:00
idet - > cur - > interlaced_frame = 0 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
idet - > cur - > flags & = ~ AV_FRAME_FLAG_INTERLACED ;
2012-04-03 16:56:04 +03:00
}
2012-04-05 07:38:48 +03:00
2014-11-02 14:49:34 +02:00
for ( i = 0 ; i < 3 ; i + + )
idet - > repeats [ i ] = av_rescale ( idet - > repeats [ i ] , idet - > decay_coefficient , PRECISION ) ;
2014-11-03 07:30:51 +02:00
for ( i = 0 ; i < 4 ; i + + ) {
2014-11-03 18:22:16 +02:00
idet - > prestat [ i ] = av_rescale ( idet - > prestat [ i ] , idet - > decay_coefficient , PRECISION ) ;
idet - > poststat [ i ] = av_rescale ( idet - > poststat [ i ] , idet - > decay_coefficient , PRECISION ) ;
2014-11-03 07:30:51 +02:00
}
2014-11-02 14:49:34 +02:00
idet - > total_repeats [ repeat ] + + ;
idet - > repeats [ repeat ] + = PRECISION ;
2014-11-03 07:30:51 +02:00
idet - > total_prestat [ type ] + + ;
idet - > prestat [ type ] + = PRECISION ;
idet - > total_poststat [ idet - > last_type ] + + ;
idet - > poststat [ idet - > last_type ] + = PRECISION ;
2014-11-01 13:10:15 +02:00
2014-11-02 14:49:34 +02:00
av_log ( ctx , AV_LOG_DEBUG , " Repeated Field:%12s, Single frame:%12s, Multi frame:%12s \n " ,
rep2str ( repeat ) , type2str ( type ) , type2str ( idet - > last_type ) ) ;
av_dict_set ( metadata , " lavfi.idet.repeated.current_frame " , rep2str ( repeat ) , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.repeated.neither " , idet - > repeats [ REPEAT_NONE ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.repeated.top " , idet - > repeats [ REPEAT_TOP ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.repeated.bottom " , idet - > repeats [ REPEAT_BOTTOM ] , 2 , 0 ) ;
2014-11-01 13:10:15 +02:00
2014-11-03 07:30:51 +02:00
av_dict_set ( metadata , " lavfi.idet.single.current_frame " , type2str ( type ) , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.single.tff " , idet - > prestat [ TFF ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.single.bff " , idet - > prestat [ BFF ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.single.progressive " , idet - > prestat [ PROGRESSIVE ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.single.undetermined " , idet - > prestat [ UNDETERMINED ] , 2 , 0 ) ;
2014-11-01 13:10:15 +02:00
2014-11-01 13:10:15 +02:00
av_dict_set ( metadata , " lavfi.idet.multiple.current_frame " , type2str ( idet - > last_type ) , 0 ) ;
2014-11-03 07:30:51 +02:00
av_dict_set_fxp ( metadata , " lavfi.idet.multiple.tff " , idet - > poststat [ TFF ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.multiple.bff " , idet - > poststat [ BFF ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.multiple.progressive " , idet - > poststat [ PROGRESSIVE ] , 2 , 0 ) ;
av_dict_set_fxp ( metadata , " lavfi.idet.multiple.undetermined " , idet - > poststat [ UNDETERMINED ] , 2 , 0 ) ;
2012-04-03 16:56:04 +03:00
}
2013-03-10 03:30:30 +03:00
static int filter_frame ( AVFilterLink * link , AVFrame * picref )
2012-04-03 16:56:04 +03:00
{
AVFilterContext * ctx = link - > dst ;
IDETContext * idet = ctx - > priv ;
2015-01-01 03:35:39 +02:00
// initial frame(s) and not interlaced, just pass through for
// the analyze_interlaced_flag mode
if ( idet - > analyze_interlaced_flag & &
2023-04-12 16:38:46 +02:00
! ( picref - > flags & AV_FRAME_FLAG_INTERLACED ) & &
2015-01-01 03:35:39 +02:00
! idet - > next ) {
return ff_filter_frame ( ctx - > outputs [ 0 ] , picref ) ;
}
if ( idet - > analyze_interlaced_flag_done ) {
2023-04-12 16:38:46 +02:00
if ( ( picref - > flags & AV_FRAME_FLAG_INTERLACED ) & & idet - > interlaced_flag_accuracy < 0 ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2015-01-01 03:35:39 +02:00
picref - > interlaced_frame = 0 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
picref - > flags & = ~ AV_FRAME_FLAG_INTERLACED ;
}
2015-01-01 03:35:39 +02:00
return ff_filter_frame ( ctx - > outputs [ 0 ] , picref ) ;
}
2015-01-19 21:24:03 +02:00
av_frame_free ( & idet - > prev ) ;
2015-01-19 06:36:27 +02:00
if ( picref - > width ! = link - > w
| | picref - > height ! = link - > h
| | picref - > format ! = link - > format ) {
link - > dst - > inputs [ 0 ] - > format = picref - > format ;
link - > dst - > inputs [ 0 ] - > w = picref - > width ;
link - > dst - > inputs [ 0 ] - > h = picref - > height ;
av_frame_free ( & idet - > cur ) ;
av_frame_free ( & idet - > next ) ;
}
2012-04-03 16:56:04 +03:00
idet - > prev = idet - > cur ;
idet - > cur = idet - > next ;
idet - > next = picref ;
2014-11-28 23:41:02 +02:00
if ( ! idet - > cur & &
! ( idet - > cur = av_frame_clone ( idet - > next ) ) )
return AVERROR ( ENOMEM ) ;
2012-04-03 16:56:04 +03:00
if ( ! idet - > prev )
2014-11-28 23:41:02 +02:00
return 0 ;
2012-04-03 16:56:04 +03:00
if ( ! idet - > csp )
2012-10-20 07:43:48 +03:00
idet - > csp = av_pix_fmt_desc_get ( link - > format ) ;
2015-09-08 17:10:48 +02:00
if ( idet - > csp - > comp [ 0 ] . depth > 8 ) {
2014-09-09 15:38:58 +03:00
idet - > filter_line = ( ff_idet_filter_func ) ff_idet_filter_line_c_16bit ;
2022-06-12 05:51:12 +02:00
# if ARCH_X86
ff_idet_init_x86 ( idet , 1 ) ;
# endif
2014-09-09 15:38:58 +03:00
}
2012-04-03 16:56:04 +03:00
2015-01-01 03:35:39 +02:00
if ( idet - > analyze_interlaced_flag ) {
2023-04-12 16:38:46 +02:00
if ( idet - > cur - > flags & AV_FRAME_FLAG_INTERLACED ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2015-01-01 03:35:39 +02:00
idet - > cur - > interlaced_frame = 0 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
idet - > cur - > flags & = ~ AV_FRAME_FLAG_INTERLACED ;
2015-01-01 03:35:39 +02:00
filter ( ctx ) ;
if ( idet - > last_type = = PROGRESSIVE ) {
idet - > interlaced_flag_accuracy - - ;
idet - > analyze_interlaced_flag - - ;
} else if ( idet - > last_type ! = UNDETERMINED ) {
idet - > interlaced_flag_accuracy + + ;
idet - > analyze_interlaced_flag - - ;
}
if ( idet - > analyze_interlaced_flag = = 1 ) {
ff_filter_frame ( ctx - > outputs [ 0 ] , av_frame_clone ( idet - > cur ) ) ;
2023-04-12 16:38:46 +02:00
if ( ( idet - > next - > flags & AV_FRAME_FLAG_INTERLACED ) & & idet - > interlaced_flag_accuracy < 0 ) {
2023-04-12 19:18:50 +02:00
# if FF_API_INTERLACED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
2015-01-01 03:35:39 +02:00
idet - > next - > interlaced_frame = 0 ;
2023-04-12 19:18:50 +02:00
FF_ENABLE_DEPRECATION_WARNINGS
# endif
2023-04-12 16:38:46 +02:00
idet - > next - > flags & = ~ AV_FRAME_FLAG_INTERLACED ;
}
2015-01-01 03:35:39 +02:00
idet - > analyze_interlaced_flag_done = 1 ;
av_log ( ctx , AV_LOG_INFO , " Final flag accuracy %d \n " , idet - > interlaced_flag_accuracy ) ;
return ff_filter_frame ( ctx - > outputs [ 0 ] , av_frame_clone ( idet - > next ) ) ;
}
}
} else {
filter ( ctx ) ;
}
2012-04-03 16:56:04 +03:00
2013-03-10 03:30:30 +03:00
return ff_filter_frame ( ctx - > outputs [ 0 ] , av_frame_clone ( idet - > cur ) ) ;
2012-04-03 16:56:04 +03:00
}
2014-10-22 09:40:06 +03:00
static int request_frame ( AVFilterLink * link )
{
AVFilterContext * ctx = link - > src ;
IDETContext * idet = ctx - > priv ;
2015-08-26 12:21:27 +02:00
int ret ;
2014-10-22 09:40:06 +03:00
2015-08-26 12:21:27 +02:00
if ( idet - > eof )
return AVERROR_EOF ;
2014-10-22 09:40:06 +03:00
2015-08-26 12:21:27 +02:00
ret = ff_request_frame ( link - > src - > inputs [ 0 ] ) ;
2014-10-22 09:40:06 +03:00
2015-08-26 12:21:27 +02:00
if ( ret = = AVERROR_EOF & & idet - > cur & & ! idet - > analyze_interlaced_flag_done ) {
AVFrame * next = av_frame_clone ( idet - > next ) ;
2014-10-22 09:40:06 +03:00
2015-08-26 12:21:27 +02:00
if ( ! next )
return AVERROR ( ENOMEM ) ;
2014-10-22 09:40:06 +03:00
2015-08-26 12:21:27 +02:00
ret = filter_frame ( link - > src - > inputs [ 0 ] , next ) ;
idet - > eof = 1 ;
}
2014-10-22 09:40:06 +03:00
2015-08-25 20:31:50 +02:00
return ret ;
2014-10-22 09:40:06 +03:00
}
2012-04-03 16:56:04 +03:00
static av_cold void uninit ( AVFilterContext * ctx )
{
IDETContext * idet = ctx - > priv ;
2021-10-07 12:53:49 +02:00
av_log ( ctx , AV_LOG_INFO , " Repeated Fields: Neither:%6 " PRId64 " Top:%6 " PRId64 " Bottom:%6 " PRId64 " \n " ,
2014-11-02 14:49:34 +02:00
idet - > total_repeats [ REPEAT_NONE ] ,
idet - > total_repeats [ REPEAT_TOP ] ,
idet - > total_repeats [ REPEAT_BOTTOM ]
) ;
2021-10-07 12:53:49 +02:00
av_log ( ctx , AV_LOG_INFO , " Single frame detection: TFF:%6 " PRId64 " BFF:%6 " PRId64 " Progressive:%6 " PRId64 " Undetermined:%6 " PRId64 " \n " ,
2014-11-03 07:30:51 +02:00
idet - > total_prestat [ TFF ] ,
idet - > total_prestat [ BFF ] ,
idet - > total_prestat [ PROGRESSIVE ] ,
idet - > total_prestat [ UNDETERMINED ]
) ;
2021-10-07 12:53:49 +02:00
av_log ( ctx , AV_LOG_INFO , " Multi frame detection: TFF:%6 " PRId64 " BFF:%6 " PRId64 " Progressive:%6 " PRId64 " Undetermined:%6 " PRId64 " \n " ,
2014-11-03 07:30:51 +02:00
idet - > total_poststat [ TFF ] ,
idet - > total_poststat [ BFF ] ,
idet - > total_poststat [ PROGRESSIVE ] ,
idet - > total_poststat [ UNDETERMINED ]
) ;
2012-04-04 17:31:31 +03:00
2013-03-10 03:30:30 +03:00
av_frame_free ( & idet - > prev ) ;
av_frame_free ( & idet - > cur ) ;
av_frame_free ( & idet - > next ) ;
2012-04-03 16:56:04 +03:00
}
2021-09-29 15:57:43 +02:00
static const enum AVPixelFormat pix_fmts [ ] = {
AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_YUV422P ,
AV_PIX_FMT_YUV444P ,
AV_PIX_FMT_YUV410P ,
AV_PIX_FMT_YUV411P ,
AV_PIX_FMT_GRAY8 ,
AV_PIX_FMT_YUVJ420P ,
AV_PIX_FMT_YUVJ422P ,
AV_PIX_FMT_YUVJ444P ,
AV_PIX_FMT_GRAY16 ,
AV_PIX_FMT_YUV440P ,
AV_PIX_FMT_YUVJ440P ,
AV_PIX_FMT_YUV420P9 ,
AV_PIX_FMT_YUV422P9 ,
AV_PIX_FMT_YUV444P9 ,
AV_PIX_FMT_YUV420P10 ,
AV_PIX_FMT_YUV422P10 ,
AV_PIX_FMT_YUV444P10 ,
AV_PIX_FMT_YUV420P12 ,
AV_PIX_FMT_YUV422P12 ,
AV_PIX_FMT_YUV444P12 ,
AV_PIX_FMT_YUV420P14 ,
AV_PIX_FMT_YUV422P14 ,
AV_PIX_FMT_YUV444P14 ,
AV_PIX_FMT_YUV420P16 ,
AV_PIX_FMT_YUV422P16 ,
AV_PIX_FMT_YUV444P16 ,
AV_PIX_FMT_YUVA420P ,
AV_PIX_FMT_YUVA422P ,
AV_PIX_FMT_YUVA444P ,
AV_PIX_FMT_NONE
} ;
2012-04-03 16:56:04 +03:00
2013-04-12 12:13:33 +03:00
static av_cold int init ( AVFilterContext * ctx )
2012-04-03 16:56:04 +03:00
{
IDETContext * idet = ctx - > priv ;
2014-10-22 09:40:06 +03:00
idet - > eof = 0 ;
2012-04-05 07:33:40 +03:00
idet - > last_type = UNDETERMINED ;
2012-04-05 09:26:09 +03:00
memset ( idet - > history , UNDETERMINED , HIST_SIZE ) ;
2012-04-05 07:33:40 +03:00
2014-11-03 07:30:51 +02:00
if ( idet - > half_life > 0 )
2015-12-16 20:03:59 +02:00
idet - > decay_coefficient = lrint ( PRECISION * exp2 ( - 1.0 / idet - > half_life ) ) ;
2014-11-03 07:30:51 +02:00
else
idet - > decay_coefficient = PRECISION ;
2014-09-03 12:02:32 +03:00
idet - > filter_line = ff_idet_filter_line_c ;
2022-06-12 05:51:12 +02:00
# if ARCH_X86
ff_idet_init_x86 ( idet , 0 ) ;
# endif
2012-04-03 16:56:04 +03:00
return 0 ;
}
2012-11-28 22:01:59 +03:00
static const AVFilterPad idet_inputs [ ] = {
{
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
2012-12-06 23:09:17 +03:00
. filter_frame = filter_frame ,
2012-11-28 22:01:59 +03:00
} ,
} ;
static const AVFilterPad idet_outputs [ ] = {
{
2013-09-07 15:13:50 +03:00
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
2014-10-22 09:40:06 +03:00
. request_frame = request_frame
2012-11-28 22:01:59 +03:00
} ,
} ;
2021-04-19 18:33:56 +02:00
const AVFilter ff_vf_idet = {
2012-04-03 16:56:04 +03:00
. name = " idet " ,
. description = NULL_IF_CONFIG_SMALL ( " Interlace detect Filter. " ) ,
. priv_size = sizeof ( IDETContext ) ,
. init = init ,
. uninit = uninit ,
2021-11-22 15:39:11 +02:00
. flags = AVFILTER_FLAG_METADATA_ONLY ,
2021-08-12 13:05:31 +02:00
FILTER_INPUTS ( idet_inputs ) ,
FILTER_OUTPUTS ( idet_outputs ) ,
2021-09-27 21:44:13 +02:00
FILTER_PIXFMTS_ARRAY ( pix_fmts ) ,
2012-12-26 04:47:25 +03:00
. priv_class = & idet_class ,
2012-04-03 16:56:04 +03:00
} ;