From 50ebcf1a432c4be5e458111b6915130424e56872 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 1 May 2014 23:15:50 +0200 Subject: video: handle colorspace and aspect overrides separately Now the video filter code handles these explicitly, which should increase robustness (or at least find bugs earlier). --- player/command.c | 6 +++--- player/sub.c | 3 ++- player/video.c | 1 - video/decode/dec_video.c | 4 ++-- video/filter/vf.c | 25 +++++++++++++++++++------ video/filter/vf.h | 4 +++- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/player/command.c b/player/command.c index 4d0473f4c2..ffe7a98261 100644 --- a/player/command.c +++ b/player/command.c @@ -1880,8 +1880,8 @@ static int mp_property_vd_imgparams(m_option_t *prop, int action, void *arg, if (!vd) return M_PROPERTY_UNAVAILABLE; struct sh_video *sh = vd->header->video; - if (vd->vf_input.imgfmt) { - return property_imgparams(vd->vf_input, action, arg); + if (vd->vfilter->override_params.imgfmt) { + return property_imgparams(vd->vfilter->override_params, action, arg); } else if (sh->disp_w && sh->disp_h) { // Simplistic fallback for stupid scripts querying "width"/"height" // before the first frame is decoded. @@ -1976,7 +1976,7 @@ static int mp_property_aspect(m_option_t *prop, int action, void *arg, } case M_PROPERTY_GET: { float aspect = -1; - struct mp_image_params *params = &d_video->vf_input; + struct mp_image_params *params = &d_video->vfilter->override_params; if (params && params->d_w && params->d_h) { aspect = (float)params->d_w / params->d_h; } else if (sh_video->disp_w && sh_video->disp_h) { diff --git a/player/sub.c b/player/sub.c index 00b2260c67..883ffa0dbf 100644 --- a/player/sub.c +++ b/player/sub.c @@ -34,6 +34,7 @@ #include "demux/demux.h" #include "video/mp_image.h" #include "video/decode/dec_video.h" +#include "video/filter/vf.h" #include "core.h" @@ -92,7 +93,7 @@ static void update_subtitle(struct MPContext *mpctx, int order) int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB; if (mpctx->d_video) { - struct mp_image_params params = mpctx->d_video->vf_input; + struct mp_image_params params = mpctx->d_video->vfilter->override_params; if (params.imgfmt) sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, ¶ms); } diff --git a/player/video.c b/player/video.c index b995ed2575..7679348243 100644 --- a/player/video.c +++ b/player/video.c @@ -366,7 +366,6 @@ static void filter_video(struct MPContext *mpctx, struct mp_image *frame, return; } - mp_image_set_params(frame, &d_video->vf_input); // force csp/aspect overrides vf_filter_frame(d_video->vfilter, frame); filter_output_queued_frame(mpctx, false); } diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index 7ade93b577..b59ded7ac3 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -431,12 +431,12 @@ int video_reconfig_filters(struct dec_video *d_video, MP_VERBOSE(d_video, "VO Config (%dx%d->%dx%d,0x%X)\n", p.w, p.h, p.d_w, p.d_h, p.imgfmt); - if (vf_reconfig(d_video->vfilter, &p) < 0) { + if (vf_reconfig(d_video->vfilter, params, &p) < 0) { MP_FATAL(d_video, "Cannot initialize video filters.\n"); return -1; } - d_video->vf_input = p; + d_video->vf_input = *params; return 0; } diff --git a/video/filter/vf.c b/video/filter/vf.c index 08391290a3..a812ba8136 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -245,6 +245,9 @@ void vf_print_filter_chain(struct vf_chain *c, int msglevel) if (!mp_msg_test(c->log, msglevel)) return; + mp_msg(c->log, msglevel, " [vd] "); + print_fmt(c->log, msglevel, &c->input_params); + mp_msg(c->log, msglevel, "\n"); for (vf_instance_t *f = c->first; f; f = f->next) { mp_msg(c->log, msglevel, " [%s] ", f->info->name); print_fmt(c->log, msglevel, &f->fmt_out); @@ -404,7 +407,8 @@ int vf_filter_frame(struct vf_chain *c, struct mp_image *img) talloc_free(img); return -1; } - vf_fix_img_params(img, &c->input_params); + assert(mp_image_params_equals(&img->params, &c->input_params)); + vf_fix_img_params(img, &c->override_params); return vf_do_filter(c->first, img); } @@ -583,9 +587,11 @@ static int vf_reconfig_wrapper(struct vf_instance *vf, return r; } -int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params) +// override_params is used to forcibly change the parameters of input images, +// while params has to match the input images exactly. +int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params, + const struct mp_image_params *override_params) { - struct mp_image_params cur = *params; int r = 0; vf_chain_forget_frames(c); for (struct vf_instance *vf = c->first; vf; ) { @@ -594,7 +600,11 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params) vf_remove_filter(c, vf); vf = next; } - c->first->fmt_in = *params; + c->input_params = *params; + c->first->fmt_in = *override_params; + c->override_params = *override_params; + struct mp_image_params cur = c->override_params; + uint8_t unused[IMGFMT_END - IMGFMT_START]; update_formats(c, c->first, unused); for (struct vf_instance *vf = c->first; vf; vf = vf->next) { @@ -603,14 +613,17 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params) break; cur = vf->fmt_out; } - c->input_params = r < 0 ? (struct mp_image_params){0} : *params; - c->output_params = r < 0 ? (struct mp_image_params){0} : cur; + c->output_params = cur; c->initialized = r < 0 ? -1 : 1; int loglevel = r < 0 ? MSGL_WARN : MSGL_V; if (r == -2) MP_ERR(c, "Image formats incompatible.\n"); mp_msg(c->log, loglevel, "Video filter chain:\n"); vf_print_filter_chain(c, loglevel); + if (r < 0) { + c->input_params = c->override_params = c->output_params = + (struct mp_image_params){0}; + } return r; } diff --git a/video/filter/vf.h b/video/filter/vf.h index 399e3f1e42..5773d36105 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -103,6 +103,7 @@ struct vf_chain { struct vf_instance *first, *last; struct mp_image_params input_params; + struct mp_image_params override_params; // input to first filter struct mp_image_params output_params; uint8_t allowed_output_formats[IMGFMT_END - IMGFMT_START]; @@ -135,7 +136,8 @@ enum vf_ctrl { struct vf_chain *vf_new(struct mpv_global *global); void vf_destroy(struct vf_chain *c); -int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params); +int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params, + const struct mp_image_params *override_params); int vf_control_any(struct vf_chain *c, int cmd, void *arg); int vf_control_by_label(struct vf_chain *c, int cmd, void *arg, bstr label); int vf_filter_frame(struct vf_chain *c, struct mp_image *img); -- cgit v1.2.3