video: make container vs. bitstream aspect ratio configurable

Utterly idiotic bullshit.

Fixes #2259.
This commit is contained in:
wm4 2015-08-30 23:01:46 +02:00
parent 061b947c84
commit 82f0d373fb
7 changed files with 59 additions and 18 deletions

View File

@ -20,6 +20,7 @@ Interface changes
:: ::
--- mpv 0.10.0 will be released --- --- mpv 0.10.0 will be released ---
- add --video-aspect-method option
- add --playlist-pos option - add --playlist-pos option
- add --video-sync* options - add --video-sync* options
"display-sync-active" property "display-sync-active" property

View File

@ -633,6 +633,23 @@ Video
Ignore aspect ratio information from video file and assume the video has Ignore aspect ratio information from video file and assume the video has
square pixels. See also ``--video-aspect``. square pixels. See also ``--video-aspect``.
``--video-aspect-method=<hybrid|bitstream|container>``
This sets the default video aspect determination method (if the aspect is
_not_ overridden by the user with ``--video-aspect`` or others).
:hybrid: Prefer the container aspect ratio. If the bitstream aspect
switches mid-stream, switch to preferring the bitstream aspect.
This is the default behavior in mpv and mplayer2.
:container: Strictly prefer the container aspect ratio. This is apparently
the default behavior with VLC, at least with Matroska.
:bitstream: Strictly prefer the bitstream aspect ratio, unless the bitstream
aspect ratio is not set. This is apparently the default behavior
with XBMC/kodi, at least with Matroska.
Normally you should not set this. Try the ``container`` and ``bitstream``
choices if you encounter video that has the wrong aspect ratio in mpv,
but seems to be correct in other players.
``--video-unscaled`` ``--video-unscaled``
Disable scaling of the video. If the window is larger than the video, Disable scaling of the video. If the window is larger than the video,
black bars are added. Otherwise, the video is cropped. The video still black bars are added. Otherwise, the video is cropped. The video still

View File

@ -59,7 +59,6 @@ void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
avctx->width = st->width; avctx->width = st->width;
avctx->height = st->height; avctx->height = st->height;
avctx->pix_fmt = st->pix_fmt; avctx->pix_fmt = st->pix_fmt;
avctx->sample_aspect_ratio = st->sample_aspect_ratio;
avctx->chroma_sample_location = st->chroma_sample_location; avctx->chroma_sample_location = st->chroma_sample_location;
avctx->sample_rate = st->sample_rate; avctx->sample_rate = st->sample_rate;
avctx->channels = st->channels; avctx->channels = st->channels;

View File

@ -312,6 +312,8 @@ const m_option_t mp_opts[] = {
// 0 means square pixels // 0 means square pixels
OPT_FLOATRANGE("video-aspect", movie_aspect, 0, -1.0, 10.0), OPT_FLOATRANGE("video-aspect", movie_aspect, 0, -1.0, 10.0),
OPT_FLOAT_STORE("no-video-aspect", movie_aspect, 0, 0.0), OPT_FLOAT_STORE("no-video-aspect", movie_aspect, 0, 0.0),
OPT_CHOICE("video-aspect-method", aspect_method, 0,
({"hybrid", 0}, {"bitstream", 1}, {"container", 2})),
OPT_CHOICE("field-dominance", field_dominance, 0, OPT_CHOICE("field-dominance", field_dominance, 0,
({"auto", -1}, {"top", 0}, {"bottom", 1})), ({"auto", -1}, {"top", 0}, {"bottom", 1})),

View File

@ -227,6 +227,7 @@ typedef struct MPOpts {
struct m_obj_settings *af_settings, *af_defs; struct m_obj_settings *af_settings, *af_defs;
int deinterlace; int deinterlace;
float movie_aspect; float movie_aspect;
int aspect_method;
int field_dominance; int field_dominance;
char **sub_name; char **sub_name;
char **sub_paths; char **sub_paths;

View File

@ -386,24 +386,45 @@ int video_reconfig_filters(struct dec_video *d_video,
struct mp_image_params p = *params; struct mp_image_params p = *params;
struct sh_video *sh = d_video->header->video; struct sh_video *sh = d_video->header->video;
float decoder_aspect = p.d_w / (float)p.d_h; // 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;
if (d_video->initial_decoder_aspect == 0) if (d_video->initial_decoder_aspect == 0)
d_video->initial_decoder_aspect = decoder_aspect; 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 // We normally prefer the container aspect, unless the decoder aspect
// changes at least once. // changes at least once.
if (d_video->initial_decoder_aspect == decoder_aspect) { if (dec_aspect > 0 && d_video->initial_decoder_aspect != dec_aspect) {
if (sh->aspect > 0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect);
} else {
MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n"); MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n");
// Even if the aspect switches back, don't use container aspect again. // Even if the aspect switches back, don't use container aspect again.
d_video->initial_decoder_aspect = -1; d_video->initial_decoder_aspect = -1;
use_container = false;
}
break;
case 1:
use_container = false;
break;
}
if (use_container && sh->aspect > 0) {
MP_VERBOSE(d_video, "Using container aspect ratio.\n");
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect);
} }
float force_aspect = opts->movie_aspect; float force_aspect = opts->movie_aspect;
if (force_aspect >= 0.0) if (force_aspect >= 0.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); vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
}
// 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;
}
// Detect colorspace from resolution. // Detect colorspace from resolution.
mp_image_params_guess_csp(&p); mp_image_params_guess_csp(&p);

View File

@ -476,15 +476,12 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
av_get_pix_fmt_name(pix_fmt)); av_get_pix_fmt_name(pix_fmt));
} }
int d_w, d_h;
vf_set_dar(&d_w, &d_h, width, height, aspect);
*out_params = (struct mp_image_params) { *out_params = (struct mp_image_params) {
.imgfmt = ctx->best_csp, .imgfmt = ctx->best_csp,
.w = width, .w = width,
.h = height, .h = height,
.d_w = d_w, .d_w = 0,
.d_h = d_h, .d_h = 0,
.colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace), .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
.colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range), .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
.primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries), .primaries = avcol_pri_to_mp_csp_prim(ctx->avctx->color_primaries),
@ -495,6 +492,9 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
.stereo_in = vd->header->video->stereo_mode, .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) { if (opts->video_rotate < 0) {
out_params->rotate = 0; out_params->rotate = 0;
} else { } else {