mp_image: add mp_image_params_static_equal for finer comparision

In case of dynamic HDR metadata is present.
This commit is contained in:
Kacper Michajłow 2024-02-10 23:46:04 +01:00 committed by Dudemanguy
parent 120b0ac412
commit 391261f757
11 changed files with 58 additions and 38 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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)
{