mirror of
https://github.com/mpv-player/mpv
synced 2025-04-11 04:01:31 +00:00
commands, vd_ffmpeg: fix switch_ratio slave command
The implementation of the switch_ratio command was hacky and called mpcodecs_config_vo() to reconfigure the filter/VO chain from under an existing decoder. This call no longer worked properly with vd_ffmpeg after that started using mpcodec_config_vo2(). Add new video decoder control command VDCTRL_RESET_ASPECT and use this to tell vd_ffmpeg to reinitialize the output chain properly.
This commit is contained in:
parent
7b9908dda8
commit
3a39fc1fea
@ -2948,7 +2948,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||||||
opts->movie_aspect = (float) sh_video->disp_w / sh_video->disp_h;
|
opts->movie_aspect = (float) sh_video->disp_w / sh_video->disp_h;
|
||||||
else
|
else
|
||||||
opts->movie_aspect = cmd->args[0].v.f;
|
opts->movie_aspect = cmd->args[0].v.f;
|
||||||
mpcodecs_config_vo(sh_video, sh_video->disp_w, sh_video->disp_h, 0);
|
video_reset_aspect(sh_video);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_CMD_SPEED_INCR: {
|
case MP_CMD_SPEED_INCR: {
|
||||||
|
@ -212,6 +212,13 @@ void resync_video_stream(sh_video_t *sh_video)
|
|||||||
sh_video->prev_sorted_pts = MP_NOPTS_VALUE;
|
sh_video->prev_sorted_pts = MP_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void video_reset_aspect(struct sh_video *sh_video)
|
||||||
|
{
|
||||||
|
int r = sh_video->vd_driver->control(sh_video, VDCTRL_RESET_ASPECT, NULL);
|
||||||
|
if (r != true)
|
||||||
|
mpcodecs_config_vo(sh_video, sh_video->disp_w, sh_video->disp_h, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int get_current_video_decoder_lag(sh_video_t *sh_video)
|
int get_current_video_decoder_lag(sh_video_t *sh_video)
|
||||||
{
|
{
|
||||||
const struct vd_functions *vd = sh_video->vd_driver;
|
const struct vd_functions *vd = sh_video->vd_driver;
|
||||||
|
@ -46,6 +46,7 @@ void set_video_colorspace(struct sh_video *sh);
|
|||||||
int set_rectangle(sh_video_t *sh_video, int param, int value);
|
int set_rectangle(sh_video_t *sh_video, int param, int value);
|
||||||
int redraw_osd(struct sh_video *sh_video, struct osd_state *osd);
|
int redraw_osd(struct sh_video *sh_video, struct osd_state *osd);
|
||||||
void resync_video_stream(sh_video_t *sh_video);
|
void resync_video_stream(sh_video_t *sh_video);
|
||||||
|
void video_reset_aspect(struct sh_video *sh_video);
|
||||||
int get_current_video_decoder_lag(sh_video_t *sh_video);
|
int get_current_video_decoder_lag(sh_video_t *sh_video);
|
||||||
|
|
||||||
extern int divx_quality;
|
extern int divx_quality;
|
||||||
|
@ -50,6 +50,7 @@ extern const vd_functions_t *const mpcodecs_vd_drivers[];
|
|||||||
#define VDCTRL_GET_EQUALIZER 7 // get color options (brightness,contrast etc)
|
#define VDCTRL_GET_EQUALIZER 7 // get color options (brightness,contrast etc)
|
||||||
#define VDCTRL_RESYNC_STREAM 8 // reset decode state after seeking
|
#define VDCTRL_RESYNC_STREAM 8 // reset decode state after seeking
|
||||||
#define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag
|
#define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag
|
||||||
|
#define VDCTRL_RESET_ASPECT 10 // reinit filter/VO chain for new aspect ratio
|
||||||
|
|
||||||
// callbacks:
|
// callbacks:
|
||||||
int mpcodecs_config_vo2(sh_video_t *sh, int w, int h,
|
int mpcodecs_config_vo2(sh_video_t *sh, int w, int h,
|
||||||
|
@ -119,40 +119,6 @@ static enum AVDiscard str2AVDiscard(char *str)
|
|||||||
return AVDISCARD_DEFAULT;
|
return AVDISCARD_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int control(sh_video_t *sh, int cmd, void *arg, ...)
|
|
||||||
{
|
|
||||||
vd_ffmpeg_ctx *ctx = sh->context;
|
|
||||||
AVCodecContext *avctx = ctx->avctx;
|
|
||||||
switch (cmd) {
|
|
||||||
case VDCTRL_QUERY_FORMAT:
|
|
||||||
{
|
|
||||||
int format = (*((int *)arg));
|
|
||||||
if (format == ctx->best_csp)
|
|
||||||
return CONTROL_TRUE;
|
|
||||||
// possible conversions:
|
|
||||||
switch (format) {
|
|
||||||
case IMGFMT_YV12:
|
|
||||||
case IMGFMT_IYUV:
|
|
||||||
case IMGFMT_I420:
|
|
||||||
// "converted" using pointer/stride modification
|
|
||||||
if (ctx->best_csp == IMGFMT_YV12)
|
|
||||||
return CONTROL_TRUE; // u/v swap
|
|
||||||
if (ctx->best_csp == IMGFMT_422P && !ctx->do_dr1)
|
|
||||||
return CONTROL_TRUE; // half stride
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return CONTROL_FALSE;
|
|
||||||
}
|
|
||||||
case VDCTRL_RESYNC_STREAM:
|
|
||||||
avcodec_flush_buffers(avctx);
|
|
||||||
return CONTROL_TRUE;
|
|
||||||
case VDCTRL_QUERY_UNSEEN_FRAMES:;
|
|
||||||
int delay = avctx->has_b_frames;
|
|
||||||
return delay + 10;
|
|
||||||
}
|
|
||||||
return CONTROL_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init(sh_video_t *sh)
|
static int init(sh_video_t *sh)
|
||||||
{
|
{
|
||||||
struct lavc_param *lavc_param = &sh->opts->lavc_param;
|
struct lavc_param *lavc_param = &sh->opts->lavc_param;
|
||||||
@ -864,6 +830,44 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx,
|
|||||||
return fmt[i];
|
return fmt[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int control(sh_video_t *sh, int cmd, void *arg, ...)
|
||||||
|
{
|
||||||
|
vd_ffmpeg_ctx *ctx = sh->context;
|
||||||
|
AVCodecContext *avctx = ctx->avctx;
|
||||||
|
switch (cmd) {
|
||||||
|
case VDCTRL_QUERY_FORMAT: {
|
||||||
|
int format = (*((int *)arg));
|
||||||
|
if (format == ctx->best_csp)
|
||||||
|
return CONTROL_TRUE;
|
||||||
|
// possible conversions:
|
||||||
|
switch (format) {
|
||||||
|
case IMGFMT_YV12:
|
||||||
|
case IMGFMT_IYUV:
|
||||||
|
case IMGFMT_I420:
|
||||||
|
// "converted" using pointer/stride modification
|
||||||
|
if (ctx->best_csp == IMGFMT_YV12)
|
||||||
|
return CONTROL_TRUE; // u/v swap
|
||||||
|
if (ctx->best_csp == IMGFMT_422P && !ctx->do_dr1)
|
||||||
|
return CONTROL_TRUE; // half stride
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CONTROL_FALSE;
|
||||||
|
}
|
||||||
|
case VDCTRL_RESYNC_STREAM:
|
||||||
|
avcodec_flush_buffers(avctx);
|
||||||
|
return CONTROL_TRUE;
|
||||||
|
case VDCTRL_QUERY_UNSEEN_FRAMES:;
|
||||||
|
int delay = avctx->has_b_frames;
|
||||||
|
return delay + 10;
|
||||||
|
case VDCTRL_RESET_ASPECT:
|
||||||
|
if (ctx->vo_initialized)
|
||||||
|
ctx->vo_initialized = false;
|
||||||
|
init_vo(sh, avctx->pix_fmt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return CONTROL_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
const struct vd_functions mpcodecs_vd_ffmpeg = {
|
const struct vd_functions mpcodecs_vd_ffmpeg = {
|
||||||
.info = &info,
|
.info = &info,
|
||||||
.init = init,
|
.init = init,
|
||||||
|
Loading…
Reference in New Issue
Block a user