diff mbox series

[FFmpeg-devel,2/3] avisynth: use AviSynth+'s frame properties to set various fields

Message ID 20220208110240.4179-3-qyot27@gmail.com
State Accepted
Commit af69e4c24120ad03f9838a6f7fd39a86d775ccb2
Headers show
Series avformat/avisynth: support frame properties | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Stephen Hutchinson Feb. 8, 2022, 11:02 a.m. UTC
* Field Order
* Chroma Location
* Color Transfer Characteristics
* Color Range
* Color Primaries
* Matrix Coefficients

The existing TFF/BFF detection is retained as a fallback for
older versions of AviSynth that can't access frame properties.
The other properties have no legacy equivalent to detect them.

Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
---
 libavformat/avisynth.c | 263 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 250 insertions(+), 13 deletions(-)

Comments

Stephen Hutchinson Feb. 13, 2022, 11:34 p.m. UTC | #1
On 2/8/22 6:02 AM, Stephen Hutchinson wrote:
> * Field Order
> * Chroma Location
> * Color Transfer Characteristics
> * Color Range
> * Color Primaries
> * Matrix Coefficients
> 
> The existing TFF/BFF detection is retained as a fallback for
> older versions of AviSynth that can't access frame properties.
> The other properties have no legacy equivalent to detect them.
> 
> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
> ---
>   libavformat/avisynth.c | 263 +++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 250 insertions(+), 13 deletions(-)
> 
> diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
> index 1e862a6a85..8bc39869a3 100644
> --- a/libavformat/avisynth.c
> +++ b/libavformat/avisynth.c
> @@ -19,6 +19,8 @@
>    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>    */
>   
> +#include <stdbool.h>
> +
>   #include "libavutil/attributes.h"
>   #include "libavutil/internal.h"
>   
> @@ -76,6 +78,9 @@ typedef struct AviSynthLibrary {
>       AVSC_DECLARE_FUNC(avs_get_row_size_p);
>       AVSC_DECLARE_FUNC(avs_is_planar_rgb);
>       AVSC_DECLARE_FUNC(avs_is_planar_rgba);
> +    AVSC_DECLARE_FUNC(avs_get_frame_props_ro);
> +    AVSC_DECLARE_FUNC(avs_prop_get_int);
> +    AVSC_DECLARE_FUNC(avs_get_env_property);
>   #undef AVSC_DECLARE_FUNC
>   } AviSynthLibrary;
>   
> @@ -153,6 +158,9 @@ static av_cold int avisynth_load_library(void)
>       LOAD_AVS_FUNC(avs_get_row_size_p, 1);
>       LOAD_AVS_FUNC(avs_is_planar_rgb, 1);
>       LOAD_AVS_FUNC(avs_is_planar_rgba, 1);
> +    LOAD_AVS_FUNC(avs_get_frame_props_ro, 1);
> +    LOAD_AVS_FUNC(avs_prop_get_int, 1);
> +    LOAD_AVS_FUNC(avs_get_env_property, 1);
>   #undef LOAD_AVS_FUNC
>   
>       atexit(avisynth_atexit_handler);
> @@ -236,6 +244,10 @@ static av_cold void avisynth_atexit_handler(void)
>   static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>   {
>       AviSynthContext *avs = s->priv_data;
> +    const AVS_Map *avsmap;
> +    AVS_VideoFrame *frame;
> +    int framedata, error;
> +    bool frameprop;
>       int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
>   
>       st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> @@ -251,19 +263,6 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>       avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
>   
>   
> -    st->codecpar->field_order = AV_FIELD_UNKNOWN;
> -    /* AviSynth works with frame-based video, detecting field order can
> -     * only work when avs_is_field_based returns 'false'. */
> -    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;
> -        }
> -        else if (avs_is_bff(avs->vi)) {
> -            st->codecpar->field_order = AV_FIELD_BB;
> -        }
> -    }
> -
>       switch (avs->vi->pixel_type) {
>       /* 10~16-bit YUV pix_fmts (AviSynth+) */
>       case AVS_CS_YUV444P10:
> @@ -499,6 +498,244 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>           avs->n_planes = 1;
>           avs->planes   = avs_planes_packed;
>       }
> +
> +    /* Read AviSynth+'s frame properties to set additional info.
> +     *
> +     * Due to a bug preventing the C interface from accessing frame
> +     * properties in earlier versions of interface version 8, only
> +     * enable this if we detect version 8.1 at the minimum. */
> +
> +    if (!avs_library.avs_get_env_property) {
> +        av_log(s, AV_LOG_TRACE, "%s\n",
> +               "avs_get_env_property does not exist in AviSynth library; frame properties won't be checked.");
> +        frameprop = false;
> +    } else {
> +        if (avs_library.avs_get_env_property(avs->env, AVS_AEP_INTERFACE_BUGFIX)) {
> +            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.1 or higher, reading frame properties.");
> +            frameprop = true;
> +        } else {
> +            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.0, need 8.1+ to read frame properties.");
> +            frameprop = false;
> +        }
> +    }
> +
> +    if (frameprop = true) {
> +
> +        frame  = avs_library.avs_get_frame(avs->clip, framedata);
> +        avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
> +
> +        /* Field order */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_FieldBased", 0, &error)) {
> +        case 0:
> +            st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
> +            break;
> +        case 1:
> +            st->codecpar->field_order = AV_FIELD_BB;
> +            break;
> +        case 2:
> +            st->codecpar->field_order = AV_FIELD_TT;
> +            break;
> +        default:
> +            st->codecpar->field_order = AV_FIELD_UNKNOWN;
> +        }
> +
> +        /* Color Range */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ColorRange", 0, &error)) {
> +        case 0:
> +            st->codecpar->color_range = AVCOL_RANGE_JPEG;
> +            break;
> +        case 1:
> +            st->codecpar->color_range = AVCOL_RANGE_MPEG;
> +            break;
> +        default:
> +            st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
> +        }
> +
> +        /* Color Primaries */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 0, &error)) {
> +        case 1:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT470M;
> +            break;
> +        case 5:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
> +            break;
> +        case 6:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_primaries = AVCOL_PRI_FILM;
> +            break;
> +        case 9:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT2020;
> +            break;
> +        case 10:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
> +            break;
> +        case 11:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
> +            break;
> +        case 12:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
> +            break;
> +        case 22:
> +            st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
> +            break;
> +        default:
> +            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
> +        }
> +
> +        /* Color Transfer Characteristics */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, &error)) {
> +        case 1:
> +            st->codecpar->color_trc = AVCOL_TRC_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_trc = AVCOL_TRC_GAMMA22;
> +            break;
> +        case 5:
> +            st->codecpar->color_trc = AVCOL_TRC_GAMMA28;
> +            break;
> +        case 6:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_trc = AVCOL_TRC_LINEAR;
> +            break;
> +        case 9:
> +            st->codecpar->color_trc = AVCOL_TRC_LOG;
> +            break;
> +        case 10:
> +            st->codecpar->color_trc = AVCOL_TRC_LOG_SQRT;
> +            break;
> +        case 11:
> +            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_4;
> +            break;
> +        case 12:
> +            st->codecpar->color_trc = AVCOL_TRC_BT1361_ECG;
> +            break;
> +        case 13:
> +            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_1;
> +            break;
> +        case 14:
> +            st->codecpar->color_trc = AVCOL_TRC_BT2020_10;
> +            break;
> +        case 15:
> +            st->codecpar->color_trc = AVCOL_TRC_BT2020_12;
> +            break;
> +        case 16:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE2084;
> +            break;
> +        case 17:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE428;
> +            break;
> +        case 18:
> +            st->codecpar->color_trc = AVCOL_TRC_ARIB_STD_B67;
> +            break;
> +        default:
> +            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
> +        }
> +
> +        /* Matrix coefficients */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Matrix", 0, &error)) {
> +        case 0:
> +            st->codecpar->color_space = AVCOL_SPC_RGB;
> +            break;
> +        case 1:
> +            st->codecpar->color_space = AVCOL_SPC_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_space = AVCOL_SPC_FCC;
> +            break;
> +        case 5:
> +            st->codecpar->color_space = AVCOL_SPC_BT470BG;
> +            break;
> +        case 6:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_space = AVCOL_SPC_YCGCO;
> +            break;
> +        case 9:
> +            st->codecpar->color_space = AVCOL_SPC_BT2020_NCL;
> +            break;
> +        case 10:
> +            st->codecpar->color_space = AVCOL_SPC_BT2020_CL;
> +            break;
> +        case 11:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE2085;
> +            break;
> +        case 12:
> +            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_NCL;
> +            break;
> +        case 13:
> +            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_CL;
> +            break;
> +        case 14:
> +            st->codecpar->color_space = AVCOL_SPC_ICTCP;
> +            break;
> +        default:
> +            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +        }
> +
> +        /* Chroma Location */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ChromaLocation", 0, &error)) {
> +        case 0:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_LEFT;
> +            break;
> +        case 1:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_CENTER;
> +            break;
> +        case 2:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_TOPLEFT;
> +            break;
> +        case 3:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_TOP;
> +            break;
> +        case 4:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOMLEFT;
> +            break;
> +        case 5:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOM;
> +            break;
> +        default:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
> +        }
> +    } else {
> +        st->codecpar->field_order = AV_FIELD_UNKNOWN;
> +        /* AviSynth works with frame-based video, detecting field order can
> +         * only work when avs_is_field_based returns 'false'. */
> +        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;
> +            }
> +            else if (avs_is_bff(avs->vi)) {
> +                st->codecpar->field_order = AV_FIELD_BB;
> +            }
> +        }
> +    }
> +
>       return 0;
>   }
>   

