diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/vd_lavc.c | 20 | ||||
-rw-r--r-- | video/filter/vf_vapoursynth.c | 270 | ||||
-rw-r--r-- | video/image_writer.c | 39 | ||||
-rw-r--r-- | video/mp_image.c | 23 | ||||
-rw-r--r-- | video/out/cocoa_cb_common.swift | 10 | ||||
-rw-r--r-- | video/out/d3d11/context.c | 42 | ||||
-rw-r--r-- | video/out/d3d11/ra_d3d11.c | 20 | ||||
-rw-r--r-- | video/out/drm_common.c | 3 | ||||
-rw-r--r-- | video/out/gpu/video.c | 20 | ||||
-rw-r--r-- | video/out/hwdec/hwdec_vaapi.c | 6 | ||||
-rw-r--r-- | video/out/opengl/context_x11egl.c | 1 | ||||
-rw-r--r-- | video/out/opengl/egl_helpers.c | 111 | ||||
-rw-r--r-- | video/out/vo.h | 2 | ||||
-rw-r--r-- | video/out/vo_sixel.c | 1 | ||||
-rw-r--r-- | video/out/vo_tct.c | 2 | ||||
-rw-r--r-- | video/out/vo_vaapi.c | 16 | ||||
-rw-r--r-- | video/out/vulkan/context.c | 5 | ||||
-rw-r--r-- | video/out/w32_common.c | 10 | ||||
-rw-r--r-- | video/out/wayland_common.c | 171 | ||||
-rw-r--r-- | video/out/x11_common.c | 36 | ||||
-rw-r--r-- | video/out/x11_common.h | 2 | ||||
-rw-r--r-- | video/sws_utils.c | 13 |
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(®_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(®_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(®_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) |