summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/stheader.h2
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/vd.c50
-rw-r--r--video/decode/vd.h2
-rw-r--r--video/decode/vd_lavc.c22
-rw-r--r--video/filter/vf.c92
-rw-r--r--video/filter/vf.h21
-rw-r--r--video/filter/vf_lavfi.c4
-rw-r--r--video/filter/vf_rotate.c25
-rw-r--r--video/filter/vf_vo.c21
-rw-r--r--video/mp_image.c5
-rw-r--r--video/mp_image.h10
-rw-r--r--video/out/gl_video.c16
-rw-r--r--video/out/gl_video.h2
-rw-r--r--video/out/vo.c29
-rw-r--r--video/out/vo.h37
-rw-r--r--video/out/vo_opengl.c13
17 files changed, 211 insertions, 141 deletions
diff --git a/demux/stheader.h b/demux/stheader.h
index 58caa27dcd..ff98430a65 100644
--- a/demux/stheader.h
+++ b/demux/stheader.h
@@ -149,9 +149,7 @@ typedef struct sh_video {
int colorspace; // mp_csp
int color_range; // mp_csp_levels
// output driver/filters: (set by libmpcodecs core)
- unsigned int outfmt;
struct vf_instance *vfilter; // video filter chain
- int output_flags; // query_format() results for output filters+vo
const struct vd_functions *vd_driver;
int vf_initialized; // -1 failed, 0 not done, 1 done
// win32-compatible codec parameters:
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 41701be1d6..25ed2b8ac5 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -18,6 +18,7 @@ typedef struct ffmpeg_ctx {
int do_hw_dr1;
int vo_initialized;
int best_csp;
+ struct mp_image_params image_params;
AVRational last_sample_aspect_ratio;
enum AVDiscard skip_frame;
const char *software_fallback_decoder;
diff --git a/video/decode/vd.c b/video/decode/vd.c
index b38d9d43d5..6f05ab334c 100644
--- a/video/decode/vd.c
+++ b/video/decode/vd.c
@@ -50,16 +50,22 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = {
NULL
};
-int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
+int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params)
{
struct MPOpts *opts = sh->opts;
vf_instance_t *vf = sh->vfilter;
int vocfg_flags = 0;
-
- if (w)
- sh->disp_w = w;
- if (h)
- sh->disp_h = h;
+ struct mp_image_params p = *params;
+
+ if (!p.w || !p.h) {
+ // ideally, this should be dead code
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown size, using container size.\n");
+ p.w = sh->disp_w;
+ p.h = sh->disp_h;
+ } else {
+ sh->disp_w = p.w;
+ sh->disp_h = p.h;
+ }
mp_msg(MSGT_DECVIDEO, MSGL_V,
"VIDEO: %dx%d %5.3f fps %5.1f kbps (%4.1f kB/s)\n",
@@ -67,10 +73,10 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
sh->i_bps / 1000.0);
if (!sh->disp_w || !sh->disp_h)
- return 0;
+ return -1;
mp_msg(MSGT_DECVIDEO, MSGL_V, "VDec: vo config request - %d x %d (%s)\n",
- w, h, vo_format_name(out_fmt));
+ p.w, p.h, vo_format_name(p.imgfmt));
if (get_video_quality_max(sh) <= 0 && opts->divx_quality) {
// user wants postprocess but no pp filter yet:
@@ -78,17 +84,17 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
}
// check if libvo and codec has common outfmt (no conversion):
+ int flags = 0;
for (;;) {
mp_msg(MSGT_VFILTER, MSGL_V, "Trying filter chain:\n");
vf_print_filter_chain(MSGL_V, vf);
- int flags = vf->query_format(vf, out_fmt);
+ flags = vf->query_format(vf, p.imgfmt);
mp_msg(MSGT_CPLAYER, MSGL_DBG2, "vo_debug: query(%s) returned 0x%X \n",
- vo_format_name(out_fmt), flags);
+ vo_format_name(p.imgfmt), flags);
if ((flags & VFCAP_CSP_SUPPORTED_BY_HW)
|| (flags & VFCAP_CSP_SUPPORTED))
{
- sh->output_flags = flags;
break;
}
// TODO: no match - we should use conversion...
@@ -104,16 +110,13 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
mp_tmsg(MSGT_VFILTER, MSGL_WARN, "Attempted filter chain:\n");
vf_print_filter_chain(MSGL_WARN, vf);
sh->vf_initialized = -1;
- return 0; // failed
+ return -1; // failed
}
- sh->outfmt = out_fmt;
- mp_msg(MSGT_CPLAYER, MSGL_V, "VDec: using %s as output csp\n",
- vo_format_name(out_fmt));
sh->vfilter = vf;
// autodetect flipping
bool flip = opts->flip;
- if (flip && !(sh->output_flags & VFCAP_FLIP)) {
+ if (flip && !(flags & VFCAP_FLIP)) {
// we need to flip, but no flipping filter avail.
vf_add_before_vo(&vf, "flip", NULL);
sh->vfilter = vf;
@@ -147,19 +150,21 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect);
}
+ p.d_w = d_w;
+ p.d_h = d_h;
+
vocfg_flags = (opts->fullscreen ? VOFLAG_FULLSCREEN : 0) |
(flip ? VOFLAG_FLIPPING : 0);
// Time to config libvo!
mp_msg(MSGT_CPLAYER, MSGL_V,
"VO Config (%dx%d->%dx%d,flags=%d,0x%X)\n", sh->disp_w,
- sh->disp_h, d_w, d_h, vocfg_flags, out_fmt);
+ sh->disp_h, d_w, d_h, vocfg_flags, p.imgfmt);
- if (vf_config_wrapper(vf, sh->disp_w, sh->disp_h, d_w, d_h, vocfg_flags,
- out_fmt) == 0) {
+ if (vf_reconfig_wrapper(vf, &p, vocfg_flags) < 0) {
mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "FATAL: Cannot initialize video driver.\n");
sh->vf_initialized = -1;
- return 0;
+ return -1;
}
mp_tmsg(MSGT_VFILTER, MSGL_V, "Video filter chain:\n");
@@ -167,6 +172,9 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
sh->vf_initialized = 1;
+ sh->colorspace = p.colorspace;
+ sh->color_range = p.colorlevels;
+
set_video_colorspace(sh);
if (opts->gamma_gamma != 1000)
@@ -180,5 +188,5 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
if (opts->gamma_hue != 1000)
set_video_colors(sh, "hue", opts->gamma_hue);
- return 1;
+ return 0;
}
diff --git a/video/decode/vd.h b/video/decode/vd.h
index 0e06f7bb40..ca4107dca9 100644
--- a/video/decode/vd.h
+++ b/video/decode/vd.h
@@ -44,6 +44,6 @@ extern const vd_functions_t *const mpcodecs_vd_drivers[];
#define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag
#define VDCTRL_REINIT_VO 10 // reinit filter/VO chain
-int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int outfmt);
+int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params);
#endif /* MPLAYER_VD_H */
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 1f5ae68bbf..f67e6dfbe6 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -436,10 +436,19 @@ static int init_vo(sh_video_t *sh, AVFrame *frame)
ctx->pix_fmt = pix_fmt;
ctx->best_csp = pixfmt2imgfmt(pix_fmt);
- sh->colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace);
- sh->color_range = avcol_range_to_mp_csp_levels(ctx->avctx->color_range);
+ ctx->image_params = (struct mp_image_params) {
+ .imgfmt = ctx->best_csp,
+ .w = width,
+ .h = height,
+ // Ideally, we should also set aspect ratio, but we aren't there yet
+ // - so vd.c calculates display size from sh->aspect.
+ .d_w = width,
+ .d_h = height,
+ .colorspace = avcol_spc_to_mp_csp(ctx->avctx->colorspace),
+ .colorlevels = avcol_range_to_mp_csp_levels(ctx->avctx->color_range),
+ };
- if (!mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, ctx->best_csp))
+ if (mpcodecs_reconfig_vo(sh, &ctx->image_params) < 0)
return -1;
ctx->vo_initialized = 1;
@@ -690,8 +699,8 @@ static int decode(struct sh_video *sh, struct demux_packet *packet,
struct mp_image *mpi = image_from_decoder(sh);
assert(mpi->planes[0]);
- mpi->colorspace = sh->colorspace;
- mpi->levels = sh->color_range;
+ mpi->colorspace = ctx->image_params.colorspace;
+ mpi->levels = ctx->image_params.colorlevels;
*out_image = mpi;
return 1;
@@ -745,7 +754,8 @@ static int control(sh_video_t *sh, int cmd, void *arg)
*(int *)arg = delay;
return CONTROL_TRUE;
case VDCTRL_REINIT_VO:
- mpcodecs_config_vo(sh, sh->disp_w, sh->disp_h, ctx->best_csp);
+ if (ctx->vo_initialized)
+ mpcodecs_reconfig_vo(sh, &ctx->image_params);
return true;
}
return CONTROL_UNKNOWN;
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 94df76c0e1..26841f380f 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -125,16 +125,17 @@ const m_obj_list_t vf_obj_list = {
// the last vf_config call.
struct mp_image *vf_alloc_out_image(struct vf_instance *vf)
{
+ struct mp_image_params *p = &vf->fmt_out.params;
assert(vf->fmt_out.configured);
- return mp_image_pool_get(vf->out_pool, vf->fmt_out.fmt,
- vf->fmt_out.w, vf->fmt_out.h);
+ return mp_image_pool_get(vf->out_pool, p->imgfmt, p->w, p->h);
}
void vf_make_out_image_writeable(struct vf_instance *vf, struct mp_image *img)
{
+ struct mp_image_params *p = &vf->fmt_out.params;
assert(vf->fmt_out.configured);
- assert(vf->fmt_out.fmt == img->imgfmt);
- assert(vf->fmt_out.w == img->w && vf->fmt_out.h == img->h);
+ assert(p->imgfmt == img->imgfmt);
+ assert(p->w == img->w && p->h == img->h);
mp_image_pool_make_writeable(vf->out_pool, img);
}
@@ -156,10 +157,11 @@ static struct mp_image *vf_default_filter(struct vf_instance *vf,
static void print_fmt(int msglevel, struct vf_format *fmt)
{
if (fmt && fmt->configured) {
- mp_msg(MSGT_VFILTER, msglevel, "%dx%d", fmt->w, fmt->h);
- if (fmt->w != fmt->dw || fmt->h != fmt->dh)
- mp_msg(MSGT_VFILTER, msglevel, "->%dx%d", fmt->dw, fmt->dh);
- mp_msg(MSGT_VFILTER, msglevel, " %s %#x", mp_imgfmt_to_name(fmt->fmt),
+ struct mp_image_params *p = &fmt->params;
+ mp_msg(MSGT_VFILTER, msglevel, "%dx%d", p->w, p->h);
+ if (p->w != p->d_w || p->h != p->d_h)
+ mp_msg(MSGT_VFILTER, msglevel, "->%dx%d", p->d_w, p->d_h);
+ mp_msg(MSGT_VFILTER, msglevel, " %s %#x", mp_imgfmt_to_name(p->imgfmt),
fmt->flags);
} else {
mp_msg(MSGT_VFILTER, msglevel, "???");
@@ -366,9 +368,10 @@ static struct mp_image *vf_dequeue_output_frame(struct vf_instance *vf)
// Return >= 0 on success, < 0 on failure (even if output frames were produced)
int vf_filter_frame(struct vf_instance *vf, struct mp_image *img)
{
+ struct mp_image_params *p = &vf->fmt_in.params;
assert(vf->fmt_in.configured);
- assert(img->w == vf->fmt_in.w && img->h == vf->fmt_in.h);
- assert(img->imgfmt == vf->fmt_in.fmt);
+ assert(img->w == p->w && img->h == p->h);
+ assert(img->imgfmt == p->imgfmt);
if (vf->filter_ext) {
return vf->filter_ext(vf, img);
@@ -410,54 +413,73 @@ void vf_chain_seek_reset(struct vf_instance *vf)
vf_forget_frames(cur);
}
-int vf_config_wrapper(struct vf_instance *vf,
- int width, int height, int d_width, int d_height,
- unsigned int flags, unsigned int outfmt)
+int vf_reconfig_wrapper(struct vf_instance *vf, struct mp_image_params *p,
+ int flags)
{
vf_forget_frames(vf);
mp_image_pool_clear(vf->out_pool);
- vf->fmt_in = vf->fmt_out = (struct vf_format){0};
-
- int r = vf->config(vf, width, height, d_width, d_height, flags, outfmt);
- if (r) {
- vf->fmt_in = (struct vf_format) {
- .configured = 1,
- .w = width, .h = height,
- .dw = d_width, .dh = d_height,
- .flags = flags,
- .fmt = outfmt,
- };
- vf->fmt_out = vf->next ? vf->next->fmt_in : (struct vf_format){0};
+ vf->fmt_in = (struct vf_format) {
+ .params = *p,
+ .flags = flags,
+ };
+ vf->fmt_out = (struct vf_format){0};
+
+ int r;
+ if (vf->reconfig) {
+ r = vf->reconfig(vf, p, flags);
+ } else {
+ r = vf->config(vf, p->w, p->h, p->d_w, p->d_h, flags, p->imgfmt);
+ r = r ? 0 : -1;
+ }
+ if (r >= 0) {
+ vf->fmt_in.configured = 1;
+ if (vf->next)
+ vf->fmt_out = vf->next->fmt_in;
}
return r;
}
-int vf_next_config(struct vf_instance *vf,
- int width, int height, int d_width, int d_height,
- unsigned int voflags, unsigned int outfmt)
+int vf_next_reconfig(struct vf_instance *vf, struct mp_image_params *p,
+ int outflags)
{
struct MPOpts *opts = vf->opts;
- int flags = vf->next->query_format(vf->next, outfmt);
+ int flags = vf->next->query_format(vf->next, p->imgfmt);
if (!flags) {
// hmm. colorspace mismatch!!!
// let's insert the 'scale' filter, it does the job for us:
vf_instance_t *vf2;
if (vf->next->info == &vf_info_scale)
- return 0; // scale->scale
+ return -1; // scale->scale
vf2 = vf_open_filter(opts, vf->next, "scale", NULL);
if (!vf2)
- return 0; // shouldn't happen!
+ return -1; // shouldn't happen!
vf->next = vf2;
- flags = vf->next->query_format(vf->next, outfmt);
+ flags = vf->next->query_format(vf->next, p->imgfmt);
if (!flags) {
mp_tmsg(MSGT_VFILTER, MSGL_ERR, "Cannot find matching colorspace, "
"even by inserting 'scale' :(\n");
- return 0; // FAIL
+ return -1; // FAIL
}
}
- return vf_config_wrapper(vf->next, width, height, d_width, d_height,
- voflags, outfmt);
+ return vf_reconfig_wrapper(vf->next, p, outflags);
+}
+
+int vf_next_config(struct vf_instance *vf,
+ int width, int height, int d_width, int d_height,
+ unsigned int voflags, unsigned int outfmt)
+{
+ struct mp_image_params p = {
+ .imgfmt = outfmt,
+ .w = width,
+ .h = height,
+ .d_w = d_width,
+ .d_h = d_height,
+ .colorspace = vf->fmt_in.params.colorspace,
+ .colorlevels = vf->fmt_in.params.colorlevels,
+ };
+ int r = vf_reconfig_wrapper(vf->next, &p, voflags);
+ return r < 0 ? 0 : 1;
}
int vf_next_control(struct vf_instance *vf, int request, void *data)
diff --git a/video/filter/vf.h b/video/filter/vf.h
index fd0118e152..638fc30a61 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -36,21 +36,28 @@ typedef struct vf_info {
const char *author;
const char *comment;
int (*vf_open)(struct vf_instance *vf, char *args);
- // Ptr to a struct dscribing the options
+ // Ptr to a struct describing the options
const void *opts;
} vf_info_t;
struct vf_format {
int configured;
- int w, h, dw, dh, flags, fmt;
+ struct mp_image_params params;
+ int flags;
};
typedef struct vf_instance {
const vf_info_t *info;
- // funcs:
+
int (*config)(struct vf_instance *vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt);
+
+ // Alternative to config() (can pass more image parameters)
+ // Note: the callee is allowed to write *params.
+ int (*reconfig)(struct vf_instance *vf, struct mp_image_params *params,
+ int flags);
+
int (*control)(struct vf_instance *vf, int request, void *data);
int (*query_format)(struct vf_instance *vf, unsigned int fmt);
@@ -131,6 +138,9 @@ int vf_next_config(struct vf_instance *vf,
int vf_next_control(struct vf_instance *vf, int request, void *data);
int vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
+int vf_next_reconfig(struct vf_instance *vf, struct mp_image_params *params,
+ int flags);
+
struct m_obj_settings;
vf_instance_t *append_filters(vf_instance_t *last,
struct m_obj_settings *vf_settings);
@@ -140,9 +150,8 @@ vf_instance_t *vf_find_by_label(vf_instance_t *chain, const char *label);
void vf_uninit_filter(vf_instance_t *vf);
void vf_uninit_filter_chain(vf_instance_t *vf);
-int vf_config_wrapper(struct vf_instance *vf,
- int width, int height, int d_width, int d_height,
- unsigned int flags, unsigned int outfmt);
+int vf_reconfig_wrapper(struct vf_instance *vf, struct mp_image_params *params,
+ int flags);
void vf_print_filter_chain(int msglevel, struct vf_instance *vf);
void vf_rescale_dsize(int *d_width, int *d_height, int old_w, int old_h,
diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c
index 53e22c21b9..6d5735b433 100644
--- a/video/filter/vf_lavfi.c
+++ b/video/filter/vf_lavfi.c
@@ -301,8 +301,8 @@ static int control(vf_instance_t *vf, int request, void *data)
switch (request) {
case VFCTRL_SEEK_RESET:
if (p->graph) {
- struct vf_format *f = &vf->fmt_in;
- recreate_graph(vf, f->w, f->h, f->dw, f->dh, f->fmt);
+ struct mp_image_params *f = &vf->fmt_in.params;
+ recreate_graph(vf, f->w, f->h, f->d_w, f->d_h, f->imgfmt);
}
break;
}
diff --git a/video/filter/vf_rotate.c b/video/filter/vf_rotate.c
index 0e5fbdbd37..94132848fb 100644
--- a/video/filter/vf_rotate.c
+++ b/video/filter/vf_rotate.c
@@ -65,21 +65,24 @@ static void rotate(unsigned char* dst,unsigned char* src,int dststride,int srcst
}
}
-static int config(struct vf_instance *vf, int width, int height,
- int d_width, int d_height,
- unsigned int flags, unsigned int outfmt)
+static int reconfig(struct vf_instance *vf, struct mp_image_params *p, int flags)
{
if (vf->priv->direction & 4) {
- if (width < height)
+ if (p->w < p->h)
vf->priv->direction &= 3;
}
if (vf->priv->direction & 4)
- return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
- struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(outfmt);
- int a_w = MP_ALIGN_DOWN(width, desc.align_x);
- int a_h = MP_ALIGN_DOWN(height, desc.align_y);
- vf_rescale_dsize(&d_width, &d_height, width, height, a_w, a_h);
- return vf_next_config(vf, a_h, a_w, d_height, d_width, flags, outfmt);
+ return vf_next_reconfig(vf, p, flags);
+ struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->imgfmt);
+ int a_w = MP_ALIGN_DOWN(p->w, desc.align_x);
+ int a_h = MP_ALIGN_DOWN(p->h, desc.align_y);
+ vf_rescale_dsize(&p->d_w, &p->d_h, p->w, p->h, a_w, a_h);
+ p->w = a_h;
+ p->h = a_w;
+ int t = p->d_w;
+ p->d_w = p->d_h;
+ p->d_h = t;
+ return vf_next_reconfig(vf, p, flags);
}
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
@@ -113,7 +116,7 @@ static int query_format(struct vf_instance *vf, unsigned int fmt)
}
static int vf_open(vf_instance_t *vf, char *args){
- vf->config=config;
+ vf->reconfig=reconfig;
vf->filter=filter;
vf->query_format=query_format;
vf->priv=malloc(sizeof(struct vf_priv_s));
diff --git a/video/filter/vf_vo.c b/video/filter/vf_vo.c
index 5edd2956c6..22fa38f8d0 100644
--- a/video/filter/vf_vo.c
+++ b/video/filter/vf_vo.c
@@ -37,22 +37,18 @@ struct vf_priv_s {
};
#define video_out (vf->priv->vo)
-static int config(struct vf_instance *vf,
- int width, int height, int d_width, int d_height,
- unsigned int flags, unsigned int outfmt)
+static int reconfig(struct vf_instance *vf, struct mp_image_params *p, int flags)
{
-
- if ((width <= 0) || (height <= 0) || (d_width <= 0) || (d_height <= 0)) {
+ if (p->w <= 0 || p->h <= 0 || p->d_w <= 0 || p->d_h <= 0) {
mp_msg(MSGT_CPLAYER, MSGL_ERR, "VO: invalid dimensions!\n");
- return 0;
+ return -1;
}
const vo_info_t *info = video_out->driver->info;
mp_msg(MSGT_CPLAYER, MSGL_INFO, "VO: [%s] %dx%d => %dx%d %s %s%s\n",
info->short_name,
- width, height,
- d_width, d_height,
- vo_format_name(outfmt),
+ p->w, p->h, p->d_w, p->d_h,
+ vo_format_name(p->imgfmt),
(flags & VOFLAG_FULLSCREEN) ? " [fs]" : "",
(flags & VOFLAG_FLIPPING) ? " [flip]" : "");
mp_msg(MSGT_CPLAYER, MSGL_V, "VO: Description: %s\n", info->name);
@@ -60,10 +56,7 @@ static int config(struct vf_instance *vf,
if (info->comment && strlen(info->comment) > 0)
mp_msg(MSGT_CPLAYER, MSGL_V, "VO: Comment: %s\n", info->comment);
- if (vo_config(video_out, width, height, d_width, d_height, flags, outfmt))
- return 0;
-
- return 1;
+ return vo_reconfig(video_out, p, flags);
}
static int control(struct vf_instance *vf, int request, void *data)
@@ -120,7 +113,7 @@ static void uninit(struct vf_instance *vf)
static int vf_open(vf_instance_t *vf, char *args)
{
- vf->config = config;
+ vf->reconfig = reconfig;
vf->control = control;
vf->query_format = query_format;
vf->uninit = uninit;
diff --git a/video/mp_image.c b/video/mp_image.c
index ec8f14fc34..85c174dfaa 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -152,15 +152,14 @@ static int mp_chroma_div_up(int size, int shift)
// Caller has to make sure this doesn't exceed the allocated plane data/strides.
void mp_image_set_size(struct mp_image *mpi, int w, int h)
{
- mpi->w = w;
- mpi->h = h;
+ mpi->w = mpi->display_w = w;
+ mpi->h = mpi->display_h = h;
for (int n = 0; n < mpi->num_planes; n++) {
mpi->plane_w[n] = mp_chroma_div_up(mpi->w, mpi->fmt.xs[n]);
mpi->plane_h[n] = mp_chroma_div_up(mpi->h, mpi->fmt.ys[n]);
}
mpi->chroma_width = mpi->plane_w[1];
mpi->chroma_height = mpi->plane_h[1];
- mpi->display_w = mpi->display_h = 0;
}
void mp_image_set_display_size(struct mp_image *mpi, int dw, int dh)
diff --git a/video/mp_image.h b/video/mp_image.h
index ca536a1e91..643b70b949 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -37,6 +37,14 @@
#define MP_IMGFIELD_BOTTOM 0x10
#define MP_IMGFIELD_INTERLACED 0x20
+struct mp_image_params {
+ enum mp_imgfmt imgfmt; // pixel format
+ int w, h; // image dimensions
+ int d_w, d_h; // define display aspect ratio (never 0/0)
+ enum mp_csp colorspace;
+ enum mp_csp_levels colorlevels;
+};
+
/* Memory management:
* - mp_image is a light-weight reference to the actual image data (pixels).
* The actual image data is reference counted and can outlive mp_image
@@ -58,7 +66,7 @@ typedef struct mp_image {
struct mp_imgfmt_desc fmt;
// fields redundant to fmt, for convenience or compatibility
- unsigned int imgfmt;
+ enum mp_imgfmt imgfmt;
int num_planes;
int chroma_x_shift; // horizontal
int chroma_y_shift; // vertical
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 4d780f41d8..658c531546 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -1848,17 +1848,19 @@ bool gl_video_check_format(int mp_format)
return init_format(mp_format, NULL);
}
-void gl_video_config(struct gl_video *p, int format, int w, int h, int dw, int dh)
+void gl_video_config(struct gl_video *p, struct mp_image_params *params)
{
- if (p->image_format != format || p->image_w != w || p->image_h != h) {
+ if (p->image_format != params->imgfmt || p->image_w != params->w ||
+ p->image_h != params->h)
+ {
uninit_video(p);
- p->image_w = w;
- p->image_h = h;
- init_format(format, p);
+ p->image_w = params->w;
+ p->image_h = params->h;
+ init_format(params->imgfmt, p);
init_video(p);
}
- p->image_dw = dw;
- p->image_dh = dh;
+ p->image_dw = params->d_w;
+ p->image_dh = params->d_h;
}
void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b)
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index 0d796502bb..289ccddf52 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -54,7 +54,7 @@ struct gl_video;
struct gl_video *gl_video_init(GL *gl);
void gl_video_uninit(struct gl_video *p);
void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts);
-void gl_video_config(struct gl_video *p, int format, int w, int h, int dw, int dh);
+void gl_video_config(struct gl_video *p, struct mp_image_params *params);
void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b);
void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d);
void gl_video_draw_osd(struct gl_video *p, struct osd_state *osd);
diff --git a/video/out/vo.c b/video/out/vo.c
index c621f37472..02d51bf7b6 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -406,21 +406,34 @@ static int event_fd_callback(void *ctx, int fd)
return MP_INPUT_NOTHING;
}
-int vo_config(struct vo *vo, uint32_t width, uint32_t height,
- uint32_t d_width, uint32_t d_height, uint32_t flags,
- uint32_t format)
+int vo_reconfig(struct vo *vo, struct mp_image_params *params, int flags)
{
- aspect_save_videores(vo, width, height, d_width, d_height);
+ int d_width = params->d_w;
+ int d_height = params->d_h;
+ aspect_save_videores(vo, params->w, params->h, d_width, d_height);
if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
- determine_window_geometry(vo, d_width, d_height);
+ determine_window_geometry(vo, params->d_w, params->d_h);
d_width = vo->dwidth;
d_height = vo->dheight;
}
+ vo->dwidth = d_width;
+ vo->dheight = d_height;
- int ret = vo->driver->config(vo, width, height, d_width, d_height, flags,
- format);
- vo->config_ok = (ret == 0);
+ struct mp_image_params p2 = *params;
+ p2.d_w = vo->aspdat.prew;
+ p2.d_h = vo->aspdat.preh;
+
+ int ret;
+ if (vo->driver->reconfig) {
+ ret = vo->driver->reconfig(vo, &p2, flags);
+ } else {
+ // Old config() takes window size, while reconfig() takes aspect (!)
+ ret = vo->driver->config(vo, p2.w, p2.h, d_width, d_height, flags,
+ p2.imgfmt);
+ ret = ret ? -1 : 0;
+ }
+ vo->config_ok = (ret >= 0);
vo->config_count += vo->config_ok;
if (vo->registered_fd == -1 && vo->event_fd != -1 && vo->config_ok) {
mp_input_add_key_fd(vo->input_ctx, vo->event_fd, 1, event_fd_callback,
diff --git a/video/out/vo.h b/video/out/vo.h
index df16a01d0e..9f4d2a9060 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -47,8 +47,8 @@ enum mp_voctrl {
VOCTRL_GET_PANSCAN,
VOCTRL_SET_PANSCAN,
- VOCTRL_SET_EQUALIZER, // struct voctrl_set_equalizer_args
- VOCTRL_GET_EQUALIZER, // struct voctrl_get_equalizer_args
+ VOCTRL_SET_EQUALIZER, // struct voctrl_set_equalizer_args*
+ VOCTRL_GET_EQUALIZER, // struct voctrl_get_equalizer_args*
/* for vdpau hardware decoding */
VOCTRL_HWDEC_DECODER_RENDER, // pointer to hw state
@@ -62,7 +62,7 @@ enum mp_voctrl {
VOCTRL_BORDER,
VOCTRL_UPDATE_WINDOW_TITLE, // char*
- VOCTRL_SET_CURSOR_VISIBILITY, // bool
+ VOCTRL_SET_CURSOR_VISIBILITY, // bool*
VOCTRL_KILL_SCREENSAVER,
VOCTRL_RESTORE_SCREENSAVER,
@@ -72,12 +72,12 @@ enum mp_voctrl {
VOCTRL_UPDATE_SCREENINFO,
- VOCTRL_SET_YUV_COLORSPACE, // struct mp_csp_details
- VOCTRL_GET_YUV_COLORSPACE, // struct mp_csp_details
+ VOCTRL_SET_YUV_COLORSPACE, // struct mp_csp_details*
+ VOCTRL_GET_YUV_COLORSPACE, // struct mp_csp_details*
- VOCTRL_SCREENSHOT, // struct voctrl_screenshot_args
+ VOCTRL_SCREENSHOT, // struct voctrl_screenshot_args*
- VOCTRL_SET_COMMAND_LINE, // char*
+ VOCTRL_SET_COMMAND_LINE, // char**
};
// VOCTRL_SET_EQUALIZER
@@ -139,6 +139,7 @@ typedef struct vo_info_s
struct vo;
struct osd_state;
struct mp_image;
+struct mp_image_params;
struct vo_driver {
// Driver buffers or adds (deinterlace) frames and will keep track
@@ -164,20 +165,28 @@ struct vo_driver {
int (*query_format)(struct vo *vo, uint32_t format);
/*
- * Initialize (means CONFIGURE) the display driver.
- * params:
+ * Initialize or reconfigure the display driver.
* width,height: image source size
- * d_width,d_height: size of the requested window size, just a hint
- * fullscreen: flag, 0=windowd 1=fullscreen, just a hint
+ * d_width,d_height: requested window size, just a hint
+ * flags: combination of VOFLAG_ values
* title: window title, if available
* format: fourcc of pixel format
* returns : zero on successful initialization, non-zero on error.
*/
int (*config)(struct vo *vo, uint32_t width, uint32_t height,
- uint32_t d_width, uint32_t d_height, uint32_t fullscreen,
+ uint32_t d_width, uint32_t d_height, uint32_t flags,
uint32_t format);
/*
+ * Initialize or reconfigure the display driver. Alternative to config(),
+ * and can carry more image parameters.
+ * params: video parameters, like pixel format and frame size
+ * flags: combination of VOFLAG_ values
+ * returns: < 0 on error, >= 0 on success
+ */
+ int (*reconfig)(struct vo *vo, struct mp_image_params *params, int flags);
+
+ /*
* Control interface
*/
int (*control)(struct vo *vo, uint32_t request, void *data);
@@ -284,9 +293,7 @@ struct vo *init_best_video_out(struct mp_vo_opts *opts,
struct mp_fifo *key_fifo,
struct input_ctx *input_ctx,
struct encode_lavc_context *encode_lavc_ctx);
-int vo_config(struct vo *vo, uint32_t width, uint32_t height,
- uint32_t d_width, uint32_t d_height, uint32_t flags,
- uint32_t format);
+int vo_reconfig(struct vo *vo, struct mp_image_params *p, int flags);
void list_video_out(void);
int vo_control(struct vo *vo, uint32_t request, void *data);
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 35ea0cebb0..882689ed87 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -163,15 +163,13 @@ static void video_resize_redraw_callback(struct vo *vo, int w, int h)
}
-static int config(struct vo *vo, uint32_t width, uint32_t height,
- uint32_t d_width, uint32_t d_height, uint32_t flags,
- uint32_t format)
+static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
{
struct gl_priv *p = vo->priv;
mpgl_lock(p->glctx);
- if (!config_window(p, d_width, d_height, flags)) {
+ if (!config_window(p, vo->dwidth, vo->dheight, flags)) {
mpgl_unlock(p->glctx);
return -1;
}
@@ -180,8 +178,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
p->glctx->register_resize_callback(vo, video_resize_redraw_callback);
}
- gl_video_config