Message ID | 20220208110240.4179-3-qyot27@gmail.com |
---|---|
State | Accepted |
Commit | af69e4c24120ad03f9838a6f7fd39a86d775ccb2 |
Headers | show |
Series | avformat/avisynth: support frame properties | expand |
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 |
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.
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; > } >
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.
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
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.
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
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 --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; }
* 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(-)