summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-14 00:18:31 +0100
committerwm4 <wm4@nowhere>2016-01-14 00:18:31 +0100
commitbf13bd0d47e5fc6761c51c6ba7056968e60bf4cd (patch)
treea031821a03564128a5e0dabb0a33361fd56b0e07 /video
parentdd973da108165ebb95e856dbc82326cb35fb45a5 (diff)
downloadmpv-bf13bd0d47e5fc6761c51c6ba7056968e60bf4cd.tar.bz2
mpv-bf13bd0d47e5fc6761c51c6ba7056968e60bf4cd.tar.xz
video: refactor: handle video format fixups closer to decoder
Instead of handling this on filter chain reinit, do it directly after the decoder. This makes the code less entangled. In particular, this gets rid of the really weird "override params" concept in the video filter code. The last_format/fixed_formats have some redundance with decoder_output, but unfortunately the latter has a slightly different use.
Diffstat (limited to 'video')
-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
4 files changed, 74 insertions, 85 deletions
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);