[FFmpeg-devel] [PATCH] avisynth.c corrected interlace detection

Stephen Hutchinson qyot27 at gmail.com
Thu May 27 23:38:41 EEST 2021


On 5/24/2021 11:03 AM, emcodem wrote:
> Sorry for the delay on this, should have corrected it much earlier.
> There was some confusion in the interlaced analysis. From 3rdparty decoders perspective, a clip
> can only be interlaced when it is NOT field_based. This is because in a field_based clip, the fields
> are separate images, so it is actually progressive. In that case, avisynth still shows is_tff or bff because those
> values are needed in case the script decides to weave the separated fields later on.
> 
> ---
>   libavformat/avisynth.c | 11 ++++-------
>   1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
> index 350ac6d11d..ff6e6e1bfa 100644
> --- a/libavformat/avisynth.c
> +++ b/libavformat/avisynth.c
> @@ -250,15 +250,12 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>       st->nb_frames         = avs->vi->num_frames;
>       avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
>   
> -    av_log(s, AV_LOG_TRACE, "avs_is_field_based: %d\n", avs_is_field_based(avs->vi));
> -    av_log(s, AV_LOG_TRACE, "avs_is_parity_known: %d\n", avs_is_parity_known(avs->vi));
>   
> -    /* The following typically only works when assumetff (-bff) and
> -     * assumefieldbased is used in-script. Additional
> -     * logic using GetParity() could deliver more accurate results
> -     * but also decodes a frame which we want to avoid. */
>       st->codecpar->field_order = AV_FIELD_UNKNOWN;
> -    if (avs_is_field_based(avs->vi)) {
> +    /* separatefields makes field_based==true, weave makes field_based==false
> +     * only non field_based clips can therefore be interlaced */
> +    av_log(s, AV_LOG_TRACE, "avs_is_field_based: %d\n", avs_is_field_based(avs->vi));
> +    if (avs_is_field_based(avs->vi) == 0) {
>           if (avs_is_tff(avs->vi)) {
>               st->codecpar->field_order = AV_FIELD_TT;
>           }
> 

The change seems okay, but the comment and commit message need to
explain what's going on better, because the confusion that's erupted
over this seems to derive from the rather poor way the AviSynth
documentation describes the difference between field-based and 
frame-based clips, and how to access this information through the API. 
After having read through all of this a bit more, the situation appears to
be as follows:

AviSynth works on Frame-based video.  Full stop.  'Frame-based',
despite the name, is not a synonym for 'progressive', merely that
it's being processed as a single frame rather than as a half-height
field.  This is the single point from which all the rest of this
got confused.

Using SeparateFields(), you can break the frame into its constituent
half-height fields so that certain filters which don't like processing
interlaced footage can filter the fields as a sort of 'fake
progressive', before using Weave() to combine the fields again into
a singular full height frame.  That's its intention, rather than to
signal to a client program that something is interlaced. The
AssumeFieldBased() function and avs_is_field_based API check are
there to allow other functions to understand this situation
where the fields have been broken apart (or to override the
field-based setting in cases that it didn't get set properly).

The confusion seems to have arisen from mistaking these as ways
that AviSynth indicates something is interlaced or not, and it
isn't.  For that purpose, you have to look at frame properties,
something that was introduced in AviSynth+ as a flag that a source 
plugin can set to indicate whether the frame is interlaced (either
tff or bff) or progressive.  Adding frame property detection to
the demuxer here would require larger changes that need to be
guarded from 2.6, but it would accomplish the goal I *think*
this is ultimately intended to address.

The in-code comment should probably be something closer to:

/* AviSynth works on frame-based video by default, which can
/* be either progressive or interlaced. Some filters can break
/* frames into half-height fields, at which point it considers
/* the clip to be field-based (avs_is_field_based can be used
/* to check for this situation).

/* To properly detect the field order of a typical video clip,
/* the frame needs to have been weaved back together already,
/* so avs_is_field_based should actually report 'false' when
/* checked. */


More information about the ffmpeg-devel mailing list