summaryrefslogtreecommitdiffstats
path: root/video/filter
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-08 01:35:44 +0200
committerwm4 <wm4@nowhere>2013-06-28 20:34:46 +0200
commit3382a6f6e48c7e093c2b7e0e4a0e28b60a084358 (patch)
treecc50df6d6ae5ffa6b1f7d3eb4e816a3afcfd1641 /video/filter
parent823e0c511bea235be06d5e2037ef9d0b345d9405 (diff)
downloadmpv-3382a6f6e48c7e093c2b7e0e4a0e28b60a084358.tar.bz2
mpv-3382a6f6e48c7e093c2b7e0e4a0e28b60a084358.tar.xz
video: add a new method to configure filters and VOs
The filter chain and the video ouputs have config() functions. They are strictly limited to transfering the video size and format. Other parameters (like color levels) have to be transferred separately. Improve upon this by introducing a separate set of reconfig() functions, which use mp_image_params to carry format parameters. This struct contains all image format related parameters from config(), plus additional parameters such as colorspace. Change vf_rotate to use it, as well as vo_opengl. vf_rotate is just an example/test case, but vo_opengl will need it later. The intention is also to get rid of VOCTRL_SET_YUV_COLORSPACE. This information is now handed to the VOs via reconfig(). The getter, VOCTRL_GET_YUV_COLORSPACE, will still be needed though.
Diffstat (limited to 'video/filter')
-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
5 files changed, 95 insertions, 68 deletions
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;