Pushed.
Andreas Rheinhardt Feb. 19, 2022, 8:39 p.m. UTC | #2
Stephen Hutchinson:
> * Field Order
> * Chroma Location
> * Color Transfer Characteristics
> * Color Range
> * Color Primaries
> * Matrix Coefficients
> 
> The existing TFF/BFF detection is retained as a fallback for
> older versions of AviSynth that can't access frame properties.
> The other properties have no legacy equivalent to detect them.
> 
> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
> ---
>  libavformat/avisynth.c | 263 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 250 insertions(+), 13 deletions(-)
> 
> diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
> index 1e862a6a85..8bc39869a3 100644
> --- a/libavformat/avisynth.c
> +++ b/libavformat/avisynth.c
> @@ -19,6 +19,8 @@
>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>   */
>  
> +#include <stdbool.h>
> +
>  #include "libavutil/attributes.h"
>  #include "libavutil/internal.h"
>  
> @@ -76,6 +78,9 @@ typedef struct AviSynthLibrary {
>      AVSC_DECLARE_FUNC(avs_get_row_size_p);
>      AVSC_DECLARE_FUNC(avs_is_planar_rgb);
>      AVSC_DECLARE_FUNC(avs_is_planar_rgba);
> +    AVSC_DECLARE_FUNC(avs_get_frame_props_ro);
> +    AVSC_DECLARE_FUNC(avs_prop_get_int);
> +    AVSC_DECLARE_FUNC(avs_get_env_property);
>  #undef AVSC_DECLARE_FUNC
>  } AviSynthLibrary;
>  
> @@ -153,6 +158,9 @@ static av_cold int avisynth_load_library(void)
>      LOAD_AVS_FUNC(avs_get_row_size_p, 1);
>      LOAD_AVS_FUNC(avs_is_planar_rgb, 1);
>      LOAD_AVS_FUNC(avs_is_planar_rgba, 1);
> +    LOAD_AVS_FUNC(avs_get_frame_props_ro, 1);
> +    LOAD_AVS_FUNC(avs_prop_get_int, 1);
> +    LOAD_AVS_FUNC(avs_get_env_property, 1);
>  #undef LOAD_AVS_FUNC
>  
>      atexit(avisynth_atexit_handler);
> @@ -236,6 +244,10 @@ static av_cold void avisynth_atexit_handler(void)
>  static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>  {
>      AviSynthContext *avs = s->priv_data;
> +    const AVS_Map *avsmap;
> +    AVS_VideoFrame *frame;
> +    int framedata, error;
> +    bool frameprop;
>      int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
>  
>      st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> @@ -251,19 +263,6 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>      avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
>  
>  
> -    st->codecpar->field_order = AV_FIELD_UNKNOWN;
> -    /* AviSynth works with frame-based video, detecting field order can
> -     * only work when avs_is_field_based returns 'false'. */
> -    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;
> -        }
> -        else if (avs_is_bff(avs->vi)) {
> -            st->codecpar->field_order = AV_FIELD_BB;
> -        }
> -    }
> -
>      switch (avs->vi->pixel_type) {
>      /* 10~16-bit YUV pix_fmts (AviSynth+) */
>      case AVS_CS_YUV444P10:
> @@ -499,6 +498,244 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>          avs->n_planes = 1;
>          avs->planes   = avs_planes_packed;
>      }
> +
> +    /* Read AviSynth+'s frame properties to set additional info.
> +     *
> +     * Due to a bug preventing the C interface from accessing frame
> +     * properties in earlier versions of interface version 8, only
> +     * enable this if we detect version 8.1 at the minimum. */
> +
> +    if (!avs_library.avs_get_env_property) {
> +        av_log(s, AV_LOG_TRACE, "%s\n",
> +               "avs_get_env_property does not exist in AviSynth library; frame properties won't be checked.");
> +        frameprop = false;
> +    } else {
> +        if (avs_library.avs_get_env_property(avs->env, AVS_AEP_INTERFACE_BUGFIX)) {
> +            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.1 or higher, reading frame properties.");
> +            frameprop = true;
> +        } else {
> +            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.0, need 8.1+ to read frame properties.");
> +            frameprop = false;
> +        }
> +    }
> +
> +    if (frameprop = true) {
> +
> +        frame  = avs_library.avs_get_frame(avs->clip, framedata);

framedata is completely uninitialized here. I presume it should be zero
(for the first frame)? (This is Coverity issue 1500290.)

> +        avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
> +
> +        /* Field order */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_FieldBased", 0, &error)) {
> +        case 0:
> +            st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
> +            break;
> +        case 1:
> +            st->codecpar->field_order = AV_FIELD_BB;
> +            break;
> +        case 2:
> +            st->codecpar->field_order = AV_FIELD_TT;
> +            break;
> +        default:
> +            st->codecpar->field_order = AV_FIELD_UNKNOWN;
> +        }
> +
> +        /* Color Range */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ColorRange", 0, &error)) {
> +        case 0:
> +            st->codecpar->color_range = AVCOL_RANGE_JPEG;
> +            break;
> +        case 1:
> +            st->codecpar->color_range = AVCOL_RANGE_MPEG;
> +            break;
> +        default:
> +            st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
> +        }
> +
> +        /* Color Primaries */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 0, &error)) {
> +        case 1:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT470M;
> +            break;
> +        case 5:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
> +            break;
> +        case 6:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_primaries = AVCOL_PRI_FILM;
> +            break;
> +        case 9:
> +            st->codecpar->color_primaries = AVCOL_PRI_BT2020;
> +            break;
> +        case 10:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
> +            break;
> +        case 11:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
> +            break;
> +        case 12:
> +            st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
> +            break;
> +        case 22:
> +            st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
> +            break;
> +        default:
> +            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
> +        }
> +
> +        /* Color Transfer Characteristics */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, &error)) {
> +        case 1:
> +            st->codecpar->color_trc = AVCOL_TRC_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_trc = AVCOL_TRC_GAMMA22;
> +            break;
> +        case 5:
> +            st->codecpar->color_trc = AVCOL_TRC_GAMMA28;
> +            break;
> +        case 6:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_trc = AVCOL_TRC_LINEAR;
> +            break;
> +        case 9:
> +            st->codecpar->color_trc = AVCOL_TRC_LOG;
> +            break;
> +        case 10:
> +            st->codecpar->color_trc = AVCOL_TRC_LOG_SQRT;
> +            break;
> +        case 11:
> +            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_4;
> +            break;
> +        case 12:
> +            st->codecpar->color_trc = AVCOL_TRC_BT1361_ECG;
> +            break;
> +        case 13:
> +            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_1;
> +            break;
> +        case 14:
> +            st->codecpar->color_trc = AVCOL_TRC_BT2020_10;
> +            break;
> +        case 15:
> +            st->codecpar->color_trc = AVCOL_TRC_BT2020_12;
> +            break;
> +        case 16:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE2084;
> +            break;
> +        case 17:
> +            st->codecpar->color_trc = AVCOL_TRC_SMPTE428;
> +            break;
> +        case 18:
> +            st->codecpar->color_trc = AVCOL_TRC_ARIB_STD_B67;
> +            break;
> +        default:
> +            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
> +        }
> +
> +        /* Matrix coefficients */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Matrix", 0, &error)) {
> +        case 0:
> +            st->codecpar->color_space = AVCOL_SPC_RGB;
> +            break;
> +        case 1:
> +            st->codecpar->color_space = AVCOL_SPC_BT709;
> +            break;
> +        case 2:
> +            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +            break;
> +        case 4:
> +            st->codecpar->color_space = AVCOL_SPC_FCC;
> +            break;
> +        case 5:
> +            st->codecpar->color_space = AVCOL_SPC_BT470BG;
> +            break;
> +        case 6:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE170M;
> +            break;
> +        case 7:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE240M;
> +            break;
> +        case 8:
> +            st->codecpar->color_space = AVCOL_SPC_YCGCO;
> +            break;
> +        case 9:
> +            st->codecpar->color_space = AVCOL_SPC_BT2020_NCL;
> +            break;
> +        case 10:
> +            st->codecpar->color_space = AVCOL_SPC_BT2020_CL;
> +            break;
> +        case 11:
> +            st->codecpar->color_space = AVCOL_SPC_SMPTE2085;
> +            break;
> +        case 12:
> +            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_NCL;
> +            break;
> +        case 13:
> +            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_CL;
> +            break;
> +        case 14:
> +            st->codecpar->color_space = AVCOL_SPC_ICTCP;
> +            break;
> +        default:
> +            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +        }
> +
> +        /* Chroma Location */
> +        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ChromaLocation", 0, &error)) {
> +        case 0:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_LEFT;
> +            break;
> +        case 1:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_CENTER;
> +            break;
> +        case 2:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_TOPLEFT;
> +            break;
> +        case 3:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_TOP;
> +            break;
> +        case 4:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOMLEFT;
> +            break;
> +        case 5:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOM;
> +            break;
> +        default:
> +            st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
> +        }
> +    } else {
> +        st->codecpar->field_order = AV_FIELD_UNKNOWN;
> +        /* AviSynth works with frame-based video, detecting field order can
> +         * only work when avs_is_field_based returns 'false'. */
> +        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;
> +            }
> +            else if (avs_is_bff(avs->vi)) {
> +                st->codecpar->field_order = AV_FIELD_BB;
> +            }
> +        }
> +    }
> +
>      return 0;
>  }
>
Stephen Hutchinson Feb. 19, 2022, 9:45 p.m. UTC | #3
On 2/19/22 3:39 PM, Andreas Rheinhardt wrote:
>> +    if (frameprop = true) {
>> +
>> +        frame  = avs_library.avs_get_frame(avs->clip, framedata);
> 
> framedata is completely uninitialized here. I presume it should be zero
> (for the first frame)? (This is Coverity issue 1500290.)
> 

I don't remember why I left that uninitialized (there's a vague memory 
of something, almost certainly unrelated since it works now, but it was 
months ago at this point).

