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:
Uoti Urpala 2011-11-14 20:12:20 +02:00
parent 7b9908dda8
commit 3a39fc1fea
5 changed files with 48 additions and 35 deletions

View File

@ -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: {

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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,