summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-12-19 20:04:31 +0100
committerwm4 <wm4@nowhere>2015-12-19 20:45:36 +0100
commit0a0bb9059f42671c267ea5d0c8faa3ac71a8c742 (patch)
tree89cbdee7748d36f98cc5d0efbfc8a3fc810b2016 /video
parent1f7c099dc0feb9a160d9018ad6ad068e0295341a (diff)
downloadmpv-0a0bb9059f42671c267ea5d0c8faa3ac71a8c742.tar.bz2
mpv-0a0bb9059f42671c267ea5d0c8faa3ac71a8c742.tar.xz
video: switch from using display aspect to sample aspect
MPlayer traditionally always used the display aspect ratio, e.g. 16:9, while FFmpeg uses the sample (aka pixel) aspect ratio. Both have a bunch of advantages and disadvantages. Actually, it seems using sample aspect ratio is generally nicer. The main reason for the change is making mpv closer to how FFmpeg works in order to make life easier. It's also nice that everything uses integer fractions instead of floats now (except --video-aspect option/property). Note that there is at least 1 user-visible change: vf_dsize now does not set the display size, only the display aspect ratio. This is because the image_params d_w/d_h fields did not just set the display aspect, but also the size (except in encoding mode).
Diffstat (limited to 'video')
-rw-r--r--video/decode/dec_video.c30
-rw-r--r--video/decode/vd_lavc.c8
-rw-r--r--video/filter/vf.c25
-rw-r--r--video/filter/vf.h6
-rw-r--r--video/filter/vf_crop.c6
-rw-r--r--video/filter/vf_dlopen.c9
-rw-r--r--video/filter/vf_dsize.c7
-rw-r--r--video/filter/vf_expand.c5
-rw-r--r--video/filter/vf_format.c12
-rw-r--r--video/filter/vf_lavfi.c41
-rw-r--r--video/filter/vf_scale.c8
-rw-r--r--video/filter/vf_sub.c12
-rw-r--r--video/filter/vf_vapoursynth.c7
-rw-r--r--video/image_writer.c4
-rw-r--r--video/mp_image.c43
-rw-r--r--video/mp_image.h6
-rw-r--r--video/out/aspect.c8
-rw-r--r--video/out/vo.c3
-rw-r--r--video/out/vo_drm.c4
-rw-r--r--video/out/vo_lavc.c9
-rw-r--r--video/out/vo_wayland.c4
-rw-r--r--video/out/vo_x11.c4
-rw-r--r--video/out/win_state.c6
-rw-r--r--video/sws_utils.c4
-rw-r--r--video/vdpau.c4
25 files changed, 109 insertions, 166 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 509daf7cd8..9409ce146f 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -15,14 +15,15 @@
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-#include "options/options.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
+#include <libavutil/rational.h>
+
+#include "config.h"
+#include "options/options.h"
#include "common/msg.h"
#include "osdep/timer.h"
@@ -342,7 +343,7 @@ int video_reconfig_filters(struct dec_video *d_video,
// 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.d_w > 0 && p.d_h > 0 ? p.d_w / (float)p.d_h : 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;
@@ -363,22 +364,25 @@ int video_reconfig_filters(struct dec_video *d_video,
break;
}
- if (use_container && sh->aspect > 0) {
+ if (use_container && sh->par_w > 0 && sh->par_h) {
MP_VERBOSE(d_video, "Using container aspect ratio.\n");
- vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect);
+ p.p_w = sh->par_w;
+ p.p_h = sh->par_h;
}
- float force_aspect = opts->movie_aspect;
- if (force_aspect >= 0.0) {
+ if (opts->movie_aspect >= 0) {
MP_VERBOSE(d_video, "Forcing user-set aspect ratio.\n");
- vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
+ 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.d_w <= 0 || p.d_h <= 0) {
- p.d_w = p.w;
- p.d_h = p.h;
- }
+ 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);
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 92ea8bd0d8..89fa21c4e1 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -484,7 +484,6 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
struct MPOpts *opts = ctx->opts;
int width = frame->width;
int height = frame->height;
- float aspect = av_q2d(frame->sample_aspect_ratio) * width / height;
int pix_fmt = frame->format;
if (pix_fmt != ctx->pix_fmt) {
@@ -499,8 +498,8 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
.imgfmt = ctx->best_csp,
.w = width,
.h = height,
- .d_w = 0,
- .d_h = 0,
+ .p_w = frame->sample_aspect_ratio.num,
+ .p_h = frame->sample_aspect_ratio.den,
.colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
.colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
.primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries),
@@ -511,9 +510,6 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
.stereo_in = vd->header->video->stereo_mode,
};
- if (aspect > 0)
- vf_set_dar(&out_params->d_w, &out_params->d_h, width, height, aspect);
-
if (opts->video_rotate < 0) {
out_params->rotate = 0;
} else {
diff --git a/video/filter/vf.c b/video/filter/vf.c
index c5d11ef222..dd5b560df3 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -700,28 +700,3 @@ void vf_destroy(struct vf_chain *c)
vf_chain_forget_frames(c);
talloc_free(c);
}
-
-// When changing the size of an image that had old_w/old_h with
-// DAR *d_width/*d_height to the new size new_w/new_h, adjust
-// *d_width/*d_height such that the new image has the same pixel aspect ratio.
-void vf_rescale_dsize(int *d_width, int *d_height, int old_w, int old_h,
- int new_w, int new_h)
-{
- *d_width = *d_width * new_w / old_w;
- *d_height = *d_height * new_h / old_h;
-}
-
-// Set *d_width/*d_height to display aspect ratio with the givem source size
-void vf_set_dar(int *d_w, int *d_h, int w, int h, double dar)
-{
- *d_w = w;
- *d_h = h;
- if (dar > 0.01) {
- *d_w = h * dar + 0.5;
- // we don't like horizontal downscale
- if (*d_w < w) {
- *d_w = w;
- *d_h = w / dar + 0.5;
- }
- }
-}
diff --git a/video/filter/vf.h b/video/filter/vf.h
index 2bca682fbc..2e253b88e3 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -174,10 +174,4 @@ void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img);
// default wrappers:
int vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
-// Helpers
-
-void vf_rescale_dsize(int *d_width, int *d_height, int old_w, int old_h,
- int new_w, int new_h);
-void vf_set_dar(int *d_width, int *d_height, int w, int h, double dar);
-
#endif /* MPLAYER_VF_H */
diff --git a/video/filter/vf_crop.c b/video/filter/vf_crop.c
index 79e915fd4a..89b2b6fde1 100644
--- a/video/filter/vf_crop.c
+++ b/video/filter/vf_crop.c
@@ -42,7 +42,7 @@ static const struct vf_priv_s {
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
- int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h;
+ int width = in->w, height = in->h;
// calculate the missing parameters:
if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width;
@@ -63,13 +63,9 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
return -1;
}
- vf_rescale_dsize(&d_width, &d_height, width, height,
- vf->priv->crop_w, vf->priv->crop_h);
*out = *in;
out->w = vf->priv->crop_w;
out->h = vf->priv->crop_h;
- out->d_w = d_width;
- out->d_h = d_height;
return 0;
}
diff --git a/video/filter/vf_dlopen.c b/video/filter/vf_dlopen.c
index 7cf04ca428..bd85583a96 100644
--- a/video/filter/vf_dlopen.c
+++ b/video/filter/vf_dlopen.c
@@ -93,10 +93,11 @@ static void set_imgprop(struct vf_dlopen_picdata *out, const mp_image_t *mpi)
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
+ mp_image_params_get_dsize(in, &vf->priv->filter.in_d_width,
+ &vf->priv->filter.in_d_height);
+
vf->priv->filter.in_width = in->w;
vf->priv->filter.in_height = in->h;
- vf->priv->filter.in_d_width = in->d_w;
- vf->priv->filter.in_d_height = in->d_h;
vf->priv->filter.in_fmt = talloc_strdup(vf, mp_imgfmt_to_name(in->imgfmt));
vf->priv->filter.out_width = vf->priv->filter.in_width;
vf->priv->filter.out_height = vf->priv->filter.in_height;
@@ -164,8 +165,8 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
*out = *in;
out->w = vf->priv->out_width;
out->h = vf->priv->out_height;
- out->d_w = vf->priv->filter.out_d_width;
- out->d_h = vf->priv->filter.out_d_height;
+ mp_image_params_set_dsize(out, vf->priv->filter.out_d_width,
+ vf->priv->filter.out_d_height);
out->imgfmt = vf->priv->outfmt;
return 0;
}
diff --git a/video/filter/vf_dsize.c b/video/filter/vf_dsize.c
index eafcaf3472..b498b317f6 100644
--- a/video/filter/vf_dsize.c
+++ b/video/filter/vf_dsize.c
@@ -39,7 +39,9 @@ struct vf_priv_s {
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
- int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h;
+ int width = in->w, height = in->h;
+ int d_width, d_height;
+ mp_image_params_get_dsize(in, &d_width, &d_height);
int w = vf->priv->w;
int h = vf->priv->h;
if (vf->priv->aspect < 0.001) { // did the user input aspect or w,h params
@@ -75,8 +77,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
}
}
*out = *in;
- out->d_w = d_width;
- out->d_h = d_height;
+ mp_image_params_set_dsize(out, d_width, d_height);
return 0;
}
diff --git a/video/filter/vf_expand.c b/video/filter/vf_expand.c
index 69574efff3..a788568e14 100644
--- a/video/filter/vf_expand.c
+++ b/video/filter/vf_expand.c
@@ -72,7 +72,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
else if( vf->priv->exp_h<height ) vf->priv->exp_h=height;
if (vf->priv->aspect) {
float adjusted_aspect = vf->priv->aspect;
- adjusted_aspect *= ((double)width/height) / ((double)in->d_w/in->d_h);
+ adjusted_aspect *= (double)in->p_w/in->p_h;
if (vf->priv->exp_h < vf->priv->exp_w / adjusted_aspect) {
vf->priv->exp_h = vf->priv->exp_w / adjusted_aspect + 0.5;
} else {
@@ -96,9 +96,6 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
out->w = vf->priv->exp_w;
out->h = vf->priv->exp_h;
- vf_rescale_dsize(&out->d_w, &out->d_h, width, height,
- vf->priv->exp_w, vf->priv->exp_h);
-
return 0;
}
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index 83d697b412..ff7389cb7a 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -20,6 +20,8 @@
#include <string.h>
#include <inttypes.h>
+#include <libavutil/rational.h>
+
#include "common/msg.h"
#include "common/common.h"
@@ -100,12 +102,16 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
out->stereo_out = p->stereo_out;
if (p->rotate >= 0)
out->rotate = p->rotate;
+
+ AVRational dsize;
+ mp_image_params_get_dsize(out, &dsize.num, &dsize.den);
if (p->dw > 0)
- out->d_w = p->dw;
+ dsize.num = p->dw;
if (p->dh > 0)
- out->d_h = p->dh;
+ dsize.den = p->dh;
if (p->dar > 0)
- vf_set_dar(&out->d_w, &out->d_h, out->w, out->h, p->dar);
+ dsize = av_d2q(p->dar, INT_MAX);
+ mp_image_params_set_dsize(out, dsize.num, dsize.den);
// Make sure the user-overrides are consistent (no RGB csp for YUV, etc.).
mp_image_params_guess_csp(out);
diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c
index a64738d355..16aeb52338 100644
--- a/video/filter/vf_lavfi.c
+++ b/video/filter/vf_lavfi.c
@@ -103,30 +103,7 @@ static void destroy_graph(struct vf_instance *vf)
p->eof = false;
}
-static AVRational par_from_sar_dar(int width, int height,
- int d_width, int d_height)
-{
- return av_div_q((AVRational){d_width, d_height},
- (AVRational){width, height});
-}
-
-static void dar_from_sar_par(int width, int height, AVRational par,
- int *out_dw, int *out_dh)
-{
- *out_dw = width;
- *out_dh = height;
- if (par.num != 0 && par.den != 0) {
- double d = av_q2d(par);
- if (d > 1.0) {
- *out_dw = floor(*out_dw * d + 0.5);
- } else {
- *out_dh = floor(*out_dh / d + 0.5);
- }
- }
-}
-
-static bool recreate_graph(struct vf_instance *vf, int width, int height,
- int d_width, int d_height, unsigned int fmt)
+static bool recreate_graph(struct vf_instance *vf, struct mp_image_params *fmt)
{
void *tmp = talloc_new(NULL);
struct vf_priv_s *p = vf->priv;
@@ -168,13 +145,12 @@ static bool recreate_graph(struct vf_instance *vf, int width, int height,
char *sws_flags = talloc_asprintf(tmp, "flags=%"PRId64, p->cfg_sws_flags);
graph->scale_sws_opts = av_strdup(sws_flags);
- AVRational par = par_from_sar_dar(width, height, d_width, d_height);
AVRational timebase = AV_TIME_BASE_Q;
char *src_args = talloc_asprintf(tmp, "%d:%d:%d:%d:%d:%d:%d",
- width, height, imgfmt2pixfmt(fmt),
+ fmt->w, fmt->h, imgfmt2pixfmt(fmt->imgfmt),
timebase.num, timebase.den,
- par.num, par.den);
+ fmt->p_w, fmt->p_h);
if (avfilter_graph_create_filter(&in, avfilter_get_by_name("buffer"),
"src", src_args, NULL, graph) < 0)
@@ -225,7 +201,7 @@ static void reset(vf_instance_t *vf)
struct vf_priv_s *p = vf->priv;
struct mp_image_params *f = &vf->fmt_in;
if (p->graph && f->imgfmt)
- recreate_graph(vf, f->w, f->h, f->d_w, f->d_h, f->imgfmt);
+ recreate_graph(vf, f);
}
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
@@ -240,7 +216,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
return -1;
}
- if (!recreate_graph(vf, in->w, in->h, in->d_w, in->d_h, in->imgfmt))
+ if (!recreate_graph(vf, in))
return -1;
AVFilterLink *l_out = p->out->inputs[0];
@@ -251,13 +227,10 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
p->par_in = l_in->sample_aspect_ratio;
- int dw, dh;
- dar_from_sar_par(l_out->w, l_out->h, l_out->sample_aspect_ratio, &dw, &dh);
-
out->w = l_out->w;
out->h = l_out->h;
- out->d_w = dw;
- out->d_h = dh;
+ out->p_w = l_out->sample_aspect_ratio.num;
+ out->p_h = l_out->sample_aspect_ratio.den;
out->imgfmt = pixfmt2imgfmt(l_out->format);
return 0;
}
diff --git a/video/filter/vf_scale.c b/video/filter/vf_scale.c
index a71f2c1038..518ff41beb 100644
--- a/video/filter/vf_scale.c
+++ b/video/filter/vf_scale.c
@@ -76,7 +76,10 @@ static int find_best_out(vf_instance_t *vf, int in_format)
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
- int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h;
+ int width = in->w, height = in->h;
+ int d_width, d_height;
+ mp_image_params_get_dsize(in, &d_width, &d_height);
+
unsigned int best = find_best_out(vf, in->imgfmt);
int round_w = 0, round_h = 0;
@@ -154,8 +157,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
*out = *in;
out->w = vf->priv->w;
out->h = vf->priv->h;
- out->d_w = d_width;
- out->d_h = d_height;
+ mp_image_params_set_dsize(out, d_width, d_height);
out->imgfmt = best;
// Second-guess what libswscale is going to output and what not.
diff --git a/video/filter/vf_sub.c b/video/filter/vf_sub.c
index f44c4c0a67..a3680a3b9a 100644
--- a/video/filter/vf_sub.c
+++ b/video/filter/vf_sub.c
@@ -52,31 +52,23 @@ struct vf_priv_s {
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
- int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h;
+ int width = in->w, height = in->h;
vf->priv->outh = height + vf->priv->opt_top_margin +
vf->priv->opt_bottom_margin;
vf->priv->outw = width;
- double dar = (double)d_width / d_height;
- double sar = (double)width / height;
-
- vf_rescale_dsize(&d_width, &d_height, width, height,
- vf->priv->outw, vf->priv->outh);
-
vf->priv->dim = (struct mp_osd_res) {
.w = vf->priv->outw,
.h = vf->priv->outh,
.mt = vf->priv->opt_top_margin,
.mb = vf->priv->opt_bottom_margin,
- .display_par = sar / dar,
+ .display_par = in->p_w / (double)in->p_h,
};
*out = *in;
out->w = vf->priv->outw;
out->h = vf->priv->outh;
- out->d_w = d_width;
- out->d_h = d_height;
return 0;
}
diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c
index 68a43d8210..57ffe4d535 100644
--- a/video/filter/vf_vapoursynth.c
+++ b/video/filter/vf_vapoursynth.c
@@ -651,8 +651,6 @@ error:
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
- int width = in->w, height = in->h, d_width = in->d_w, d_height = in->d_h;
-
struct vf_priv_s *p = vf->priv;
p->fmt_in = *in;
@@ -669,18 +667,15 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
}
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(in->imgfmt);
- if (width % desc.align_x || height % desc.align_y) {
+ if (in->w % desc.align_x || in->h % desc.align_y) {
MP_FATAL(vf, "VapourSynth does not allow unaligned/cropped video sizes.\n");
destroy_vs(vf);
return -1;
}
- vf_rescale_dsize(&d_width, &d_height, width, height, vi->width, vi->height);
*out = *in;
out->w = vi->width;
out->h = vi->height;
- out->d_w = d_width;
- out->d_h = d_height;
return 0;
}
diff --git a/video/image_writer.c b/video/image_writer.c
index 6c1ed5482c..50dc42aff5 100644
--- a/video/image_writer.c
+++ b/video/image_writer.c
@@ -291,8 +291,8 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts)
struct mp_image *convert_image(struct mp_image *image, int destfmt,
struct mp_log *log)
{
- int d_w = image->params.d_w;
- int d_h = image->params.d_h;
+ int d_w, d_h;
+ mp_image_params_get_dsize(&image->params, &d_w, &d_h);
bool is_anamorphic = image->w != d_w || image->h != d_h;
// Caveat: no colorspace/levels conversion done if pixel formats equal
diff --git a/video/mp_image.c b/video/mp_image.c
index a3472baf3f..dfd7d0dc77 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -27,6 +27,7 @@
#include <libavutil/mem.h>
#include <libavutil/common.h>
#include <libavutil/bswap.h>
+#include <libavutil/rational.h>
#include <libavcodec/avcodec.h>
#include "talloc.h"
@@ -116,8 +117,9 @@ int mp_image_plane_h(struct mp_image *mpi, int plane)
void mp_image_set_size(struct mp_image *mpi, int w, int h)
{
assert(w >= 0 && h >= 0);
- mpi->w = mpi->params.w = mpi->params.d_w = w;
- mpi->h = mpi->params.h = mpi->params.d_h = h;
+ mpi->w = mpi->params.w = w;
+ mpi->h = mpi->params.h = h;
+ mpi->params.p_w = mpi->params.p_h = 1;
}
void mp_image_set_params(struct mp_image *image,
@@ -385,8 +387,8 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
dst->params.stereo_in = src->params.stereo_in;
dst->params.stereo_out = src->params.stereo_out;
if (dst->w == src->w && dst->h == src->h) {
- dst->params.d_w = src->params.d_w;
- dst->params.d_h = src->params.d_h;
+ dst->params.p_w = src->params.p_w;
+ dst->params.p_h = src->params.p_h;
}
dst->params.primaries = src->params.primaries;
dst->params.gamma = src->params.gamma;
@@ -477,13 +479,32 @@ void mp_image_vflip(struct mp_image *img)
}
}
+// Display size derived from image size and pixel aspect ratio.
+void mp_image_params_get_dsize(const struct mp_image_params *p,
+ int *d_w, int *d_h)
+{
+ *d_w = p->w;
+ *d_h = p->h;
+ if (p->p_w > p->p_h && p->p_h >= 1)
+ *d_w = MPCLAMP(*d_w * (int64_t)p->p_w / p->p_h, 0, INT_MAX);
+ if (p->p_h > p->p_w && p->p_w >= 1)
+ *d_h = MPCLAMP(*d_h * (int64_t)p->p_h / p->p_w, 0, INT_MAX);
+}
+
+void mp_image_params_set_dsize(struct mp_image_params *p, int d_w, int d_h)
+{
+ AVRational ds = av_div_q((AVRational){d_w, d_h}, (AVRational){p->w, p->h});
+ p->p_w = ds.num;
+ p->p_h = ds.den;
+}
+
char *mp_image_params_to_str_buf(char *b, size_t bs,
const struct mp_image_params *p)
{
if (p && p->imgfmt) {
snprintf(b, bs, "%dx%d", p->w, p->h);
- if (p->w != p->d_w || p->h != p->d_h)
- mp_snprintf_cat(b, bs, "->%dx%d", p->d_w, p->d_h);
+ if (p->p_w != p->p_h || !p->p_w)
+ mp_snprintf_cat(b, bs, " [%d:%d]", p->p_w, p->p_h);
mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt));
mp_snprintf_cat(b, bs, " %s/%s",
m_opt_choice_str(mp_csp_names, p->colorspace),
@@ -515,7 +536,7 @@ bool mp_image_params_valid(const struct mp_image_params *p)
if (p->w <= 0 || p->h <= 0 || (p->w + 128LL) * (p->h + 128LL) >= INT_MAX / 8)
return false;
- if (p->d_w <= 0 || p->d_h <= 0)
+ if (p->p_w <= 0 || p->p_h <= 0)
return false;
if (p->rotate < 0 || p->rotate >= 360)
@@ -533,7 +554,7 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
{
return p1->imgfmt == p2->imgfmt &&
p1->w == p2->w && p1->h == p2->h &&
- p1->d_w == p2->d_w && p1->d_h == p2->d_h &&
+ p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
p1->colorspace == p2->colorspace &&
p1->colorlevels == p2->colorlevels &&
p1->primaries == p2->primaries &&
@@ -555,12 +576,6 @@ void mp_image_set_attributes(struct mp_image *image,
nparams.h = image->h;
if (nparams.imgfmt != params->imgfmt)
mp_image_params_guess_csp(&nparams);
- if (nparams.w != params->w || nparams.h != params->h) {
- if (nparams.d_w && nparams.d_h) {
- vf_rescale_dsize(&nparams.d_w, &nparams.d_h,
- params->w, params->h, nparams.w, nparams.h);
- }
- }
mp_image_set_params(image, &nparams);
}
diff --git a/video/mp_image.h b/video/mp_image.h
index f71f7b3652..c2841490f4 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -40,7 +40,7 @@
struct mp_image_params {
enum mp_imgfmt imgfmt; // pixel format
int w, h; // image dimensions
- int d_w, d_h; // define display aspect ratio (never 0/0)
+ int p_w, p_h; // define pixel aspect ratio (never 0/0)
enum mp_csp colorspace;
enum mp_csp_levels colorlevels;
enum mp_csp_prim primaries;
@@ -137,6 +137,10 @@ 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);
+void mp_image_params_get_dsize(const struct mp_image_params *p,
+ int *d_w, int *d_h);
+void mp_image_params_set_dsize(struct mp_image_params *p, int d_w, int d_h);
+
void mp_image_set_params(struct mp_image *image,
const struct mp_image_params *params);
diff --git a/video/out/aspect.c b/video/out/aspect.c
index 2e1093c921..2d25bbdfd5 100644
--- a/video/out/aspect.c
+++ b/video/out/aspect.c
@@ -135,8 +135,8 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
{
int src_w = video->w;
int src_h = video->h;
- int src_dw = video->d_w;
- int src_dh = video->d_h;
+ int src_dw, src_dh;
+ mp_image_params_get_dsize(video, &src_dw, &src_dh);
if (video->rotate % 180 == 90 && (vo_caps & VO_CAP_ROTATE90)) {
MPSWAP(int, src_w, src_h);
MPSWAP(int, src_dw, src_dh);
@@ -174,8 +174,8 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
mp_verbose(log, "Window size: %dx%d\n",
window_w, window_h);
- mp_verbose(log, "Video source: %dx%d (%dx%d)\n",
- video->w, video->h, video->d_w, video->d_h);
+ mp_verbose(log, "Video source: %dx%d (%d:%d)\n",
+ video->w, video->h, video->p_w, video->p_h);
mp_verbose(log, "Video display: (%d, %d) %dx%d -> (%d, %d) %dx%d\n",
src.x0, src.y0, sw, sh, dst.x0, dst.y0, dw, dh);
mp_verbose(log, "Video scale: %f/%f\n",
diff --git a/video/out/vo.c b/video/out/vo.c
index 6318ac7dc5..f65ff864e5 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -508,8 +508,7 @@ static void run_reconfig(void *p)
struct vo_internal *in = vo->in;
- vo->dwidth = params->d_w;
- vo->dheight = params->d_h;
+ mp_image_params_get_dsize(params, &vo->dwidth, &vo->dheight);
talloc_free(vo->params);
vo->params = talloc_memdup(vo, params, sizeof(*params));
diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c
index f671acf989..740631ddb4 100644
--- a/video/out/vo_drm.c
+++ b/video/out/vo_drm.c
@@ -305,8 +305,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
.imgfmt = IMGFMT,
.w = w,
.h = h,
- .d_w = w,
- .d_h = h,
+ .p_w = 1,
+ .p_h = 1,
};
talloc_free(p->cur_frame);
diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c
index 09e8af748c..aae7f7b934 100644
--- a/video/out/vo_lavc.c
+++ b/video/out/vo_lavc.c
@@ -93,8 +93,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
{
struct priv *vc = vo->priv;
enum AVPixelFormat pix_fmt = imgfmt2pixfmt(params->imgfmt);
- AVRational display_aspect_ratio, image_aspect_ratio;
- AVRational aspect;
+ AVRational aspect = {params->p_w, params->p_h};
uint32_t width = params->w;
uint32_t height = params->h;
@@ -103,12 +102,6 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
- display_aspect_ratio.num = params->d_w;
- display_aspect_ratio.den = params->d_h;
- image_aspect_ratio.num = width;
- image_aspect_ratio.den = height;
- aspect = av_div_q(display_aspect_ratio, image_aspect_ratio);
-
if (vc->stream) {
/* NOTE:
* in debug builds we get a "comparison between signed and unsigned"
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c
index dcbe2d5347..2fb60d96d1 100644
--- a/video/out/vo_wayland.c
+++ b/video/out/vo_wayland.c
@@ -299,8 +299,8 @@ static bool resize(struct priv *p)
.imgfmt = p->video_format->mp_format,
.w = p->dst_w,
.h = p->dst_h,
- .d_w = p->dst_w,
- .d_h = p->dst_h,
+ .p_w = 1,
+ .p_h = 1,
};
mp_image_params_guess_csp(&p->sws->dst);
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c
index 7f4e36fbb6..d763592020 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -259,8 +259,8 @@ static bool resize(struct vo *vo)
.imgfmt = fmte->mpfmt,
.w = p->dst_w,
.h = p->dst_h,
- .d_w = p->dst_w,
- .d_h = p->dst_h,
+ .p_w = 1,
+ .p_h = 1,
};
mp_image_params_guess_csp(&p->sws->dst);
diff --git a/video/out/win_state.c b/video/out/win_state.c
index f48f628173..a80a650315 10064