Patch sent.
Steinar Apalnes Aug. 24, 2022, 5:04 p.m. UTC | #4
tir. 8. feb. 2022 kl. 12:03 skrev Stephen Hutchinson <qyot27@gmail.com>:

> * Field Order
> * Chroma Location
> * Color Transfer Characteristics
> * Color Range
> * Color Primaries
> * Matrix Coefficients
>
> The existing TFF/BFF detection is retained as a fallback for
> older versions of AviSynth that can't access frame properties.
> The other properties have no legacy equivalent to detect them.
>
> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
>
.......
 Hi Stephen,

Would it be possible to add support for "_SARum" and "_SARDen" so that
ffmpeg could also recognize the sample aspect ratio in avs scripts?

-steinar
Stephen Hutchinson Aug. 25, 2022, 12:11 a.m. UTC | #5
On 8/24/22 1:04 PM, Steinar Apalnes wrote:
> tir. 8. feb. 2022 kl. 12:03 skrev Stephen Hutchinson <qyot27@gmail.com>:
> 
>> * Field Order
>> * Chroma Location
>> * Color Transfer Characteristics
>> * Color Range
>> * Color Primaries
>> * Matrix Coefficients
>>
>> The existing TFF/BFF detection is retained as a fallback for
>> older versions of AviSynth that can't access frame properties.
>> The other properties have no legacy equivalent to detect them.
>>
>> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
>>
> .......
>   Hi Stephen,
> 
> Would it be possible to add support for "_SARum" and "_SARDen" so that
> ffmpeg could also recognize the sample aspect ratio in avs scripts?
> 

