@ -77,6 +77,18 @@ static int query_formats(AVFilterContext *ctx)
return 0 ;
}
static void lowpass_line_c ( uint8_t * dstp , ptrdiff_t width , const uint8_t * srcp ,
const uint8_t * srcp_above , const uint8_t * srcp_below )
{
int i ;
for ( i = 0 ; i < width ; i + + ) {
// this calculation is an integer representation of
// '0.5 * current + 0.25 * above + 0.25 * below'
// '1 +' is for rounding.
dstp [ i ] = ( 1 + srcp [ i ] + srcp [ i ] + srcp_above [ i ] + srcp_below [ i ] ) > > 2 ;
}
}
static av_cold void uninit ( AVFilterContext * ctx )
{
TInterlaceContext * tinterlace = ctx - > priv ;
@ -131,6 +143,10 @@ static int config_out_props(AVFilterLink *outlink)
outlink - > frame_rate = av_mul_q ( inlink - > frame_rate , ( AVRational ) { 1 , 2 } ) ;
}
if ( tinterlace - > flags & TINTERLACE_FLAG_VLPF ) {
tinterlace - > lowpass_line = lowpass_line_c ;
}
av_log ( ctx , AV_LOG_VERBOSE , " mode:%d filter:%s h:%d -> h:%d \n " ,
tinterlace - > mode , ( tinterlace - > flags & TINTERLACE_FLAG_VLPF ) ? " on " : " off " ,
inlink - > h , outlink - > h ) ;
@ -152,7 +168,8 @@ static int config_out_props(AVFilterLink *outlink)
* @ param flags context flags
*/
static inline
void copy_picture_field ( uint8_t * dst [ 4 ] , int dst_linesize [ 4 ] ,
void copy_picture_field ( TInterlaceContext * tinterlace ,
uint8_t * dst [ 4 ] , int dst_linesize [ 4 ] ,
const uint8_t * src [ 4 ] , int src_linesize [ 4 ] ,
enum AVPixelFormat format , int w , int src_h ,
int src_field , int interleave , int dst_field ,
@ -189,12 +206,8 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
const uint8_t * srcp_below = srcp + src_linesize [ plane ] ;
if ( h = = lines ) srcp_above = srcp ; // there is no line above
if ( h = = 1 ) srcp_below = srcp ; // there is no line below
for ( i = 0 ; i < cols ; i + + ) {
// this calculation is an integer representation of
// '0.5 * current + 0.25 * above + 0.25 * below'
// '1 +' is for rounding. */
dstp [ i ] = ( 1 + srcp [ i ] + srcp [ i ] + srcp_above [ i ] + srcp_below [ i ] ) > > 2 ;
}
tinterlace - > lowpass_line ( dstp , cols , srcp , srcp_above , srcp_below ) ;
dstp + = dstp_linesize ;
srcp + = srcp_linesize ;
}
@ -235,12 +248,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
out - > top_field_first = 1 ;
/* write odd frame lines into the upper field of the new frame */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) cur - > data , cur - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
FIELD_UPPER_AND_LOWER , 1 , FIELD_UPPER , tinterlace - > flags ) ;
/* write even frame lines into the lower field of the new frame */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) next - > data , next - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
FIELD_UPPER_AND_LOWER , 1 , FIELD_LOWER , tinterlace - > flags ) ;
@ -265,12 +278,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
field = ( 1 + tinterlace - > frame ) & 1 ? FIELD_UPPER : FIELD_LOWER ;
/* copy upper and lower fields */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) cur - > data , cur - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
FIELD_UPPER_AND_LOWER , 1 , field , tinterlace - > flags ) ;
/* pad with black the other field */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) tinterlace - > black_data , tinterlace - > black_linesize ,
inlink - > format , inlink - > w , inlink - > h ,
FIELD_UPPER_AND_LOWER , 1 , ! field , tinterlace - > flags ) ;
@ -289,13 +302,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
out - > top_field_first = tff ;
/* copy upper/lower field from cur */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) cur - > data , cur - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
tff ? FIELD_UPPER : FIELD_LOWER , 1 , tff ? FIELD_UPPER : FIELD_LOWER ,
tinterlace - > flags ) ;
/* copy lower/upper field from next */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) next - > data , next - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
tff ? FIELD_LOWER : FIELD_UPPER , 1 , tff ? FIELD_LOWER : FIELD_UPPER ,
@ -328,13 +341,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
else
out - > pts = AV_NOPTS_VALUE ;
/* write current frame second field lines into the second field of the new frame */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) cur - > data , cur - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
tff ? FIELD_LOWER : FIELD_UPPER , 1 , tff ? FIELD_LOWER : FIELD_UPPER ,
tinterlace - > flags ) ;
/* write next frame first field lines into the first field of the new frame */
copy_picture_field ( out - > data , out - > linesize ,
copy_picture_field ( tinterlace , out - > data , out - > linesize ,
( const uint8_t * * ) next - > data , next - > linesize ,
inlink - > format , inlink - > w , inlink - > h ,
tff ? FIELD_UPPER : FIELD_LOWER , 1 , tff ? FIELD_UPPER : FIELD_LOWER ,