summaryrefslogtreecommitdiffstats
path: root/video/filter
diff options
context:
space:
mode:
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;