I'm a bit hesitant to do so, namely because the _SARNum/Den properties
are much more likely to need to have been changed due to operations
in-script, and unless the user is studious about updating those
properties after even just a basic resizing operation, then _SARNum/Den
will still be set to the original values populated by the source filter,
and will be wrong, leading to encodes ending up wrong and potentially
bug reports to Trac which aren't actually the fault of the demuxer.

This is partially coming from the fact that even the color-based
properties that were already added have experienced some level of
backlash because of the requirement for users to ensure the properties
are correctly updated if they've done any changes to those factors
(as best as I'm aware, the filters in the AviSynth+ core still only pass
through the existing properties, but they don't update them if they
pertain to that property's functionality; I believe some external
filters do update them, however).  I would be fairly confident in
betting that users resizing video is far more common than them doing
color correction ops that would require updating the frameprops FFmpeg
can currently read.

One mitigation to that, IMO, would be to flag that as an experimental
feature, making it to where FFmpeg won't read _SARNum/Den unless
the -strict option has been used.
Steinar Apalnes Aug. 25, 2022, 7:46 a.m. UTC | #6
tor. 25. aug. 2022 kl. 02:11 skrev Stephen Hutchinson <qyot27@gmail.com>:

> On 8/24/22 1:04 PM, Steinar Apalnes wrote:
> > tir. 8. feb. 2022 kl. 12:03 skrev Stephen Hutchinson <qyot27@gmail.com>:
> >
> >> * Field Order
> >> * Chroma Location
> >> * Color Transfer Characteristics
> >> * Color Range
> >> * Color Primaries
> >> * Matrix Coefficients
> >>
> >> The existing TFF/BFF detection is retained as a fallback for
> >> older versions of AviSynth that can't access frame properties.
> >> The other properties have no legacy equivalent to detect them.
> >>
> >> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
> >>
> > .......
> >   Hi Stephen,
> >
> > Would it be possible to add support for "_SARum" and "_SARDen" so that
> > ffmpeg could also recognize the sample aspect ratio in avs scripts?
> >
>
> I'm a bit hesitant to do so, namely because the _SARNum/Den properties
> are much more likely to need to have been changed due to operations
> in-script, and unless the user is studious about updating those
> properties after even just a basic resizing operation, then _SARNum/Den
> will still be set to the original values populated by the source filter,
> and will be wrong, leading to encodes ending up wrong and potentially
> bug reports to Trac which aren't actually the fault of the demuxer.
>
> This is partially coming from the fact that even the color-based
> properties that were already added have experienced some level of
> backlash because of the requirement for users to ensure the properties
> are correctly updated if they've done any changes to those factors
> (as best as I'm aware, the filters in the AviSynth+ core still only pass
> through the existing properties, but they don't update them if they
> pertain to that property's functionality; I believe some external
> filters do update them, however).  I would be fairly confident in
> betting that users resizing video is far more common than them doing
> color correction ops that would require updating the frameprops FFmpeg
> can currently read.
>
> One mitigation to that, IMO, would be to flag that as an experimental
> feature, making it to where FFmpeg won't read _SARNum/Den unless
> the -strict option has been used.
> _______________________________________________
>
>
If you think cherry picking what props to support under normal operation is
the way to go
then a -strict option to support *all* "scary" avs props would be very
welcome indeed.
Because as it is now we have nothing at all in regards to the SAR.

