From 3a39fc1feabf24a07084b4e1f68129c492e5d54a Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Mon, 14 Nov 2011 20:12:20 +0200 Subject: 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. --- command.c | 2 +- libmpcodecs/dec_video.c | 7 +++++ libmpcodecs/dec_video.h | 1 + libmpcodecs/vd.h | 1 + libmpcodecs/vd_ffmpeg.c | 72 ++++++++++++++++++++++++++----------------------- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/command.c b/command.c index bdb9343187..d5ab987baf 100644 --- a/command.c +++ b/command.c @@ -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; else 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; case MP_CMD_SPEED_INCR: { diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c index 91b255114a..cd3083faa4 100644 --- a/libmpcodecs/dec_video.c +++ b/libmpcodecs/dec_video.c @@ -212,6 +212,13 @@ void resync_video_stream(sh_video_t *sh_video) 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) { const struct vd_functions *vd = sh_video->vd_driver; diff --git a/libmpcodecs/dec_video.h b/libmpcodecs/dec_video.h index 60a9e5f2d2..f7210e02c3 100644 --- a/libmpcodecs/dec_video.h +++ b/libmpcodecs/dec_video.h @@ -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 redraw_osd(struct sh_video *sh_video, struct osd_state *osd); 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); extern int divx_quality; diff --git a/libmpcodecs/vd.h b/libmpcodecs/vd.h index 7591d6863f..8b0f9c1aea 100644 --- a/libmpcodecs/vd.h +++ b/libmpcodecs/vd.h @@ -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_RESYNC_STREAM 8 // reset decode state after seeking #define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag +#define VDCTRL_RESET_ASPECT 10 // reinit filter/VO chain for new aspect ratio // callbacks: int mpcodecs_config_vo2(sh_video_t *sh, int w, int h, diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index 21c107587d..b7f189ec5f 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -119,40 +119,6 @@ static enum AVDiscard str2AVDiscard(char *str) 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) { struct lavc_param *lavc_param = &sh->opts->lavc_param; @@ -864,6 +830,44 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx, 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 = { .info = &info, .init = init, -- cgit v1.2.3