mirror of
https://github.com/mpv-player/mpv
synced 2025-02-17 13:17:13 +00:00
video: move handling of container vs. stream AR out of vd_lavc.c
Now the actual decoder doesn't need to care about this anymore, and it's handled in generic code instead. This simplifies vd_lavc.c, and in particular we don't need to detect format changes in the old way anymore.
This commit is contained in:
parent
215b3cedda
commit
de68b8f23c
@ -339,13 +339,26 @@ int mpcodecs_reconfig_vo(struct dec_video *d_video,
|
|||||||
d_video->vfilter = vf;
|
d_video->vfilter = vf;
|
||||||
flip = false;
|
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;
|
float force_aspect = opts->movie_aspect;
|
||||||
if (force_aspect > -1.0 && d_video->stream_aspect != 0.0)
|
if (force_aspect > -1.0 && d_video->stream_aspect != 0.0)
|
||||||
force_aspect = d_video->stream_aspect;
|
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);
|
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) {
|
if (abs(p.d_w - p.w) >= 4 || abs(p.d_h - p.h) >= 4) {
|
||||||
|
@ -57,6 +57,8 @@ struct dec_video {
|
|||||||
|
|
||||||
float stream_aspect; // aspect ratio in media headers (DVD IFO files)
|
float stream_aspect; // aspect ratio in media headers (DVD IFO files)
|
||||||
int i_bps; // == bitrate (compressed bytes/sec)
|
int i_bps; // == bitrate (compressed bytes/sec)
|
||||||
|
|
||||||
|
float initial_decoder_aspect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mp_decoder_list *video_decoder_list(void);
|
struct mp_decoder_list *video_decoder_list(void);
|
||||||
|
@ -32,7 +32,6 @@ typedef struct lavc_ctx {
|
|||||||
int best_csp;
|
int best_csp;
|
||||||
struct mp_image_params image_params;
|
struct mp_image_params image_params;
|
||||||
struct mp_image_params vo_image_params;
|
struct mp_image_params vo_image_params;
|
||||||
AVRational last_sample_aspect_ratio;
|
|
||||||
enum AVDiscard skip_frame;
|
enum AVDiscard skip_frame;
|
||||||
const char *software_fallback_decoder;
|
const char *software_fallback_decoder;
|
||||||
|
|
||||||
|
@ -502,7 +502,6 @@ static void uninit_avctx(struct dec_video *vd)
|
|||||||
avcodec_free_frame(&ctx->pic);
|
avcodec_free_frame(&ctx->pic);
|
||||||
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
|
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
|
||||||
#endif
|
#endif
|
||||||
ctx->last_sample_aspect_ratio = (AVRational){0, 0};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uninit(struct dec_video *vd)
|
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;
|
int height = frame->height;
|
||||||
float aspect = av_q2d(frame->sample_aspect_ratio) * width / height;
|
float aspect = av_q2d(frame->sample_aspect_ratio) * width / height;
|
||||||
int pix_fmt = frame->format;
|
int pix_fmt = frame->format;
|
||||||
struct sh_video *sh = vd->header->video;
|
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 40, 0)
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 40, 0)
|
||||||
pix_fmt = ctx->avctx->pix_fmt;
|
pix_fmt = ctx->avctx->pix_fmt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (av_cmp_q(frame->sample_aspect_ratio, ctx->last_sample_aspect_ratio) ||
|
if (pix_fmt != ctx->pix_fmt) {
|
||||||
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;
|
|
||||||
|
|
||||||
ctx->pix_fmt = pix_fmt;
|
ctx->pix_fmt = pix_fmt;
|
||||||
ctx->best_csp = pixfmt2imgfmt(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,
|
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);
|
mp_image_params_from_image(&vo_params, mpi);
|
||||||
|
|
||||||
if (!mp_image_params_equals(&vo_params, &ctx->vo_image_params)) {
|
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) {
|
if (mpcodecs_reconfig_vo(vd, &vo_params) < 0) {
|
||||||
talloc_free(mpi);
|
talloc_free(mpi);
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user