Thanks for your efforts :-)

-steinar
Stephen Hutchinson Sept. 4, 2022, 7:14 p.m. UTC | #7
On 8/25/22 3:46 AM, Steinar Apalnes wrote:
> tor. 25. aug. 2022 kl. 02:11 skrev Stephen Hutchinson <qyot27@gmail.com>:
> 
>> On 8/24/22 1:04 PM, Steinar Apalnes wrote:
>>> tir. 8. feb. 2022 kl. 12:03 skrev Stephen Hutchinson <qyot27@gmail.com>:
>>>
>>>> * Field Order
>>>> * Chroma Location
>>>> * Color Transfer Characteristics
>>>> * Color Range
>>>> * Color Primaries
>>>> * Matrix Coefficients
>>>>
>>>> The existing TFF/BFF detection is retained as a fallback for
>>>> older versions of AviSynth that can't access frame properties.
>>>> The other properties have no legacy equivalent to detect them.
>>>>
>>>> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
>>>>
>>> .......
>>>    Hi Stephen,
>>>
>>> Would it be possible to add support for "_SARum" and "_SARDen" so that
>>> ffmpeg could also recognize the sample aspect ratio in avs scripts?
>>>
>>
>> I'm a bit hesitant to do so, namely because the _SARNum/Den properties
>> are much more likely to need to have been changed due to operations
>> in-script, and unless the user is studious about updating those
>> properties after even just a basic resizing operation, then _SARNum/Den
>> will still be set to the original values populated by the source filter,
>> and will be wrong, leading to encodes ending up wrong and potentially
>> bug reports to Trac which aren't actually the fault of the demuxer.
>>
>> This is partially coming from the fact that even the color-based
>> properties that were already added have experienced some level of
>> backlash because of the requirement for users to ensure the properties
>> are correctly updated if they've done any changes to those factors
>> (as best as I'm aware, the filters in the AviSynth+ core still only pass
>> through the existing properties, but they don't update them if they
>> pertain to that property's functionality; I believe some external
>> filters do update them, however).  I would be fairly confident in
>> betting that users resizing video is far more common than them doing
>> color correction ops that would require updating the frameprops FFmpeg
>> can currently read.
>>
>> One mitigation to that, IMO, would be to flag that as an experimental
>> feature, making it to where FFmpeg won't read _SARNum/Den unless
>> the -strict option has been used.
>> _______________________________________________
>>
>>
> If you think cherry picking what props to support under normal operation is
> the way to go
> then a -strict option to support *all* "scary" avs props would be very
> welcome indeed.
> Because as it is now we have nothing at all in regards to the SAR.
> 
> Thanks for your efforts :-)
> 
> -steinar

