From 391261f7576ff2abc738cf8d566bdc8aad267f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Sat, 10 Feb 2024 23:46:04 +0100 Subject: [PATCH] mp_image: add mp_image_params_static_equal for finer comparision In case of dynamic HDR metadata is present. --- filters/f_autoconvert.c | 2 +- filters/f_decoder_wrapper.c | 21 ++++++++++++++------- filters/f_output_chain.c | 30 ++++++++++++++++-------------- player/video.c | 10 +--------- video/filter/refqueue.c | 2 +- video/filter/vf_gpu.c | 6 ++++-- video/mp_image.c | 11 +++++++++++ video/mp_image.h | 2 ++ video/out/gpu/video.c | 4 ++-- video/out/vo_gpu_next.c | 6 +++++- video/vdpau_mixer.c | 2 +- 11 files changed, 58 insertions(+), 38 deletions(-) diff --git a/filters/f_autoconvert.c b/filters/f_autoconvert.c index dcd5ea2485..aaea7fe4f1 100644 --- a/filters/f_autoconvert.c +++ b/filters/f_autoconvert.c @@ -157,7 +157,7 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log, */ if (samefmt && samesubffmt) { if (p->imgparams_set) { - if (!mp_image_params_equal(&p->imgparams, &img->params)) + if (!mp_image_params_static_equal(&p->imgparams, &img->params)) break; } return true; diff --git a/filters/f_decoder_wrapper.c b/filters/f_decoder_wrapper.c index e85463ce90..ba867621c5 100644 --- a/filters/f_decoder_wrapper.c +++ b/filters/f_decoder_wrapper.c @@ -551,31 +551,36 @@ void mp_decoder_wrapper_set_play_dir(struct mp_decoder_wrapper *d, int dir) } static void fix_image_params(struct priv *p, - struct mp_image_params *params) + struct mp_image_params *params, + bool quiet) { struct mp_image_params m = *params; struct mp_codec_params *c = p->codec; struct dec_wrapper_opts *opts = p->opts; - MP_VERBOSE(p, "Decoder format: %s\n", mp_image_params_to_str(params)); + if (!quiet) + MP_VERBOSE(p, "Decoder format: %s\n", mp_image_params_to_str(params)); p->dec_format = *params; // While mp_image_params normally always have to have d_w/d_h set, the // decoder signals unknown bitstream aspect ratio with both set to 0. bool use_container = true; if (opts->aspect_method == 1 && m.p_w > 0 && m.p_h > 0) { - MP_VERBOSE(p, "Using bitstream aspect ratio.\n"); + if (!quiet) + MP_VERBOSE(p, "Using bitstream aspect ratio.\n"); use_container = false; } if (use_container && c->par_w > 0 && c->par_h) { - MP_VERBOSE(p, "Using container aspect ratio.\n"); + if (!quiet) + MP_VERBOSE(p, "Using container aspect ratio.\n"); m.p_w = c->par_w; m.p_h = c->par_h; } if (opts->movie_aspect >= 0) { - MP_VERBOSE(p, "Forcing user-set aspect ratio.\n"); + if (!quiet) + MP_VERBOSE(p, "Forcing user-set aspect ratio.\n"); if (opts->movie_aspect == 0) { m.p_w = m.p_h = 1; } else { @@ -819,8 +824,10 @@ static void process_output_frame(struct priv *p, struct mp_frame frame) correct_video_pts(p, mpi); - if (!mp_image_params_equal(&p->last_format, &mpi->params)) - fix_image_params(p, &mpi->params); + if (!mp_image_params_equal(&p->last_format, &mpi->params)) { + fix_image_params(p, &mpi->params, + mp_image_params_static_equal(&p->last_format, &mpi->params)); + } mpi->params = p->fixed_format; mpi->nominal_fps = p->fps; diff --git a/filters/f_output_chain.c b/filters/f_output_chain.c index ffad932a57..6c14ebc12b 100644 --- a/filters/f_output_chain.c +++ b/filters/f_output_chain.c @@ -100,27 +100,29 @@ static void check_in_format_change(struct mp_user_filter *u, struct mp_image *img = frame.data; if (!mp_image_params_equal(&img->params, &u->last_in_vformat)) { - MP_VERBOSE(p, "[%s] %s\n", u->name, - mp_image_params_to_str(&img->params)); - u->last_in_vformat = img->params; - if (u == p->input) { p->public.input_params = img->params; } else if (u == p->output) { p->public.output_params = img->params; } - // Unfortunately there's no good place to update these. - // But a common case is enabling HW decoding, which - // might init some support of them in the VO, and update - // the VO's format list. - // - // But as this is only relevant to the "convert" filter, don't - // do this for the other filters as it is wasted work. - if (strcmp(u->name, "convert") == 0) - update_output_caps(p); + if (!mp_image_params_static_equal(&img->params, &u->last_in_vformat)) { + MP_VERBOSE(p, "[%s] %s\n", u->name, + mp_image_params_to_str(&img->params)); - p->public.reconfig_happened = true; + // Unfortunately there's no good place to update these. + // But a common case is enabling HW decoding, which + // might init some support of them in the VO, and update + // the VO's format list. + // + // But as this is only relevant to the "convert" filter, don't + // do this for the other filters as it is wasted work. + if (strcmp(u->name, "convert") == 0) + update_output_caps(p); + + p->public.reconfig_happened = true; + } + u->last_in_vformat = img->params; } } diff --git a/player/video.c b/player/video.c index 908299baa1..777460dcea 100644 --- a/player/video.c +++ b/player/video.c @@ -1043,14 +1043,6 @@ static void apply_video_crop(struct MPContext *mpctx, struct vo *vo) } } -static bool video_reconfig_needed(struct mp_image_params a, - struct mp_image_params b) -{ - a.color.hdr = (struct pl_hdr_metadata){0}; - b.color.hdr = (struct pl_hdr_metadata){0}; - return !mp_image_params_equal(&a, &b); -} - void write_video(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -1173,7 +1165,7 @@ void write_video(struct MPContext *mpctx) // Filter output is different from VO input? struct mp_image_params *p = &mpctx->next_frames[0]->params; - if (!vo->params || video_reconfig_needed(*p, *vo->params)) { + if (!vo->params || !mp_image_params_static_equal(p, vo->params)) { // Changing config deletes the current frame; wait until it's finished. if (vo_still_displaying(vo)) { vo_request_wakeup_on_done(vo); diff --git a/video/filter/refqueue.c b/video/filter/refqueue.c index 3cfe3c61ff..f5124087c6 100644 --- a/video/filter/refqueue.c +++ b/video/filter/refqueue.c @@ -333,7 +333,7 @@ bool mp_refqueue_can_output(struct mp_refqueue *q) if (!q->in_format || !!q->in_format->hwctx != !!img->hwctx || (img->hwctx && img->hwctx->data != q->in_format->hwctx->data) || - !mp_image_params_equal(&q->in_format->params, &img->params)) + !mp_image_params_static_equal(&q->in_format->params, &img->params)) { q->next = img; q->eof = true; diff --git a/video/filter/vf_gpu.c b/video/filter/vf_gpu.c index dba4b3204f..e19faaef42 100644 --- a/video/filter/vf_gpu.c +++ b/video/filter/vf_gpu.c @@ -166,12 +166,14 @@ static struct mp_image *gpu_render_frame(struct mp_filter *f, struct mp_image *i bool need_reconfig = m_config_cache_update(priv->vo_opts_cache); - if (!mp_image_params_equal(&priv->img_params, &in->params)) { - priv->img_params = in->params; + if (!mp_image_params_static_equal(&priv->img_params, &in->params)) { gl_video_config(priv->renderer, &in->params); need_reconfig = true; } + if (!mp_image_params_equal(&priv->img_params, &in->params)) + priv->img_params = in->params; + if (need_reconfig) { struct mp_rect src, dst; struct mp_osd_res osd; diff --git a/video/mp_image.c b/video/mp_image.c index f9decfa579..33a784741f 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -844,6 +844,17 @@ bool mp_image_params_equal(const struct mp_image_params *p1, mp_rect_equals(&p1->crop, &p2->crop); } +bool mp_image_params_static_equal(const struct mp_image_params *p1, + const struct mp_image_params *p2) +{ + // Compare only static video parameters, excluding dynamic metadata. + struct mp_image_params a = *p1; + struct mp_image_params b = *p2; + a.repr.dovi = b.repr.dovi = NULL; + a.color.hdr = b.color.hdr = (struct pl_hdr_metadata){0}; + return mp_image_params_equal(&a, &b); +} + // Set most image parameters, but not image format or size. // Display size is used to set the PAR. void mp_image_set_attributes(struct mp_image *image, diff --git a/video/mp_image.h b/video/mp_image.h index 9658efd433..3a6130a24d 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -177,6 +177,8 @@ bool mp_image_crop_valid(const struct mp_image_params *p); bool mp_image_params_valid(const struct mp_image_params *p); bool mp_image_params_equal(const struct mp_image_params *p1, const struct mp_image_params *p2); +bool mp_image_params_static_equal(const struct mp_image_params *p1, + const struct mp_image_params *p2); void mp_image_params_get_dsize(const struct mp_image_params *p, int *d_w, int *d_h); diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 1de9ae8cd5..fe6ec1cdde 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -3193,7 +3193,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t, struct mp_image *f = t->frames[i]; uint64_t f_id = t->frame_id + i; - if (!mp_image_params_equal(&f->params, &p->real_image_params)) + if (!mp_image_params_static_equal(&f->params, &p->real_image_params)) continue; if (f_id > p->surfaces[p->surface_idx].id) { @@ -4016,7 +4016,7 @@ void gl_video_config(struct gl_video *p, struct mp_image_params *params) unmap_overlay(p); unref_current_image(p); - if (!mp_image_params_equal(&p->real_image_params, params)) { + if (!mp_image_params_static_equal(&p->real_image_params, params)) { uninit_video(p); p->real_image_params = *params; p->image_params = *params; diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 8fb24c39b1..0139cfd3e1 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -494,7 +494,11 @@ static bool hwdec_reconfig(struct priv *p, struct ra_hwdec *hwdec, const struct mp_image_params *par) { if (p->hwdec_mapper) { - if (mp_image_params_equal(par, &p->hwdec_mapper->src_params)) { + if (mp_image_params_static_equal(par, &p->hwdec_mapper->src_params)) { + p->hwdec_mapper->src_params.repr.dovi = par->repr.dovi; + p->hwdec_mapper->dst_params.repr.dovi = par->repr.dovi; + p->hwdec_mapper->src_params.color.hdr = par->color.hdr; + p->hwdec_mapper->dst_params.color.hdr = par->color.hdr; return p->hwdec_mapper; } else { ra_hwdec_mapper_free(&p->hwdec_mapper); diff --git a/video/vdpau_mixer.c b/video/vdpau_mixer.c index 5adb3b4ec3..e062dcc06c 100644 --- a/video/vdpau_mixer.c +++ b/video/vdpau_mixer.c @@ -277,7 +277,7 @@ int mp_vdpau_mixer_render(struct mp_vdpau_mixer *mixer, CHECK_VDP_ERROR(mixer, "Error when calling vdp_video_surface_get_parameters"); if (!mixer->initialized || !opts_equal(opts, &mixer->opts) || - !mp_image_params_equal(&video->params, &mixer->image_params) || + !mp_image_params_static_equal(&video->params, &mixer->image_params) || mixer->current_w != s_w || mixer->current_h != s_h || mixer->current_chroma_type != s_chroma_type) {