summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c20
-rw-r--r--video/filter/vf_vapoursynth.c270
-rw-r--r--video/image_writer.c39
-rw-r--r--video/mp_image.c23
-rw-r--r--video/out/cocoa_cb_common.swift10
-rw-r--r--video/out/d3d11/context.c42
-rw-r--r--video/out/d3d11/ra_d3d11.c20
-rw-r--r--video/out/drm_common.c3
-rw-r--r--video/out/gpu/video.c20
-rw-r--r--video/out/hwdec/hwdec_vaapi.c6
-rw-r--r--video/out/opengl/context_x11egl.c1
-rw-r--r--video/out/opengl/egl_helpers.c111
-rw-r--r--video/out/vo.h2
-rw-r--r--video/out/vo_sixel.c1
-rw-r--r--video/out/vo_tct.c2
-rw-r--r--video/out/vo_vaapi.c16
-rw-r--r--video/out/vulkan/context.c5
-rw-r--r--video/out/w32_common.c10
-rw-r--r--video/out/wayland_common.c171
-rw-r--r--video/out/x11_common.c36
-rw-r--r--video/out/x11_common.h2
-rw-r--r--video/sws_utils.c13
22 files changed, 430 insertions, 393 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 05b66edbd8..d0daa97bdc 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -759,11 +759,6 @@ static void init_avctx(struct mp_filter *vd)
if (!ctx->use_hwdec && ctx->vo && lavc_param->dr) {
avctx->opaque = vd;
avctx->get_buffer2 = get_buffer2_direct;
-#if LIBAVCODEC_VERSION_MAJOR < 60
- AV_NOWARN_DEPRECATED({
- avctx->thread_safe_callbacks = 1;
- });
-#endif
}
avctx->flags |= lavc_param->bitexact ? AV_CODEC_FLAG_BITEXACT : 0;
@@ -780,12 +775,6 @@ static void init_avctx(struct mp_filter *vd)
if (lavc_codec->id == AV_CODEC_ID_H264 && lavc_param->old_x264)
av_opt_set(avctx, "x264_build", "150", AV_OPT_SEARCH_CHILDREN);
-#ifndef AV_CODEC_EXPORT_DATA_FILM_GRAIN
- if (ctx->opts->film_grain == 1)
- MP_WARN(vd, "GPU film grain requested, but FFmpeg too old to expose "
- "film grain parameters. Please update to latest master, "
- "or at least to release 4.4.\n");
-#else
switch(ctx->opts->film_grain) {
case 0: /*CPU*/
// default lavc flags handle film grain within the decoder.
@@ -808,7 +797,6 @@ static void init_avctx(struct mp_filter *vd)
break;
}
-#endif
mp_set_avopts(vd->log, avctx, lavc_param->avopts);
@@ -1238,13 +1226,7 @@ static int decode_frame(struct mp_filter *vd)
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
-
- mpi->pkt_duration =
-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(59, 30, 100)
- mp_pts_from_av(ctx->pic->duration, &ctx->codec_timebase);
-#else
- mp_pts_from_av(ctx->pic->pkt_duration, &ctx->codec_timebase);
-#endif
+ mpi->pkt_duration = mp_pts_from_av(ctx->pic->duration, &ctx->codec_timebase);
av_frame_unref(ctx->pic);
diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c
index 597ef5cbf2..c0d4fdb474 100644
--- a/video/filter/vf_vapoursynth.c
+++ b/video/filter/vf_vapoursynth.c
@@ -22,8 +22,8 @@
#include <limits.h>
#include <assert.h>
-#include <VapourSynth.h>
-#include <VSHelper.h>
+#include <VapourSynth4.h>
+#include <VSScript4.h>
#include <libavutil/rational.h>
#include <libavutil/cpu.h>
@@ -46,6 +46,7 @@ struct vapoursynth_opts {
char *file;
int maxbuffer;
int maxrequests;
+ char *user_data;
const struct script_driver *drv;
};
@@ -57,13 +58,13 @@ struct priv {
VSCore *vscore;
const VSAPI *vsapi;
- VSNodeRef *out_node;
- VSNodeRef *in_node;
+ VSNode *out_node;
+ VSNode *in_node;
const struct script_driver *drv;
// drv_vss
- bool vs_initialized;
- struct VSScript *se;
+ const VSSCRIPTAPI *vs_script_api;
+ VSScript *vs_script;
struct mp_filter *f;
struct mp_pin *in_pin;
@@ -108,72 +109,50 @@ struct script_driver {
void (*unload)(struct priv *p); // unload script and maybe vs
};
-struct mpvs_fmt {
- VSPresetFormat vs;
- int bits, xs, ys;
-};
-
-static const struct mpvs_fmt mpvs_fmt_table[] = {
- {pfYUV420P8, 8, 1, 1},
- {pfYUV420P9, 9, 1, 1},
- {pfYUV420P10, 10, 1, 1},
- {pfYUV420P16, 16, 1, 1},
- {pfYUV422P8, 8, 1, 0},
- {pfYUV422P9, 9, 1, 0},
- {pfYUV422P10, 10, 1, 0},
- {pfYUV422P16, 16, 1, 0},
- {pfYUV410P8, 8, 2, 2},
- {pfYUV411P8, 8, 2, 0},
- {pfYUV440P8, 8, 0, 1},
- {pfYUV444P8, 8, 0, 0},
- {pfYUV444P9, 9, 0, 0},
- {pfYUV444P10, 10, 0, 0},
- {pfYUV444P16, 16, 0, 0},
- {pfNone}
-};
-
-static bool compare_fmt(int imgfmt, const struct mpvs_fmt *vs)
-{
- struct mp_regular_imgfmt rfmt;
- if (!mp_get_regular_imgfmt(&rfmt, imgfmt))
- return false;
- if (rfmt.component_pad > 0)
- return false;
- if (rfmt.chroma_xs != vs->xs || rfmt.chroma_ys != vs->ys)
+static bool get_valid_mp_regular_imgfmt(struct mp_regular_imgfmt *reg_fmt, int imgfmt) {
+ if (!mp_get_regular_imgfmt(reg_fmt, imgfmt))
return false;
- if (rfmt.component_size * 8 + rfmt.component_pad != vs->bits)
+ if (reg_fmt->component_pad > 0)
return false;
- if (rfmt.num_planes != 3)
+ if (reg_fmt->num_planes != 3)
return false;
for (int n = 0; n < 3; n++) {
- if (rfmt.planes[n].num_components != 1)
+ if (reg_fmt->planes[n].num_components != 1)
return false;
- if (rfmt.planes[n].components[0] != n + 1)
+ if (reg_fmt->planes[n].components[0] != n + 1)
return false;
}
return true;
}
-static VSPresetFormat mp_to_vs(int imgfmt)
+static bool mp_to_vs(struct priv *p, VSVideoFormat *vsfmt, int imgfmt)
{
- for (int n = 0; mpvs_fmt_table[n].bits; n++) {
- const struct mpvs_fmt *vsentry = &mpvs_fmt_table[n];
- if (compare_fmt(imgfmt, vsentry))
- return vsentry->vs;
- }
- return pfNone;
+ struct mp_regular_imgfmt reg_fmt;
+ if (!get_valid_mp_regular_imgfmt(&reg_fmt, imgfmt))
+ return false;
+
+ int rfmt_bits = reg_fmt.component_size * 8 + reg_fmt.component_pad;
+ return p->vsapi->queryVideoFormat(vsfmt, cfYUV,
+ reg_fmt.component_type == MP_COMPONENT_TYPE_FLOAT ? stFloat : stInteger,
+ rfmt_bits, reg_fmt.chroma_xs, reg_fmt.chroma_ys, p->vscore);
}
-static int mp_from_vs(VSPresetFormat vs)
+static int mp_from_vs(const VSVideoFormat *vsfmt)
{
- for (int n = 0; mpvs_fmt_table[n].bits; n++) {
- const struct mpvs_fmt *vsentry = &mpvs_fmt_table[n];
- if (vsentry->vs == vs) {
- for (int imgfmt = IMGFMT_START; imgfmt < IMGFMT_END; imgfmt++) {
- if (compare_fmt(imgfmt, vsentry))
- return imgfmt;
+ if (vsfmt->colorFamily == cfYUV) {
+ for (int imgfmt = IMGFMT_START + 1; imgfmt < IMGFMT_END; imgfmt++) {
+ struct mp_regular_imgfmt reg_fmt;
+ if (!get_valid_mp_regular_imgfmt(&reg_fmt, imgfmt))
+ continue;
+
+ int rfmt_bits = reg_fmt.component_size * 8 + reg_fmt.component_pad;
+ if ((reg_fmt.component_type == MP_COMPONENT_TYPE_FLOAT) == (vsfmt->sampleType == stFloat) &&
+ rfmt_bits == vsfmt->bitsPerSample &&
+ reg_fmt.chroma_xs == vsfmt->subSamplingW &&
+ reg_fmt.chroma_ys == vsfmt->subSamplingH)
+ {
+ return imgfmt;
}
- break;
}
}
return 0;
@@ -183,18 +162,18 @@ static void copy_mp_to_vs_frame_props_map(struct priv *p, VSMap *map,
struct mp_image *img)
{
struct mp_image_params *params = &img->params;
- p->vsapi->propSetInt(map, "_SARNum", params->p_w, 0);
- p->vsapi->propSetInt(map, "_SARDen", params->p_h, 0);
+ p->vsapi->mapSetInt(map, "_SARNum", params->p_w, 0);
+ p->vsapi->mapSetInt(map, "_SARDen", params->p_h, 0);
if (params->repr.levels) {
- p->vsapi->propSetInt(map, "_ColorRange",
+ p->vsapi->mapSetInt(map, "_ColorRange",
params->repr.levels == PL_COLOR_LEVELS_LIMITED, 0);
}
// The docs explicitly say it uses libavcodec values.
- p->vsapi->propSetInt(map, "_ColorSpace",
+ p->vsapi->mapSetInt(map, "_ColorSpace",
pl_system_to_av(params->repr.sys), 0);
if (params->chroma_location) {
// 0=left, 1=center, 2=topleft, 3=top, 4=bottomleft, 5=bottom.
- p->vsapi->propSetInt(map, "_ChromaLocation",
+ p->vsapi->mapSetInt(map, "_ChromaLocation",
params->chroma_location - 1, 0);
}
char pict_type = 0;
@@ -204,51 +183,53 @@ static void copy_mp_to_vs_frame_props_map(struct priv *p, VSMap *map,
case 3: pict_type = 'B'; break;
}
if (pict_type)
- p->vsapi->propSetData(map, "_PictType", &pict_type, 1, 0);
+ p->vsapi->mapSetData(map, "_PictType", &pict_type, 1, dtUtf8, 0);
int field = 0;
if (img->fields & MP_IMGFIELD_INTERLACED)
field = img->fields & MP_IMGFIELD_TOP_FIRST ? 2 : 1;
- p->vsapi->propSetInt(map, "_FieldBased", field, 0);
+ p->vsapi->mapSetInt(map, "_FieldBased", field, 0);
// Don't increase the reference count. It is not intended to be read externally,
// and we know it will be alive when we retrieve it.
- p->vsapi->propSetData(map, "_MP_IMAGE", (const char *)img, sizeof(*img), 0);
+ p->vsapi->mapSetData(map, "_MP_IMAGE", (const char *)img, sizeof(*img), dtBinary, 0);
}
-static int set_vs_frame_props(struct priv *p, VSFrameRef *frame,
+static int set_vs_frame_props(struct priv *p, VSFrame *frame,
struct mp_image *img, int dur_num, int dur_den)
{
- VSMap *map = p->vsapi->getFramePropsRW(frame);
+ VSMap *map = p->vsapi->getFramePropertiesRW(frame);
if (!map)
return -1;
- p->vsapi->propSetInt(map, "_DurationNum", dur_num, 0);
- p->vsapi->propSetInt(map, "_DurationDen", dur_den, 0);
+ p->vsapi->mapSetInt(map, "_DurationNum", dur_num, 0);
+ p->vsapi->mapSetInt(map, "_DurationDen", dur_den, 0);
copy_mp_to_vs_frame_props_map(p, map, img);
return 0;
}
-static VSFrameRef *alloc_vs_frame(struct priv *p, struct mp_image_params *fmt)
+static VSFrame *alloc_vs_frame(struct priv *p, struct mp_image_params *fmt)
{
- const VSFormat *vsfmt =
- p->vsapi->getFormatPreset(mp_to_vs(fmt->imgfmt), p->vscore);
- return p->vsapi->newVideoFrame(vsfmt, fmt->w, fmt->h, NULL, p->vscore);
+ VSVideoFormat vsfmt;
+ if (mp_to_vs(p, &vsfmt, fmt->imgfmt))
+ return p->vsapi->newVideoFrame(&vsfmt, fmt->w, fmt->h, NULL, p->vscore);
+
+ return NULL;
}
-static struct mp_image map_vs_frame(struct priv *p, const VSFrameRef *ref,
+static struct mp_image map_vs_frame(struct priv *p, const VSFrame *ref,
bool w, struct mp_image *ref_image)
{
- const VSFormat *fmt = p->vsapi->getFrameFormat(ref);
+ const VSVideoFormat *fmt = p->vsapi->getVideoFrameFormat(ref);
struct mp_image img = {0};
if (ref_image)
img = *ref_image;
- mp_image_setfmt(&img, mp_from_vs(fmt->id));
+ mp_image_setfmt(&img, mp_from_vs(fmt));
mp_image_set_size(&img, p->vsapi->getFrameWidth(ref, 0),
p->vsapi->getFrameHeight(ref, 0));
for (int n = 0; n < img.num_planes; n++) {
if (w) {
- img.planes[n] = p->vsapi->getWritePtr((VSFrameRef *)ref, n);
+ img.planes[n] = p->vsapi->getWritePtr((VSFrame *)ref, n);
} else {
img.planes[n] = (uint8_t *)p->vsapi->getReadPtr(ref, n);
}
@@ -269,19 +250,19 @@ static void drain_oldest_buffered_frame(struct priv *p)
p->in_frameno++;
}
-static void VS_CC vs_frame_done(void *userData, const VSFrameRef *f, int n,
- VSNodeRef *node, const char *errorMsg)
+static void VS_CC vs_frame_done(void *userData, const VSFrame *f, int n,
+ VSNode *node, const char *errorMsg)
{
struct priv *p = userData;
struct mp_image *res = NULL;
if (f) {
- const VSMap *map = p->vsapi->getFramePropsRO(f);
+ const VSMap *map = p->vsapi->getFramePropertiesRO(f);
if (!map)
MP_ERR(p, "Failed to get frame properties!");
struct mp_image *mpi = NULL;
if (map) {
- mpi = (void *)p->vsapi->propGetData(map, "_MP_IMAGE", 0, NULL);
+ mpi = (void *)p->vsapi->mapGetData(map, "_MP_IMAGE", 0, NULL);
if (!mpi)
MP_ERR(p, "Failed to get mp_image attributes!");
}
@@ -291,8 +272,8 @@ static void VS_CC vs_frame_done(void *userData, const VSFrameRef *f, int n,
img.params.crop = (struct mp_rect){0, 0, img.w, img.h};
if (map) {
int err1, err2;
- int num = p->vsapi->propGetInt(map, "_DurationNum", 0, &err1);
- int den = p->vsapi->propGetInt(map, "_DurationDen", 0, &err2);
+ int num = p->vsapi->mapGetInt(map, "_DurationNum", 0, &err1);
+ int den = p->vsapi->mapGetInt(map, "_DurationDen", 0, &err2);
if (!err1 && !err2)
img.pkt_duration = num / (double)den;
}
@@ -453,39 +434,13 @@ done:
mp_mutex_unlock(&p->lock);
}
-static void VS_CC infiltInit(VSMap *in, VSMap *out, void **instanceData,
- VSNode *node, VSCore *core, const VSAPI *vsapi)
-{
- struct priv *p = *instanceData;
- // The number of frames of our input node is obviously unknown. The user
- // could for example seek any time, randomly "ending" the clip.
- // This specific value was suggested by the VapourSynth developer.
- int enough_for_everyone = INT_MAX / 16;
-
- // Note: this is called from createFilter, so no need for locking.
-
- VSVideoInfo fmt = {
- .format = p->vsapi->getFormatPreset(mp_to_vs(p->fmt_in.imgfmt), p->vscore),
- .width = p->fmt_in.w,
- .height = p->fmt_in.h,
- .numFrames = enough_for_everyone,
- };
- if (!fmt.format) {
- p->vsapi->setError(out, "Unsupported input format.\n");
- return;
- }
-
- p->vsapi->setVideoInfo(&fmt, 1, node);
- p->in_node_active = true;
-}
-
-static const VSFrameRef *VS_CC infiltGetFrame(int frameno, int activationReason,
- void **instanceData, void **frameData,
+static const VSFrame *VS_CC infiltGetFrame(int frameno, int activationReason,
+ void *instanceData, void **frameData,
VSFrameContext *frameCtx, VSCore *core,
const VSAPI *vsapi)
{
- struct priv *p = *instanceData;
- VSFrameRef *ret = NULL;
+ struct priv *p = instanceData;
+ VSFrame *ret = NULL;
mp_mutex_lock(&p->lock);
MP_TRACE(p, "VS asking for frame %d (at %d)\n", frameno, p->in_frameno);
@@ -637,7 +592,7 @@ static void destroy_vs(struct priv *p)
static int reinit_vs(struct priv *p, struct mp_image *input)
{
- VSMap *vars = NULL, *in = NULL, *out = NULL;
+ VSMap *vars = NULL;
int res = -1;
destroy_vs(p);
@@ -658,29 +613,41 @@ static int reinit_vs(struct priv *p, struct mp_image *input)
goto error;
}
- in = p->vsapi->createMap();
- out = p->vsapi->createMap();
- vars = p->vsapi->createMap();
- if (!in || !out || !vars)
+ // The number of frames of our input node is obviously unknown. The user
+ // could for example seek any time, randomly "ending" the clip.
+ // This specific value was suggested by the VapourSynth developer.
+ int enough_for_everyone = INT_MAX / 16;
+
+ VSVideoInfo vi_in = {
+ .width = p->fmt_in.w,
+ .height = p->fmt_in.h,
+ .numFrames = enough_for_everyone,
+ };
+ if (!mp_to_vs(p, &vi_in.format, p->fmt_in.imgfmt)) {
+ MP_FATAL(p, "Unsupported input format.\n");
goto error;
+ }
- p->vsapi->createFilter(in, out, "Input", infiltInit, infiltGetFrame,
- infiltFree, fmSerial, 0, p, p->vscore);
- int vserr;
- p->in_node = p->vsapi->propGetNode(out, "clip", 0, &vserr);
+ p->in_node = p->vsapi->createVideoFilter2("Input", &vi_in, infiltGetFrame, infiltFree,
+ fmParallel, NULL, 0, p, p->vscore);
if (!p->in_node) {
MP_FATAL(p, "Could not get our own input node.\n");
goto error;
}
+ p->in_node_active = true;
+
+ vars = p->vsapi->createMap();
+ if (!vars)
+ goto error;
- if (p->vsapi->propSetNode(vars, "video_in", p->in_node, 0))
+ if (p->vsapi->mapSetNode(vars, "video_in", p->in_node, 0))
goto error;
int d_w, d_h;
mp_image_params_get_dsize(&p->fmt_in, &d_w, &d_h);
- p->vsapi->propSetInt(vars, "video_in_dw", d_w, 0);
- p->vsapi->propSetInt(vars, "video_in_dh", d_h, 0);
+ p->vsapi->mapSetInt(vars, "video_in_dw", d_w, 0);
+ p->vsapi->mapSetInt(vars, "video_in_dh", d_h, 0);
struct mp_stream_info *info = mp_filter_find_stream_info(p->f);
double container_fps = input->nominal_fps;
@@ -696,9 +663,10 @@ static int reinit_vs(struct priv *p, struct mp_image *input)
display_res[1] = tmp[1];
}
}
- p->vsapi->propSetFloat(vars, "container_fps", container_fps, 0);
- p->vsapi->propSetFloat(vars, "display_fps", display_fps, 0);
- p->vsapi->propSetIntArray(vars, "display_res", display_res, 2);
+ p->vsapi->mapSetFloat(vars, "container_fps", container_fps, 0);
+ p->vsapi->mapSetFloat(vars, "display_fps", display_fps, 0);
+ p->vsapi->mapSetIntArray(vars, "display_res", display_res, 2);
+ p->vsapi->mapSetData(vars, "user_data", p->opts->user_data, -1, dtUtf8, 0);
if (p->drv->load(p, vars) < 0)
goto error;
@@ -707,8 +675,8 @@ static int reinit_vs(struct priv *p, struct mp_image *input)
goto error;
}
- const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node);
- if (!mp_from_vs(vi->format->id)) {
+ const VSVideoInfo *vi_out = p->vsapi->getVideoInfo(p->out_node);
+ if (!mp_from_vs(&vi_out->format)) {
MP_FATAL(p, "Unsupported output format.\n");
goto error;
}
@@ -720,8 +688,6 @@ static int reinit_vs(struct priv *p, struct mp_image *input)
res = 0;
error:
if (p->vsapi) {
- p->vsapi->freeMap(in);
- p->vsapi->freeMap(out);
p->vsapi->freeMap(vars);
}
if (res < 0)
@@ -798,9 +764,11 @@ static struct mp_filter *vf_vapoursynth_create(struct mp_filter *parent,
if (!conv)
goto error;
- for (int n = 0; mpvs_fmt_table[n].bits; n++) {
- int imgfmt = mp_from_vs(mpvs_fmt_table[n].vs);
- if (imgfmt)
+ for (int imgfmt = IMGFMT_START + 1; imgfmt < IMGFMT_END; imgfmt++) {
+ // due to the lack of access to VapourSynth at this point, the formats
+ // added to autoconvert is a superset of what's actually needed
+ struct mp_regular_imgfmt reg_fmt;
+ if (get_valid_mp_regular_imgfmt(&reg_fmt, imgfmt))
mp_autoconvert_add_imgfmt(conv, imgfmt, 0);
}
@@ -830,58 +798,56 @@ static const m_option_t vf_opts_fields[] = {
OPTDEF_INT(4)},
{"concurrent-frames", OPT_CHOICE(maxrequests, {"auto", -1}),
M_RANGE(1, 99), OPTDEF_INT(-1)},
+ {"user-data", OPT_STRING(user_data), OPTDEF_STR("")},
{0}
};
-#include <VSScript.h>
-
static int drv_vss_init(struct priv *p)
{
- if (!vsscript_init()) {
+ p->vs_script_api = getVSScriptAPI(VSSCRIPT_API_VERSION);
+ if (!p->vs_script_api) {
MP_FATAL(p, "Could not initialize VapourSynth scripting.\n");
return -1;
}
- p->vs_initialized = true;
return 0;
}
static void drv_vss_uninit(struct priv *p)
{
- if (p->vs_initialized)
- vsscript_finalize();
- p->vs_initialized = false;
+ p->vs_script_api = NULL;
}
static int drv_vss_load_core(struct priv *p)
{
// First load an empty script to get a VSScript, so that we get the vsapi
// and vscore.
- if (vsscript_createScript(&p->se))
+ p->vs_script = p->vs_script_api->createScript(NULL);
+ if (!p->vs_script)
return -1;
- p->vsapi = vsscript_getVSApi();
- p->vscore = vsscript_getCore(p->se);
+ p->vsapi = p->vs_script_api->getVSAPI(VAPOURSYNTH_API_VERSION);
+ p->vscore = p->vs_script_api->getCore(p->vs_script);
return 0;
}
static int drv_vss_load(struct priv *p, VSMap *vars)
{
- vsscript_setVariable(p->se, vars);
+ p->vs_script_api->setVariables(p->vs_script, vars);
- if (vsscript_evaluateFile(&p->se, p->script_path, 0)) {
- MP_FATAL(p, "Script evaluation failed:\n%s\n", vsscript_getError(p->se));
+ if (p->vs_script_api->evaluateFile(p->vs_script, p->script_path)) {
+ MP_FATAL(p, "Script evaluation failed:\n%s\n", p->vs_script_api->getError(p->vs_script));
return -1;
}
- p->out_node = vsscript_getOutput(p->se, 0);
+ p->out_node = p->vs_script_api->getOutputNode(p->vs_script, 0);
return 0;
}
static void drv_vss_unload(struct priv *p)
{
- if (p->se)
- vsscript_freeScript(p->se);
- p->se = NULL;
+ if (p->vs_script)
+ p->vs_script_api->freeScript(p->vs_script);
p->vsapi = NULL;
p->vscore = NULL;
+ p->vs_script = NULL;
}
static const struct script_driver drv_vss = {
diff --git a/video/image_writer.c b/video/image_writer.c
index 3c2d57a80f..d91e1e7b2c 100644
--- a/video/image_writer.c
+++ b/video/image_writer.c
@@ -75,12 +75,8 @@ const struct m_opt_choice_alternatives mp_image_writer_formats[] = {
{"jpeg", AV_CODEC_ID_MJPEG},
{"png", AV_CODEC_ID_PNG},
{"webp", AV_CODEC_ID_WEBP},
-#if HAVE_JPEGXL
{"jxl", AV_CODEC_ID_JPEGXL},
-#endif
-#if HAVE_AVIF_MUXER
{"avif", AV_CODEC_ID_AV1},
-#endif
{0}
};
@@ -95,15 +91,11 @@ const struct m_option image_writer_opts[] = {
{"webp-lossless", OPT_BOOL(webp_lossless)},
{"webp-quality", OPT_INT(webp_quality), M_RANGE(0, 100)},
{"webp-compression", OPT_INT(webp_compression), M_RANGE(0, 6)},
-#if HAVE_JPEGXL
{"jxl-distance", OPT_DOUBLE(jxl_distance), M_RANGE(0.0, 15.0)},
{"jxl-effort", OPT_INT(jxl_effort), M_RANGE(1, 9)},
-#endif
-#if HAVE_AVIF_MUXER
{"avif-encoder", OPT_STRING(avif_encoder)},
{"avif-opts", OPT_KEYVALUELIST(avif_opts)},
{"avif-pixfmt", OPT_STRING(avif_pixfmt)},
-#endif
{"high-bit-depth", OPT_BOOL(high_bit_depth)},
{"tag-colorspace", OPT_BOOL(tag_csp)},
{0},
@@ -210,13 +202,11 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp
AV_OPT_SEARCH_CHILDREN);
av_opt_set_int(avctx, "quality", ctx->opts->webp_quality,
AV_OPT_SEARCH_CHILDREN);
-#if HAVE_JPEGXL
} else if (codec->id == AV_CODEC_ID_JPEGXL) {
av_opt_set_double(avctx, "distance", ctx->opts->jxl_distance,
AV_OPT_SEARCH_CHILDREN);
av_opt_set_int(avctx, "effort", ctx->opts->jxl_effort,
AV_OPT_SEARCH_CHILDREN);
-#endif
}
if (avcodec_open2(avctx, codec, NULL) < 0) {
@@ -320,8 +310,6 @@ static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp
#endif
-#if HAVE_AVIF_MUXER
-
static void log_side_data(struct image_writer_ctx *ctx, AVPacketSideData *data,
size_t size)
{
@@ -500,8 +488,6 @@ free_data:
return success;
}
-#endif
-
static int get_encoder_format(const AVCodec *codec, int srcfmt, bool highdepth)
{
const enum AVPixelFormat *pix_fmts = codec->pix_fmts;
@@ -562,31 +548,17 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts)
bool image_writer_high_depth(const struct image_writer_opts *opts)
{
return opts->format == AV_CODEC_ID_PNG
-#if HAVE_JPEGXL
|| opts->format == AV_CODEC_ID_JPEGXL
-#endif
-#if HAVE_AVIF_MUXER
- || opts->format == AV_CODEC_ID_AV1
-#endif
- ;
+ || opts->format == AV_CODEC_ID_AV1;
}
bool image_writer_flexible_csp(const struct image_writer_opts *opts)
{
if (!opts->tag_csp)
return false;
- return false
-#if HAVE_JPEGXL
- || opts->format == AV_CODEC_ID_JPEGXL
-#endif
-#if HAVE_AVIF_MUXER
+ return opts->format == AV_CODEC_ID_JPEGXL
|| opts->format == AV_CODEC_ID_AV1
-#endif
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59, 58, 100)
- // This version added support for cICP tag writing
- || opts->format == AV_CODEC_ID_PNG
-#endif
- ;
+ || opts->format == AV_CODEC_ID_PNG;
}
int image_writer_format_from_ext(const char *ext)
@@ -700,14 +672,11 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts,
destfmt = IMGFMT_RGB24;
}
#endif
-#if HAVE_AVIF_MUXER
if (opts->format == AV_CODEC_ID_AV1) {
write = write_avif;
if (opts->avif_pixfmt && opts->avif_pixfmt[0])
destfmt = mp_imgfmt_from_name(bstr0(opts->avif_pixfmt));
- }
-#endif
- if (opts->format == AV_CODEC_ID_WEBP && !opts->webp_lossless) {
+ } else if (opts->format == AV_CODEC_ID_WEBP && !opts->webp_lossless) {
// For lossy images, libwebp has its own RGB->YUV conversion.
// We don't want that, so force YUV/YUVA here.
int alpha = image->fmt.flags & MP_IMGFLAG_ALPHA;
diff --git a/video/mp_image.c b/video/mp_image.c
index 609fb17bf0..a89762b6d5 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -21,6 +21,7 @@
#include <libavutil/mem.h>
#include <libavutil/common.h>
#include <libavutil/display.h>
+#include <libavutil/dovi_meta.h>
#include <libavutil/bswap.h>
#include <libavutil/hwcontext.h>
#include <libavutil/intreadwrite.h>
@@ -29,10 +30,6 @@
#include <libavutil/mastering_display_metadata.h>
#include <libplacebo/utils/libav.h>
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 16, 100)
-# include <libavutil/dovi_meta.h>
-#endif
-
#include "mpv_talloc.h"
#include "common/av_common.h"
@@ -1031,17 +1028,10 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
dst->params.crop.y1 = src->height - src->crop_bottom;
dst->fields = 0;
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 7, 100)
if (src->flags & AV_FRAME_FLAG_INTERLACED)
dst->fields |= MP_IMGFIELD_INTERLACED;
if (src->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)
dst->fields |= MP_IMGFIELD_TOP_FIRST;
-#else
- if (src->interlaced_frame)
- dst->fields |= MP_IMGFIELD_INTERLACED;
- if (src->top_field_first)
- dst->fields |= MP_IMGFIELD_TOP_FIRST;
-#endif
if (src->repeat_pict == 1)
dst->fields |= MP_IMGFIELD_REPEAT_FIRST;
@@ -1090,7 +1080,6 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
dst->a53_cc = sd->buf;
AVBufferRef *dovi = NULL;
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 16, 100)
sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_METADATA);
if (sd) {
#ifdef PL_HAVE_LAV_DOLBY_VISION
@@ -1116,12 +1105,9 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_RPU_BUFFER);
if (sd) {
-#ifdef PL_HAVE_LIBDOVI
pl_hdr_metadata_from_dovi_rpu(&dst->params.color.hdr, sd->buf->data,
sd->buf->size);
-#endif
}
-#endif
sd = av_frame_get_side_data(src, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
if (sd)
@@ -1189,17 +1175,10 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src)
dst->extended_data = dst->data;
dst->pict_type = src->pict_type;
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 7, 100)
if (src->fields & MP_IMGFIELD_INTERLACED)
dst->flags |= AV_FRAME_FLAG_INTERLACED;
if (src->fields & MP_IMGFIELD_TOP_FIRST)
dst->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
-#else
- if (src->fields & MP_IMGFIELD_INTERLACED)
- dst->interlaced_frame = 1;
- if (src->fields & MP_IMGFIELD_TOP_FIRST)
- dst->top_field_first = 1;
-#endif
if (src->fields & MP_IMGFIELD_REPEAT_FIRST)
dst->repeat_pict = 1;
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index b2910dba85..4b4250c565 100644
--- a/video/out/cocoa_cb_common.swift
+++ b/video/out/cocoa_cb_common.swift
@@ -135,7 +135,6 @@ class CocoaCB: Common, EventSubscriber {
case MAC_CSP_AUTO: return colorSpace
case MAC_CSP_DISPLAY_P3: return CGColorSpace(name: CGColorSpace.displayP3)
case MAC_CSP_DISPLAY_P3_HLG: return CGColorSpace(name: CGColorSpace.displayP3_HLG)
- case MAC_CSP_DISPLAY_P3_PQ: return CGColorSpace(name: CGColorSpace.displayP3_PQ)
case MAC_CSP_DCI_P3: return CGColorSpace(name: CGColorSpace.dcip3)
case MAC_CSP_BT_2020: return CGColorSpace(name: CGColorSpace.itur_2020)
case MAC_CSP_BT_709: return CGColorSpace(name: CGColorSpace.itur_709)
@@ -146,6 +145,15 @@ class CocoaCB: Common, EventSubscriber {
default: break
}
+#if HAVE_MACOS_10_15_4_FEATURES
+ if #available(macOS 10.15.4, *) {
+ switch outputCsp {
+ case MAC_CSP_DISPLAY_P3_PQ: return CGColorSpace(name: CGColorSpace.displayP3_PQ)
+ default: break
+ }
+ }
+#endif
+
#if HAVE_MACOS_11_FEATURES
if #available(macOS 11.0, *) {
switch outputCsp {
diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c
index f183ae8be5..488884eb53 100644
--- a/video/out/d3d11/context.c
+++ b/video/out/d3d11/context.c
@@ -99,8 +99,8 @@ struct priv {
struct pl_color_space swapchain_csp;
int64_t perf_freq;
- unsigned sync_refresh_count;
- int64_t sync_qpc_time;
+ unsigned last_sync_refresh_count;
+ int64_t last_sync_qpc_time;
int64_t vsync_duration_qpc;
int64_t last_submit_qpc;
};
@@ -156,8 +156,8 @@ static int d3d11_color_depth(struct ra_swapchain *sw)
struct priv *p = sw->priv;
DXGI_OUTPUT_DESC1 desc1;
- if (mp_get_dxgi_output_desc(p->swapchain, &desc1))
- return desc1.BitsPerColor;
+ if (!mp_get_dxgi_output_desc(p->swapchain, &desc1))
+ desc1.BitsPerColor = 0;
DXGI_SWAP_CHAIN_DESC desc;
@@ -165,15 +165,18 @@ static int d3d11_color_depth(struct ra_swapchain *sw)
if (FAILED(hr)) {
MP_ERR(sw->ctx, "Failed to query swap chain description: %s!\n",
mp_HRESULT_to_str(hr));
- return 0;
+ return desc1.BitsPerColor;
}
const struct ra_format *ra_fmt =
ra_d3d11_get_ra_format(sw->ctx->ra, desc.BufferDesc.Format);
- if (!ra_fmt)
- return 0;
+ if (!ra_fmt || !ra_fmt->component_depth[0])
+ return desc1.BitsPerColor;
+
+ if (!desc1.BitsPerColor)
+ return ra_fmt->component_depth[0];
- return ra_fmt->component_depth[0];
+ return MPMIN(ra_fmt->component_depth[0], desc1.BitsPerColor);
}
static bool d3d11_start_frame(struct ra_swapchain *sw, struct ra_fbo *out_fbo)