SAR frameprops implemented in commit c49beead, and a more fine-grained,
flags-based way to toggle any of the frameprops on and off added in
commit adead1cc.  Pushed a few minutes ago.
diff mbox series

Patch

diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 1e862a6a85..8bc39869a3 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -19,6 +19,8 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdbool.h>
+
 #include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 
@@ -76,6 +78,9 @@  typedef struct AviSynthLibrary {
     AVSC_DECLARE_FUNC(avs_get_row_size_p);
     AVSC_DECLARE_FUNC(avs_is_planar_rgb);
     AVSC_DECLARE_FUNC(avs_is_planar_rgba);
+    AVSC_DECLARE_FUNC(avs_get_frame_props_ro);
+    AVSC_DECLARE_FUNC(avs_prop_get_int);
+    AVSC_DECLARE_FUNC(avs_get_env_property);
 #undef AVSC_DECLARE_FUNC
 } AviSynthLibrary;
 
@@ -153,6 +158,9 @@  static av_cold int avisynth_load_library(void)
     LOAD_AVS_FUNC(avs_get_row_size_p, 1);
     LOAD_AVS_FUNC(avs_is_planar_rgb, 1);
     LOAD_AVS_FUNC(avs_is_planar_rgba, 1);
+    LOAD_AVS_FUNC(avs_get_frame_props_ro, 1);
+    LOAD_AVS_FUNC(avs_prop_get_int, 1);
+    LOAD_AVS_FUNC(avs_get_env_property, 1);
 #undef LOAD_AVS_FUNC
 
     atexit(avisynth_atexit_handler);
