summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/command.c6
-rw-r--r--player/sub.c2
-rw-r--r--player/video.c8
-rw-r--r--video/decode/dec_video.c126
-rw-r--r--video/decode/dec_video.h5
-rw-r--r--video/filter/vf.c24
-rw-r--r--video/filter/vf.h4
7 files changed, 83 insertions, 92 deletions
diff --git a/player/command.c b/player/command.c
index 0bee671e88..f2f73059ef 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2512,8 +2512,8 @@ static int mp_property_vd_imgparams(void *ctx, struct m_property *prop,
if (!vd)
return M_PROPERTY_UNAVAILABLE;
struct mp_codec_params *c = vd->header->codec;
- if (vd->vfilter->override_params.imgfmt) {
- return property_imgparams(vd->vfilter->override_params, action, arg);
+ if (vd->vfilter->input_params.imgfmt) {
+ return property_imgparams(vd->vfilter->input_params, action, arg);
} else if (c->disp_w && c->disp_h) {
// Simplistic fallback for stupid scripts querying "width"/"height"
// before the first frame is decoded.
@@ -2779,7 +2779,7 @@ static int mp_property_aspect(void *ctx, struct m_property *prop,
if (mpctx->d_video && aspect <= 0) {
struct dec_video *d_video = mpctx->d_video;
struct mp_codec_params *c = d_video->header->codec;
- struct mp_image_params *params = &d_video->vfilter->override_params;
+ struct mp_image_params *params = &d_video->vfilter->input_params;
if (params && params->p_w > 0 && params->p_h > 0) {
int d_w, d_h;
mp_image_params_get_dsize(params, &d_w, &d_h);
diff --git a/player/sub.c b/player/sub.c
index 0492be4bc8..c20df53c60 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -78,7 +78,7 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts, int order
return true;
if (mpctx->d_video) {
- struct mp_image_params params = mpctx->d_video->vfilter->override_params;
+ struct mp_image_params params = mpctx->d_video->vfilter->input_params;
if (params.imgfmt)
sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, &params);
}
diff --git a/player/video.c b/player/video.c
index 33f3b4b970..9ec7eacb74 100644
--- a/player/video.c
+++ b/player/video.c
@@ -84,10 +84,10 @@ static int try_filter(struct MPContext *mpctx, struct mp_image_params params,
vf->label = talloc_strdup(vf, label);
- if (video_reconfig_filters(d_video, &params) < 0) {
+ if (vf_reconfig(d_video->vfilter, &params) < 0) {
vf_remove_filter(d_video->vfilter, vf);
// restore
- video_reconfig_filters(d_video, &params);
+ vf_reconfig(d_video->vfilter, &params);
return -1;
}
return 0;
@@ -107,7 +107,7 @@ static void filter_reconfig(struct MPContext *mpctx,
set_allowed_vo_formats(d_video->vfilter, mpctx->video_out);
- if (video_reconfig_filters(d_video, &params) < 0) {
+ if (vf_reconfig(d_video->vfilter, &params) < 0) {
// Most video filters don't work with hardware decoding, so this
// might be the reason why filter reconfig failed.
if (!probe_only &&
@@ -119,6 +119,8 @@ static void filter_reconfig(struct MPContext *mpctx,
mp_image_unrefp(&d_video->waiting_decoded_mpi);
d_video->decoder_output = (struct mp_image_params){0};
MP_VERBOSE(mpctx, "hwdec falback due to filters.\n");
+ } else {
+ MP_FATAL(mpctx, "Cannot initialize video filters.\n");
}
return;
}
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 821aa2bda4..772bab2f16 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -68,6 +68,7 @@ void video_reset_decoding(struct dec_video *d_video)
d_video->decoded_pts = MP_NOPTS_VALUE;
d_video->codec_pts = MP_NOPTS_VALUE;
d_video->codec_dts = MP_NOPTS_VALUE;
+ d_video->last_format = d_video->fixed_format = (struct mp_image_params){0};
}
int video_vd_control(struct dec_video *d_video, int cmd, void *arg)
@@ -209,6 +210,65 @@ bool video_init_best_codec(struct dec_video *d_video, char* video_decoders)
return !!d_video->vd_driver;
}
+static void fix_image_params(struct dec_video *d_video,
+ struct mp_image_params *params)
+{
+ struct MPOpts *opts = d_video->opts;
+ struct mp_image_params p = *params;
+ struct mp_codec_params *c = d_video->header->codec;
+
+ MP_VERBOSE(d_video, "Decoder format: %s\n", mp_image_params_to_str(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.
+ float dec_aspect = p.p_w > 0 && p.p_h > 0 ? p.p_w / (float)p.p_h : 0;
+ if (d_video->initial_decoder_aspect == 0)
+ d_video->initial_decoder_aspect = dec_aspect;
+
+ bool use_container = true;
+ switch (opts->aspect_method) {
+ case 0:
+ // We normally prefer the container aspect, unless the decoder aspect
+ // changes at least once.
+ if (dec_aspect > 0 && d_video->initial_decoder_aspect != dec_aspect) {
+ MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n");
+ // Even if the aspect switches back, don't use container aspect again.
+ d_video->initial_decoder_aspect = -1;
+ use_container = false;
+ }
+ break;
+ case 1:
+ use_container = false;
+ break;
+ }
+
+ if (use_container && c->par_w > 0 && c->par_h) {
+ MP_VERBOSE(d_video, "Using container aspect ratio.\n");
+ p.p_w = c->par_w;
+ p.p_h = c->par_h;
+ }
+
+ if (opts->movie_aspect >= 0) {
+ MP_VERBOSE(d_video, "Forcing user-set aspect ratio.\n");
+ if (opts->movie_aspect == 0) {
+ p.p_w = p.p_h = 1;
+ } else {
+ AVRational a = av_d2q(opts->movie_aspect, INT_MAX);
+ mp_image_params_set_dsize(&p, a.num, a.den);
+ }
+ }
+
+ // Assume square pixels if no aspect ratio is set at all.
+ if (p.p_w <= 0 || p.p_h <= 0)
+ p.p_w = p.p_h = 1;
+
+ // Detect colorspace from resolution.
+ mp_image_params_guess_csp(&p);
+
+ d_video->last_format = *params;
+ d_video->fixed_format = p;
+}
+
static void add_avi_pts(struct dec_video *d_video, double pts)
{
if (pts != MP_NOPTS_VALUE) {
@@ -329,72 +389,16 @@ struct mp_image *video_decode(struct dec_video *d_video,
if (d_video->num_codec_pts_problems || pkt_pts == MP_NOPTS_VALUE)
d_video->has_broken_packet_pts = 1;
+ if (!mp_image_params_equal(&d_video->last_format, &mpi->params))
+ fix_image_params(d_video, &mpi->params);
+
+ mpi->params = d_video->fixed_format;
+
mpi->pts = pts;
d_video->decoded_pts = pts;
return mpi;
}
-int video_reconfig_filters(struct dec_video *d_video,
- const struct mp_image_params *params)
-{
- struct MPOpts *opts = d_video->opts;
- struct mp_image_params p = *params;
- struct mp_codec_params *c = d_video->header->codec;
-
- // 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.
- float dec_aspect = p.p_w > 0 && p.p_h > 0 ? p.p_w / (float)p.p_h : 0;
- if (d_video->initial_decoder_aspect == 0)
- d_video->initial_decoder_aspect = dec_aspect;
-
- bool use_container = true;
- switch (opts->aspect_method) {
- case 0:
- // We normally prefer the container aspect, unless the decoder aspect
- // changes at least once.
- if (dec_aspect > 0 && d_video->initial_decoder_aspect != dec_aspect) {
- MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n");
- // Even if the aspect switches back, don't use container aspect again.
- d_video->initial_decoder_aspect = -1;
- use_container = false;
- }
- break;
- case 1:
- use_container = false;
- break;
- }
-
- if (use_container && c->par_w > 0 && c->par_h) {
- MP_VERBOSE(d_video, "Using container aspect ratio.\n");
- p.p_w = c->par_w;
- p.p_h = c->par_h;
- }
-
- if (opts->movie_aspect >= 0) {
- MP_VERBOSE(d_video, "Forcing user-set aspect ratio.\n");
- if (opts->movie_aspect == 0) {
- p.p_w = p.p_h = 1;
- } else {
- AVRational a = av_d2q(opts->movie_aspect, INT_MAX);
- mp_image_params_set_dsize(&p, a.num, a.den);
- }
- }
-
- // Assume square pixels if no aspect ratio is set at all.
- if (p.p_w <= 0 || p.p_h <= 0)
- p.p_w = p.p_h = 1;
-
- // Detect colorspace from resolution.
- mp_image_params_guess_csp(&p);
-
- if (vf_reconfig(d_video->vfilter, params, &p) < 0) {
- MP_FATAL(d_video, "Cannot initialize video filters.\n");
- return -1;
- }
-
- return 0;
-}
-
// Send a VCTRL, or if it doesn't work, translate it to a VOCTRL and try the VO.
int video_vf_vo_control(struct dec_video *d_video, int vf_cmd, void *data)
{
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index ad33d784f6..fe325806c6 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -69,6 +69,8 @@ struct dec_video {
double decoded_pts;
float fps; // FPS from demuxer or from user override
+
+ struct mp_image_params last_format, fixed_format;
float initial_decoder_aspect;
// State used only by player/video.c
@@ -90,9 +92,6 @@ int video_set_colors(struct dec_video *d_video, const char *item, int value);
void video_reset_decoding(struct dec_video *d_video);
int video_vd_control(struct dec_video *d_video, int cmd, void *arg);
-int video_reconfig_filters(struct dec_video *d_video,
- const struct mp_image_params *params);
-
int video_vf_vo_control(struct dec_video *d_video, int vf_cmd, void *data);
#endif /* MPLAYER_DEC_VIDEO_H */
diff --git a/video/filter/vf.c b/video/filter/vf.c
index dd5b560df3..35de0f23a7 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -211,13 +211,8 @@ void vf_print_filter_chain(struct vf_chain *c, int msglevel,
if (!mp_msg_test(c->log, msglevel))
return;
- char b[128] = {0};
-
- mp_snprintf_cat(b, sizeof(b), "%s", mp_image_params_to_str(&c->input_params));
- mp_msg(c->log, msglevel, " [vd] %s\n", b);
-
for (vf_instance_t *f = c->first; f; f = f->next) {
- b[0] = '\0';
+ char b[128] = {0};
mp_snprintf_cat(b, sizeof(b), " [%s] ", f->info->name);
mp_snprintf_cat(b, sizeof(b), "%s", mp_image_params_to_str(&f->fmt_out));
if (f->autoinserted)
@@ -392,7 +387,6 @@ int vf_filter_frame(struct vf_chain *c, struct mp_image *img)
return -1;
}
assert(mp_image_params_equal(&img->params, &c->input_params));
- vf_fix_img_params(img, &c->override_params);
return vf_do_filter(c->first, img);
}
@@ -585,10 +579,7 @@ static int vf_reconfig_wrapper(struct vf_instance *vf,
return r;
}
-// 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)
+int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params)
{
int r = 0;
vf_seek_reset(c);
@@ -599,9 +590,8 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params,
vf = next;
}
c->input_params = *params;
- c->first->fmt_in = *override_params;
- c->override_params = *override_params;
- struct mp_image_params cur = c->override_params;
+ c->first->fmt_in = *params;
+ struct mp_image_params cur = *params;
uint8_t unused[IMGFMT_END - IMGFMT_START];
update_formats(c, c->first, unused);
@@ -621,10 +611,8 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params,
MP_ERR(c, "Image formats incompatible or invalid.\n");
mp_msg(c->log, loglevel, "Video filter chain:\n");
vf_print_filter_chain(c, loglevel, failing);
- if (r < 0) {
- c->input_params = c->override_params = c->output_params =
- (struct mp_image_params){0};
- }
+ if (r < 0)
+ c->input_params = c->output_params = (struct mp_image_params){0};
return r;
}
diff --git a/video/filter/vf.h b/video/filter/vf.h
index 2e253b88e3..f828d4e735 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -111,7 +111,6 @@ 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];
@@ -149,8 +148,7 @@ 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,
- const struct mp_image_params *override_params);
+int vf_reconfig(struct vf_chain *c, const struct mp_image_params *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);