avisynth: use AviSynth+'s frame properties to set various fields
* 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>
This commit is contained in:
parent
05c492eeb0
commit
af69e4c241
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user