@@ -236,6 +244,10 @@  static av_cold void avisynth_atexit_handler(void)
 static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
 {
     AviSynthContext *avs = s->priv_data;
+    const AVS_Map *avsmap;
+    AVS_VideoFrame *frame;
+    int framedata, error;
+    bool frameprop;
     int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA
 
     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -251,19 +263,6 @@  static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
     avpriv_set_pts_info(st, 32, avs->vi->fps_denominator, avs->vi->fps_numerator);
 
 
-    st->codecpar->field_order = AV_FIELD_UNKNOWN;
-    /* AviSynth works with frame-based video, detecting field order can
-     * only work when avs_is_field_based returns 'false'. */
-    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;
-        }
-        else if (avs_is_bff(avs->vi)) {
-            st->codecpar->field_order = AV_FIELD_BB;
-        }
-    }
-
     switch (avs->vi->pixel_type) {
     /* 10~16-bit YUV pix_fmts (AviSynth+) */
     case AVS_CS_YUV444P10:
@@ -499,6 +498,244 @@  static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
         avs->n_planes = 1;
         avs->planes   = avs_planes_packed;
     }
+
+    /* Read AviSynth+'s frame properties to set additional info.
+     *
+     * Due to a bug preventing the C interface from accessing frame
+     * properties in earlier versions of interface version 8, only
+     * enable this if we detect version 8.1 at the minimum. */
+
+    if (!avs_library.avs_get_env_property) {
+        av_log(s, AV_LOG_TRACE, "%s\n",
+               "avs_get_env_property does not exist in AviSynth library; frame properties won't be checked.");
+        frameprop = false;
+    } else {
+        if (avs_library.avs_get_env_property(avs->env, AVS_AEP_INTERFACE_BUGFIX)) {
+            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.1 or higher, reading frame properties.");
+            frameprop = true;
+        } else {
+            av_log(s, AV_LOG_TRACE, "%s\n", "Using interface version 8.0, need 8.1+ to read frame properties.");
+            frameprop = false;
+        }
+    }
+
+    if (frameprop = true) {
+
+        frame  = avs_library.avs_get_frame(avs->clip, framedata);
+        avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
+
+        /* Field order */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_FieldBased", 0, &error)) {
+        case 0:
+            st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
+            break;
+        case 1:
+            st->codecpar->field_order = AV_FIELD_BB;
+            break;
+        case 2:
+            st->codecpar->field_order = AV_FIELD_TT;
+            break;
+        default:
+            st->codecpar->field_order = AV_FIELD_UNKNOWN;
+        }
+
+        /* Color Range */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ColorRange", 0, &error)) {
+        case 0:
+            st->codecpar->color_range = AVCOL_RANGE_JPEG;
+            break;
+        case 1:
+            st->codecpar->color_range = AVCOL_RANGE_MPEG;
+            break;
+        default:
+            st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
+        }
+
+        /* Color Primaries */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 0, &error)) {
+        case 1:
+            st->codecpar->color_primaries = AVCOL_PRI_BT709;
+            break;
+        case 2:
+            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
+            break;
+        case 4:
+            st->codecpar->color_primaries = AVCOL_PRI_BT470M;
+            break;
+        case 5:
+            st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
+            break;
+        case 6:
+            st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
+            break;
+        case 7:
+            st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
+            break;
+        case 8:
+            st->codecpar->color_primaries = AVCOL_PRI_FILM;
+            break;
+        case 9:
+            st->codecpar->color_primaries = AVCOL_PRI_BT2020;
+            break;
+        case 10:
+            st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
+            break;
+        case 11:
+            st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
+            break;
+        case 12:
+            st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
+            break;
+        case 22:
+            st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
+            break;
+        default:
+            st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
+        }
+
+        /* Color Transfer Characteristics */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, &error)) {
+        case 1:
+            st->codecpar->color_trc = AVCOL_TRC_BT709;
+            break;
+        case 2:
+            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
+            break;
+        case 4:
+            st->codecpar->color_trc = AVCOL_TRC_GAMMA22;
+            break;
+        case 5:
+            st->codecpar->color_trc = AVCOL_TRC_GAMMA28;
+            break;
+        case 6:
+            st->codecpar->color_trc = AVCOL_TRC_SMPTE170M;
+            break;
+        case 7:
+            st->codecpar->color_trc = AVCOL_TRC_SMPTE240M;
+            break;
+        case 8:
+            st->codecpar->color_trc = AVCOL_TRC_LINEAR;
+            break;
+        case 9:
+            st->codecpar->color_trc = AVCOL_TRC_LOG;
+            break;
+        case 10:
+            st->codecpar->color_trc = AVCOL_TRC_LOG_SQRT;
+            break;
+        case 11:
+            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_4;
+            break;
+        case 12:
+            st->codecpar->color_trc = AVCOL_TRC_BT1361_ECG;
+            break;
+        case 13:
+            st->codecpar->color_trc = AVCOL_TRC_IEC61966_2_1;
+            break;
+        case 14:
+            st->codecpar->color_trc = AVCOL_TRC_BT2020_10;
+            break;
+        case 15:
+            st->codecpar->color_trc = AVCOL_TRC_BT2020_12;
+            break;
+        case 16:
+            st->codecpar->color_trc = AVCOL_TRC_SMPTE2084;
+            break;
+        case 17:
+            st->codecpar->color_trc = AVCOL_TRC_SMPTE428;
+            break;
+        case 18:
+            st->codecpar->color_trc = AVCOL_TRC_ARIB_STD_B67;
+            break;
+        default:
+            st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
+        }
+
+        /* Matrix coefficients */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Matrix", 0, &error)) {
+        case 0:
+            st->codecpar->color_space = AVCOL_SPC_RGB;
+            break;
+        case 1:
+            st->codecpar->color_space = AVCOL_SPC_BT709;
+            break;
+        case 2:
+            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
+            break;
+        case 4:
+            st->codecpar->color_space = AVCOL_SPC_FCC;
+            break;
+        case 5:
+            st->codecpar->color_space = AVCOL_SPC_BT470BG;
+            break;
+        case 6:
+            st->codecpar->color_space = AVCOL_SPC_SMPTE170M;
+            break;
+        case 7:
+            st->codecpar->color_space = AVCOL_SPC_SMPTE240M;
+            break;
+        case 8:
+            st->codecpar->color_space = AVCOL_SPC_YCGCO;
+            break;
+        case 9:
+            st->codecpar->color_space = AVCOL_SPC_BT2020_NCL;
+            break;
+        case 10:
+            st->codecpar->color_space = AVCOL_SPC_BT2020_CL;
+            break;
+        case 11:
+            st->codecpar->color_space = AVCOL_SPC_SMPTE2085;
+            break;
+        case 12:
+            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_NCL;
+            break;
+        case 13:
+            st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_CL;
+            break;
+        case 14:
+            st->codecpar->color_space = AVCOL_SPC_ICTCP;
+            break;
+        default:
+            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
+        }
+
+        /* Chroma Location */
+        switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ChromaLocation", 0, &error)) {
+        case 0:
+            st->codecpar->chroma_location = AVCHROMA_LOC_LEFT;
+            break;
+        case 1:
+            st->codecpar->chroma_location = AVCHROMA_LOC_CENTER;
+            break;
+        case 2:
+            st->codecpar->chroma_location = AVCHROMA_LOC_TOPLEFT;
+            break;
+        case 3:
+            st->codecpar->chroma_location = AVCHROMA_LOC_TOP;
+            break;
+        case 4:
+            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOMLEFT;
+            break;
+        case 5:
+            st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOM;
+            break;
+        default:
+            st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
+        }
+    } else {
+        st->codecpar->field_order = AV_FIELD_UNKNOWN;
+        /* AviSynth works with frame-based video, detecting field order can
+         * only work when avs_is_field_based returns 'false'. */
+        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;
+            }
+            else if (avs_is_bff(avs->vi)) {
+                st->codecpar->field_order = AV_FIELD_BB;
+            }
+        }
+    }
+
     return 0;
 }