diff mbox series

[FFmpeg-devel,3/9] avformat/avisynth: add read_frameprops option

Message ID 20220829000244.71123-4-qyot27@gmail.com
State New
Headers show
Series avisynth: add user options | expand

Commit Message

Stephen Hutchinson Aug. 29, 2022, 12:02 a.m. UTC
Allows turning the reading of frame properties entirely on and off.
Defaults to reading frame properties.

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

Comments

Andreas Rheinhardt Aug. 29, 2022, 12:41 a.m. UTC | #1
Stephen Hutchinson:
> Allows turning the reading of frame properties entirely on and off.
> Defaults to reading frame properties.
> 
> Signed-off-by: Stephen Hutchinson <qyot27@gmail.com>
> ---
>  libavformat/avisynth.c | 355 +++++++++++++++++++++--------------------
>  1 file changed, 179 insertions(+), 176 deletions(-)
> 
> diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
> index d503c7ed40..5d726d70a5 100644
> --- a/libavformat/avisynth.c
> +++ b/libavformat/avisynth.c
> @@ -103,6 +103,7 @@ typedef struct AviSynthContext {
>      int error;
>  
>      /* (de)activate reading frame properties */
> +    int frameprops;
>      int frameprop_sar;
>  
>      /* Linked list pointers. */
> @@ -522,227 +523,228 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
>          frame  = avs_library.avs_get_frame(avs->clip, 0);
>          avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
>  
> -        /* Field order */
> -        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) {
> -            st->codecpar->field_order = AV_FIELD_UNKNOWN;
> -        } else {
> -            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:
> +        if(avs->frameprops) {

This will make frameprops a global on-off which overrides everything
else even if some of the "else" stuff has been enabled explicitly. Worse
yet, if you want to disable everything except exactly one field, you
have to leave frameprops enabled and disable everything else explicitly.

Why not use a bitfield (with AV_OPT_TYPE_FLAGS and AV_OPT_TYPE_CONST)?
These properties certainly seem like a bitfield and the above would be
easily achievable with it.

> +            /* Field order */
> +            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) {
>                  st->codecpar->field_order = AV_FIELD_UNKNOWN;
> +            } else {
> +                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 */
> -        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == AVS_PROPTYPE_UNSET) {
> -            st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
> -        } else {
> -            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:
> +            /* Color Range */
> +            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == AVS_PROPTYPE_UNSET) {
>                  st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
> +            } else {
> +                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 */
> -        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_Matrix") == AVS_PROPTYPE_UNSET) {
> -            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> -        } else {
> -            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Matrix", 0, &error)) {
> -            case 0:
> -                st->codecpar->color_space = AVCOL_SPC_RGB;
> -                break;
> +            /* Color Primaries */
> +            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 0, &error)) {
>              case 1:
> -                st->codecpar->color_space = AVCOL_SPC_BT709;
> +                st->codecpar->color_primaries = AVCOL_PRI_BT709;

You reindent everything once in this patch and then in every
switch/block once more when you add the relevant option. This is
unnecessary; it also makes this patch harder to read. Just take a look
at the above: It seems as if you were replacing setting color_space with
color_primaries, but it is just the git diff algorithm trying to
minimize the diff. For that reason the project policy states that
reindentation should be done in a separate commit (one commit at the end
of this patchset is enough).

>                  break;
>              case 2:
> -                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +                st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
>                  break;
>              case 4:
> -                st->codecpar->color_space = AVCOL_SPC_FCC;
> +                st->codecpar->color_primaries = AVCOL_PRI_BT470M;
>                  break;
>              case 5:
> -                st->codecpar->color_space = AVCOL_SPC_BT470BG;
> +                st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
>                  break;
>              case 6:
> -                st->codecpar->color_space = AVCOL_SPC_SMPTE170M;
> +                st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
>                  break;
>              case 7:
> -                st->codecpar->color_space = AVCOL_SPC_SMPTE240M;
> +                st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
>                  break;
>              case 8:
> -                st->codecpar->color_space = AVCOL_SPC_YCGCO;
> +                st->codecpar->color_primaries = AVCOL_PRI_FILM;
>                  break;
>              case 9:
> -                st->codecpar->color_space = AVCOL_SPC_BT2020_NCL;
> +                st->codecpar->color_primaries = AVCOL_PRI_BT2020;
>                  break;
>              case 10:
> -                st->codecpar->color_space = AVCOL_SPC_BT2020_CL;
> +                st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
>                  break;
>              case 11:
> -                st->codecpar->color_space = AVCOL_SPC_SMPTE2085;
> +                st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
>                  break;
>              case 12:
> -                st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_NCL;
> +                st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
>                  break;
> -            case 13:
> -                st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_CL;
> -                break;
> -            case 14:
> -                st->codecpar->color_space = AVCOL_SPC_ICTCP;
> +            case 22:
> +                st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
>                  break;
>              default:
> -                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +                st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
>              }
> -        }
>  
> -        /* Chroma Location */
> -        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ChromaLocation") == AVS_PROPTYPE_UNSET) {
> -            st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
> -        } else {
> -            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ChromaLocation", 0, &error)) {
> -            case 0:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_LEFT;
> -                break;
> +            /* Color Transfer Characteristics */
> +            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, &error)) {
>              case 1:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_CENTER;
> +                st->codecpar->color_trc = AVCOL_TRC_BT709;
>                  break;
>              case 2:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_TOPLEFT;
> -                break;
> -            case 3:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_TOP;
> +                st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
>                  break;
>              case 4:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOMLEFT;
> +                st->codecpar->color_trc = AVCOL_TRC_GAMMA22;
>                  break;
>              case 5:
> -                st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOM;
> +                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 */
> +            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_Matrix") == AVS_PROPTYPE_UNSET) {
> +                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
> +            } else {
> +                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 */
> +            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ChromaLocation") == AVS_PROPTYPE_UNSET) {
>                  st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
> +            } else {
> +                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;
> +                }
>              }
> -        }
>  
> -        /* Sample aspect ratio */
> -        if (avs->frameprop_sar) {
> -            sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, &error);
> -            sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, &error);
> -            st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
> +            /* Sample aspect ratio */
> +            if (avs->frameprop_sar) {
> +                sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, &error);
> +                sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, &error);
> +                st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
> +            }
>          }
> -
>          avs_library.avs_release_video_frame(frame);
>      } else {
>          st->codecpar->field_order = AV_FIELD_UNKNOWN;
> @@ -1149,6 +1151,7 @@ static int avisynth_read_seek(AVFormatContext *s, int stream_index,
>  
>  #define OFFSET(x) offsetof(AviSynthContext, x)
>  static const AVOption avisynth_options[] = {
> +    { "read_frameprops", "Read frame properties from script (AviSynth+ v3.7.1+).", OFFSET(frameprops), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
>      { "read_frameprop_sar", "Read SAR from script's frame properties (AviSynth+ v3.7.1+).", OFFSET(frameprop_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
>      { NULL },
>  };
Stephen Hutchinson Aug. 30, 2022, 11:04 p.m. UTC | #2
On 8/28/22 8:41 PM, Andreas Rheinhardt wrote:
> This will make frameprops a global on-off which overrides everything
> else even if some of the "else" stuff has been enabled explicitly. Worse
> yet, if you want to disable everything except exactly one field, you
> have to leave frameprops enabled and disable everything else explicitly.
> 
> Why not use a bitfield (with AV_OPT_TYPE_FLAGS and AV_OPT_TYPE_CONST)?
> These properties certainly seem like a bitfield and the above would be
> easily achievable with it.
> 

How are flags supposed to be set to on by default? With av_dict_set or
a different mechanism?  Because the closest I was able to get¹,

if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER | 
AVISYNTH_FRAMEPROP_DEFAULT) {

ends up correctly setting the flags that should be on by default,
with the new sar flag able to be enabled or disabled, but the ones
flagged as default refuse to be disabled now.

¹https://github.com/qyot27/FFmpeg/commit/6d3d6108145f9c7ac2dfcdaf09852b7472f6ca7f
Andreas Rheinhardt Aug. 30, 2022, 11:17 p.m. UTC | #3
Stephen Hutchinson:
> On 8/28/22 8:41 PM, Andreas Rheinhardt wrote:
>> This will make frameprops a global on-off which overrides everything
>> else even if some of the "else" stuff has been enabled explicitly. Worse
>> yet, if you want to disable everything except exactly one field, you
>> have to leave frameprops enabled and disable everything else explicitly.
>>
>> Why not use a bitfield (with AV_OPT_TYPE_FLAGS and AV_OPT_TYPE_CONST)?
>> These properties certainly seem like a bitfield and the above would be
>> easily achievable with it.
>>
> 
> How are flags supposed to be set to on by default? With av_dict_set or
> a different mechanism?  Because the closest I was able to get¹,
> 
> if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER |
> AVISYNTH_FRAMEPROP_DEFAULT) {
> 
> ends up correctly setting the flags that should be on by default,
> with the new sar flag able to be enabled or disabled, but the ones
> flagged as default refuse to be disabled now.
> 
> ¹https://github.com/qyot27/FFmpeg/commit/6d3d6108145f9c7ac2dfcdaf09852b7472f6ca7f
> 

{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "flags" },

This is wrong. It should be
{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = AVISYNTH_FRAMEPROP_FIELD_ORDER | AVISYNTH_FRAMEPROP_RANGE |
AVISYNTH_FRAMEPROP_PRIMARIES | AVISYNTH_FRAMEPROP_TRANSFER |
AVISYNTH_FRAMEPROP_MATRIX | AVISYNTH_FRAMEPROP_CHROMA_LOCATION}, 0,
INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "flags" }
The default option should be removed. Users can then set the options via
avisynth_flags=+sar-range or via avisynth_flags=matrix or however they wish.
The AVISYNTH_FRAMEPROP_DEFAULT should also be removed (at least, it
should not be part of the bitfield, but you can of course add a define
(or an enum value) equivalent to the default value I used above and you
can use that for the default value above); to know whether field order
should be exported, you simply query via "if (avs->flags &
AVISYNTH_FRAMEPROP_FIELD_ORDER)". For this it is of course important
that the default value is a combination of other bits of the bitfield
and not a bit of its own.

- Andreas
Stephen Hutchinson Aug. 31, 2022, 12:07 a.m. UTC | #4
On 8/30/22 7:17 PM, Andreas Rheinhardt wrote:
> { "avisynth_flags", "set flags related to reading frame properties from
> script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
> {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "flags" },
> 
> This is wrong. It should be
> { "avisynth_flags", "set flags related to reading frame properties from
> script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
> {.i64 = AVISYNTH_FRAMEPROP_FIELD_ORDER | AVISYNTH_FRAMEPROP_RANGE |
> AVISYNTH_FRAMEPROP_PRIMARIES | AVISYNTH_FRAMEPROP_TRANSFER |
> AVISYNTH_FRAMEPROP_MATRIX | AVISYNTH_FRAMEPROP_CHROMA_LOCATION}, 0,
> INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "flags" }
> The default option should be removed. Users can then set the options via
> avisynth_flags=+sar-range or via avisynth_flags=matrix or however they wish.
> The AVISYNTH_FRAMEPROP_DEFAULT should also be removed (at least, it
> should not be part of the bitfield, but you can of course add a define
> (or an enum value) equivalent to the default value I used above and you
> can use that for the default value above); to know whether field order
> should be exported, you simply query via "if (avs->flags &
> AVISYNTH_FRAMEPROP_FIELD_ORDER)". For this it is of course important
> that the default value is a combination of other bits of the bitfield
> and not a bit of its own.
> 

I don't know why I didn't think to use it directly in the avisynth_flags
line.  Thanks.
diff mbox series

Patch

diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index d503c7ed40..5d726d70a5 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -103,6 +103,7 @@  typedef struct AviSynthContext {
     int error;
 
     /* (de)activate reading frame properties */
+    int frameprops;
     int frameprop_sar;
 
     /* Linked list pointers. */
@@ -522,227 +523,228 @@  static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
         frame  = avs_library.avs_get_frame(avs->clip, 0);
         avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
 
-        /* Field order */
-        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) {
-            st->codecpar->field_order = AV_FIELD_UNKNOWN;
-        } else {
-            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:
+        if(avs->frameprops) {
+            /* Field order */
+            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == AVS_PROPTYPE_UNSET) {
                 st->codecpar->field_order = AV_FIELD_UNKNOWN;
+            } else {
+                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 */
-        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == AVS_PROPTYPE_UNSET) {
-            st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
-        } else {
-            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:
+            /* Color Range */
+            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == AVS_PROPTYPE_UNSET) {
                 st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
+            } else {
+                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 */
-        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_Matrix") == AVS_PROPTYPE_UNSET) {
-            st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
-        } else {
-            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Matrix", 0, &error)) {
-            case 0:
-                st->codecpar->color_space = AVCOL_SPC_RGB;
-                break;
+            /* Color Primaries */
+            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 0, &error)) {
             case 1:
-                st->codecpar->color_space = AVCOL_SPC_BT709;
+                st->codecpar->color_primaries = AVCOL_PRI_BT709;
                 break;
             case 2:
-                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
+                st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
                 break;
             case 4:
-                st->codecpar->color_space = AVCOL_SPC_FCC;
+                st->codecpar->color_primaries = AVCOL_PRI_BT470M;
                 break;
             case 5:
-                st->codecpar->color_space = AVCOL_SPC_BT470BG;
+                st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
                 break;
             case 6:
-                st->codecpar->color_space = AVCOL_SPC_SMPTE170M;
+                st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
                 break;
             case 7:
-                st->codecpar->color_space = AVCOL_SPC_SMPTE240M;
+                st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
                 break;
             case 8:
-                st->codecpar->color_space = AVCOL_SPC_YCGCO;
+                st->codecpar->color_primaries = AVCOL_PRI_FILM;
                 break;
             case 9:
-                st->codecpar->color_space = AVCOL_SPC_BT2020_NCL;
+                st->codecpar->color_primaries = AVCOL_PRI_BT2020;
                 break;
             case 10:
-                st->codecpar->color_space = AVCOL_SPC_BT2020_CL;
+                st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
                 break;
             case 11:
-                st->codecpar->color_space = AVCOL_SPC_SMPTE2085;
+                st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
                 break;
             case 12:
-                st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_NCL;
+                st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
                 break;
-            case 13:
-                st->codecpar->color_space = AVCOL_SPC_CHROMA_DERIVED_CL;
-                break;
-            case 14:
-                st->codecpar->color_space = AVCOL_SPC_ICTCP;
+            case 22:
+                st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
                 break;
             default:
-                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
+                st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
             }
-        }
 
-        /* Chroma Location */
-        if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ChromaLocation") == AVS_PROPTYPE_UNSET) {
-            st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
-        } else {
-            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_ChromaLocation", 0, &error)) {
-            case 0:
-                st->codecpar->chroma_location = AVCHROMA_LOC_LEFT;
-                break;
+            /* Color Transfer Characteristics */
+            switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, &error)) {
             case 1:
-                st->codecpar->chroma_location = AVCHROMA_LOC_CENTER;
+                st->codecpar->color_trc = AVCOL_TRC_BT709;
                 break;
             case 2:
-                st->codecpar->chroma_location = AVCHROMA_LOC_TOPLEFT;
-                break;
-            case 3:
-                st->codecpar->chroma_location = AVCHROMA_LOC_TOP;
+                st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
                 break;
             case 4:
-                st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOMLEFT;
+                st->codecpar->color_trc = AVCOL_TRC_GAMMA22;
                 break;
             case 5:
-                st->codecpar->chroma_location = AVCHROMA_LOC_BOTTOM;
+                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 */
+            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_Matrix") == AVS_PROPTYPE_UNSET) {
+                st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
+            } else {
+                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 */
+            if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ChromaLocation") == AVS_PROPTYPE_UNSET) {
                 st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
+            } else {
+                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;
+                }
             }
-        }
 
-        /* Sample aspect ratio */
-        if (avs->frameprop_sar) {
-            sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, &error);
-            sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, &error);
-            st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
+            /* Sample aspect ratio */
+            if (avs->frameprop_sar) {
+                sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, &error);
+                sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, &error);
+                st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
+            }
         }
-
         avs_library.avs_release_video_frame(frame);
     } else {
         st->codecpar->field_order = AV_FIELD_UNKNOWN;
@@ -1149,6 +1151,7 @@  static int avisynth_read_seek(AVFormatContext *s, int stream_index,
 
 #define OFFSET(x) offsetof(AviSynthContext, x)
 static const AVOption avisynth_options[] = {
+    { "read_frameprops", "Read frame properties from script (AviSynth+ v3.7.1+).", OFFSET(frameprops), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { "read_frameprop_sar", "Read SAR from script's frame properties (AviSynth+ v3.7.1+).", OFFSET(frameprop_sar), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
 };