mirror of
https://github.com/mpv-player/mpv
synced 2025-01-24 16:43:28 +00:00
m_option: change m_option_type_aspect to double
This specific option type is only used for the video aspect. The underlying type was a float to represent the inputted value, but it's actually not precise enough. When using something like 4:3, the values of the incorrect digits are actually significant enough to make av_d2q return a very funky numerator and denominator which is close to 4/3 but not quite. This leads to some "off by one pixel" errors. Weirdly, mpv's actual calculations for this were already being done as double, but then converted to floats for this specific type. Just drop the conversion step and leave it all as double which has the precision we need (i.e. AVRational is now 4/3 for the this case). Fixes #8190.
This commit is contained in:
parent
efefe3a6dc
commit
1df0a42a8c
@ -93,7 +93,7 @@ static const struct m_sub_options adec_queue_conf = {
|
||||
#define OPT_BASE_STRUCT struct dec_wrapper_opts
|
||||
|
||||
struct dec_wrapper_opts {
|
||||
float movie_aspect;
|
||||
double movie_aspect;
|
||||
int aspect_method;
|
||||
double force_fps;
|
||||
bool correct_pts;
|
||||
|
@ -1109,6 +1109,32 @@ const m_option_type_t m_option_type_double = {
|
||||
.equal = double_equal,
|
||||
};
|
||||
|
||||
static int parse_double_aspect(struct mp_log *log, const m_option_t *opt,
|
||||
struct bstr name, struct bstr param, void *dst)
|
||||
{
|
||||
if (bstr_equals0(param, "no")) {
|
||||
if (dst)
|
||||
VAL(dst) = 0.0;
|
||||
return 1;
|
||||
}
|
||||
return parse_double(log, opt, name, param, dst);
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_aspect = {
|
||||
.name = "Aspect",
|
||||
.size = sizeof(double),
|
||||
.flags = M_OPT_TYPE_CHOICE | M_OPT_TYPE_USES_RANGE,
|
||||
.parse = parse_double_aspect,
|
||||
.print = print_double,
|
||||
.pretty_print = print_double_f3,
|
||||
.copy = copy_opt,
|
||||
.add = add_double,
|
||||
.multiply = multiply_double,
|
||||
.set = double_set,
|
||||
.get = double_get,
|
||||
.equal = double_equal,
|
||||
};
|
||||
|
||||
#undef VAL
|
||||
#define VAL(x) (*(float *)(x))
|
||||
|
||||
@ -1185,32 +1211,6 @@ const m_option_type_t m_option_type_float = {
|
||||
.equal = float_equal,
|
||||
};
|
||||
|
||||
static int parse_float_aspect(struct mp_log *log, const m_option_t *opt,
|
||||
struct bstr name, struct bstr param, void *dst)
|
||||
{
|
||||
if (bstr_equals0(param, "no")) {
|
||||
if (dst)
|
||||
VAL(dst) = 0.0f;
|
||||
return 1;
|
||||
}
|
||||
return parse_float(log, opt, name, param, dst);
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_aspect = {
|
||||
.name = "Aspect",
|
||||
.size = sizeof(float),
|
||||
.flags = M_OPT_TYPE_CHOICE | M_OPT_TYPE_USES_RANGE,
|
||||
.parse = parse_float_aspect,
|
||||
.print = print_float,
|
||||
.pretty_print = print_float_f3,
|
||||
.copy = copy_opt,
|
||||
.add = add_float,
|
||||
.multiply = multiply_float,
|
||||
.set = float_set,
|
||||
.get = float_get,
|
||||
.equal = float_equal,
|
||||
};
|
||||
|
||||
///////////// String
|
||||
|
||||
#undef VAL
|
||||
|
@ -661,7 +661,7 @@ extern const char m_option_path_separator;
|
||||
OPT_TYPED_FIELD(m_option_type_msglevels, char **, field)
|
||||
|
||||
#define OPT_ASPECT(field) \
|
||||
OPT_TYPED_FIELD(m_option_type_aspect, float, field)
|
||||
OPT_TYPED_FIELD(m_option_type_aspect, double, field)
|
||||
|
||||
#define OPT_IMAGEFORMAT(field) \
|
||||
OPT_TYPED_FIELD(m_option_type_imgfmt, int, field)
|
||||
|
Loading…
Reference in New Issue
Block a user