mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
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).
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user