summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-11-14 20:12:20 +0200
committerUoti Urpala <uau@mplayer2.org>2011-11-14 20:24:39 +0200
commit3a39fc1feabf24a07084b4e1f68129c492e5d54a (patch)
tree9c2526b9dfb350b54bbc063870584b5d713cf2b7
parent7b9908dda875db404604e87c8b762784d4f774d1 (diff)
downloadmpv-3a39fc1feabf24a07084b4e1f68129c492e5d54a.tar.bz2
mpv-3a39fc1feabf24a07084b4e1f68129c492e5d54a.tar.xz
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.
-rw-r--r--command.c2
-rw-r--r--libmpcodecs/dec_video.c7
-rw-r--r--libmpcodecs/dec_video.h1
-rw-r--r--libmpcodecs/vd.h1
-rw-r--r--libmpcodecs/vd_ffmpeg.c72
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,