diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index 1b461a619a..34dc9bd073 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -339,13 +339,26 @@ int mpcodecs_reconfig_vo(struct dec_video *d_video, d_video->vfilter = vf; flip = false; } - // time to do aspect ratio corrections... + + float decoder_aspect = p.d_w / (float)p.d_h; + if (d_video->initial_decoder_aspect == 0) + d_video->initial_decoder_aspect = decoder_aspect; + + // We normally prefer the container aspect, unless the decoder aspect + // changes at least once. + if (d_video->initial_decoder_aspect == decoder_aspect) { + if (sh->aspect > 0) + vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect); + } else { + // Even if the aspect switches back, don't use container aspect again. + d_video->initial_decoder_aspect = -1; + } float force_aspect = opts->movie_aspect; if (force_aspect > -1.0 && d_video->stream_aspect != 0.0) force_aspect = d_video->stream_aspect; - if (force_aspect >= 0) + if (force_aspect > 0) vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect); if (abs(p.d_w - p.w) >= 4 || abs(p.d_h - p.h) >= 4) { diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h index ebb2624037..ef0ff925ce 100644 --- a/video/decode/dec_video.h +++ b/video/decode/dec_video.h @@ -57,6 +57,8 @@ struct dec_video { float stream_aspect; // aspect ratio in media headers (DVD IFO files) int i_bps; // == bitrate (compressed bytes/sec) + + float initial_decoder_aspect; }; struct mp_decoder_list *video_decoder_list(void); diff --git a/video/decode/lavc.h b/video/decode/lavc.h index 0b0cf0a32a..2fdfae41f1 100644 --- a/video/decode/lavc.h +++ b/video/decode/lavc.h @@ -32,7 +32,6 @@ typedef struct lavc_ctx { int best_csp; struct mp_image_params image_params; struct mp_image_params vo_image_params; - AVRational last_sample_aspect_ratio; enum AVDiscard skip_frame; const char *software_fallback_decoder; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 332de553a6..c8a7cd322e 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -502,7 +502,6 @@ static void uninit_avctx(struct dec_video *vd) avcodec_free_frame(&ctx->pic); mp_buffer_pool_free(&ctx->dr1_buffer_pool); #endif - ctx->last_sample_aspect_ratio = (AVRational){0, 0}; } static void uninit(struct dec_video *vd) @@ -517,49 +516,30 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame) int height = frame->height; float aspect = av_q2d(frame->sample_aspect_ratio) * width / height; int pix_fmt = frame->format; - struct sh_video *sh = vd->header->video; #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 40, 0) pix_fmt = ctx->avctx->pix_fmt; #endif - if (av_cmp_q(frame->sample_aspect_ratio, ctx->last_sample_aspect_ratio) || - width != sh->disp_w || height != sh->disp_h || - pix_fmt != ctx->pix_fmt || !ctx->image_params.imgfmt) - { - mp_image_pool_clear(ctx->non_dr1_pool); - mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] aspect_ratio: %f\n", aspect); - - // Do not overwrite s->aspect on the first call, so that a container - // aspect if available is preferred. - // But set it even if the sample aspect did not change, since a - // resolution change can cause an aspect change even if the - // _sample_ aspect is unchanged. - float use_aspect = sh->aspect; - if (use_aspect == 0 || ctx->last_sample_aspect_ratio.den) - use_aspect = aspect; - ctx->last_sample_aspect_ratio = frame->sample_aspect_ratio; - sh->disp_w = width; - sh->disp_h = height; - + if (pix_fmt != ctx->pix_fmt) { ctx->pix_fmt = pix_fmt; ctx->best_csp = pixfmt2imgfmt(pix_fmt); - - int d_w, d_h; - vf_set_dar(&d_w, &d_h, width, height, use_aspect); - - ctx->image_params = (struct mp_image_params) { - .imgfmt = ctx->best_csp, - .w = width, - .h = height, - .d_w = d_w, - .d_h = d_h, - .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace), - .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range), - .chroma_location = - avchroma_location_to_mp(ctx->avctx->chroma_sample_location), - }; } + + int d_w, d_h; + vf_set_dar(&d_w, &d_h, width, height, aspect); + + ctx->image_params = (struct mp_image_params) { + .imgfmt = ctx->best_csp, + .w = width, + .h = height, + .d_w = d_w, + .d_h = d_h, + .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace), + .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range), + .chroma_location = + avchroma_location_to_mp(ctx->avctx->chroma_sample_location), + }; } static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx, @@ -793,6 +773,7 @@ static int decode(struct dec_video *vd, struct demux_packet *packet, mp_image_params_from_image(&vo_params, mpi); if (!mp_image_params_equals(&vo_params, &ctx->vo_image_params)) { + mp_image_pool_clear(ctx->non_dr1_pool); if (mpcodecs_reconfig_vo(vd, &vo_params) < 0) { talloc_free(mpi); return -1;