static void reconfig_video(struct MPContext *mpctx, const struct mp_image_params *params, bool probe_only) { struct MPOpts *opts = mpctx->opts; struct dec_video *d_video = mpctx->d_video; d_video->decoder_output = *params; set_allowed_vo_formats(d_video->vfilter, mpctx->video_out); // The event should happen _after_ filter and VO reconfig. Since we don't // have any fine grained locking, this is just as good. mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL); if (video_reconfig_filters(d_video, params) < 0) { // Most video filters don't work with hardware decoding, so this // might be the reason filter reconfig failed. if (!probe_only && video_vd_control(d_video, VDCTRL_FORCE_HWDEC_FALLBACK, NULL) == CONTROL_OK) { // Fallback active; decoder will return software format next // time. Don't abort video decoding. d_video->vfilter->initialized = 0; } return; } if (d_video->vfilter->initialized < 1) return; struct mp_image_params p = d_video->vfilter->output_params; const struct vo_driver *info = mpctx->video_out->driver; MP_INFO(mpctx, "VO: [%s] %dx%d => %dx%d %s\n", info->name, p.w, p.h, p.d_w, p.d_h, vo_format_name(p.imgfmt)); MP_VERBOSE(mpctx, "VO: Description: %s\n", info->description); int r = vo_reconfig(mpctx->video_out, &p, 0); if (r < 0) d_video->vfilter->initialized = -1; if (r >= 0) { if (opts->gamma_gamma != 1000) video_set_colors(d_video, "gamma", opts->gamma_gamma); if (opts->gamma_brightness != 1000) video_set_colors(d_video, "brightness", opts->gamma_brightness); if (opts->gamma_contrast != 1000) video_set_colors(d_video, "contrast", opts->gamma_contrast); if (opts->gamma_saturation != 1000) video_set_colors(d_video, "saturation", opts->gamma_saturation); if (opts->gamma_hue != 1000) video_set_colors(d_video, "hue", opts->gamma_hue); } }
static void init_vo(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; struct dec_video *d_video = mpctx->d_video; if (opts->gamma_gamma != 1000) video_set_colors(d_video, "gamma", opts->gamma_gamma); if (opts->gamma_brightness != 1000) video_set_colors(d_video, "brightness", opts->gamma_brightness); if (opts->gamma_contrast != 1000) video_set_colors(d_video, "contrast", opts->gamma_contrast); if (opts->gamma_saturation != 1000) video_set_colors(d_video, "saturation", opts->gamma_saturation); if (opts->gamma_hue != 1000) video_set_colors(d_video, "hue", opts->gamma_hue); mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL); }
int video_reconfig_filters(struct dec_video *d_video, const struct mp_image_params *params) { struct MPOpts *opts = d_video->opts; struct mp_image_params p = *params; struct sh_video *sh = d_video->header->video; mp_msg(MSGT_DECVIDEO, MSGL_V, "VIDEO: %dx%d %5.3f fps %5.1f kbps (%4.1f kB/s)\n", p.w, p.h, sh->fps, sh->i_bps * 0.008, sh->i_bps / 1000.0); mp_msg(MSGT_DECVIDEO, MSGL_V, "VDec: vo config request - %d x %d (%s)\n", p.w, p.h, vo_format_name(p.imgfmt)); 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) 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) { mp_msg(MSGT_CPLAYER, MSGL_V, "Aspect ratio is %.2f:1 - " "scaling to correct movie aspect.\n", sh->aspect); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect); } else { p.d_w = p.w; p.d_h = p.h; } // Apply user overrides if (opts->requested_colorspace != MP_CSP_AUTO) p.colorspace = opts->requested_colorspace; if (opts->requested_input_range != MP_CSP_LEVELS_AUTO) p.colorlevels = opts->requested_input_range; p.outputlevels = opts->requested_output_range; // Detect colorspace from resolution. // Make sure the user-overrides are consistent (no RGB csp for YUV, etc.). mp_image_params_guess_csp(&p); // Time to config libvo! mp_msg(MSGT_CPLAYER, MSGL_V, "VO Config (%dx%d->%dx%d,0x%X)\n", p.w, p.h, p.d_w, p.d_h, p.imgfmt); if (vf_reconfig(d_video->vfilter, &p) < 0) { mp_msg(MSGT_CPLAYER, MSGL_WARN, "FATAL: Cannot initialize video driver.\n"); return -1; } d_video->vf_input = p; if (opts->gamma_gamma != 1000) video_set_colors(d_video, "gamma", opts->gamma_gamma); if (opts->gamma_brightness != 1000) video_set_colors(d_video, "brightness", opts->gamma_brightness); if (opts->gamma_contrast != 1000) video_set_colors(d_video, "contrast", opts->gamma_contrast); if (opts->gamma_saturation != 1000) video_set_colors(d_video, "saturation", opts->gamma_saturation); if (opts->gamma_hue != 1000) video_set_colors(d_video, "hue", opts->gamma_hue); return 0; }