summaryrefslogtreecommitdiffstats
path: root/video/filter
diff options
context:
space:
mode:
Diffstat (limited to 'video/filter')
-rw-r--r--video/filter/vf.c334
-rw-r--r--video/filter/vf.h57
-rw-r--r--video/filter/vf_crop.c17
-rw-r--r--video/filter/vf_delogo.c62
-rw-r--r--video/filter/vf_divtc.c42
-rw-r--r--video/filter/vf_dlopen.c115
-rw-r--r--video/filter/vf_down3dright.c17
-rw-r--r--video/filter/vf_dsize.c1
-rw-r--r--video/filter/vf_eq.c37
-rw-r--r--video/filter/vf_expand.c106
-rw-r--r--video/filter/vf_flip.c61
-rw-r--r--video/filter/vf_format.c1
-rw-r--r--video/filter/vf_gradfun.c50
-rw-r--r--video/filter/vf_hqdn3d.c15
-rw-r--r--video/filter/vf_ilpack.c14
-rw-r--r--video/filter/vf_mirror.c16
-rw-r--r--video/filter/vf_noformat.c1
-rw-r--r--video/filter/vf_noise.c46
-rw-r--r--video/filter/vf_phase.c15
-rw-r--r--video/filter/vf_pp.c57
-rw-r--r--video/filter/vf_pullup.c134
-rw-r--r--video/filter/vf_rotate.c23
-rw-r--r--video/filter/vf_scale.c32
-rw-r--r--video/filter/vf_screenshot.c55
-rw-r--r--video/filter/vf_softpulldown.c55
-rw-r--r--video/filter/vf_stereo3d.c19
-rw-r--r--video/filter/vf_sub.c104
-rw-r--r--video/filter/vf_swapuv.c52
-rw-r--r--video/filter/vf_unsharp.c41
-rw-r--r--video/filter/vf_vo.c12
-rw-r--r--video/filter/vf_yadif.c50
31 files changed, 519 insertions, 1122 deletions
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 417d5be1a3..4da167641a 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -33,6 +33,7 @@
#include "video/img_format.h"
#include "video/mp_image.h"
+#include "video/mp_image_pool.h"
#include "vf.h"
#include "video/memcpy_pic.h"
@@ -177,182 +178,21 @@ void vf_mpi_clear(mp_image_t *mpi, int x0, int y0, int w, int h)
}
}
-mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt,
- int mp_imgtype, int mp_imgflag, int w, int h)
+// Get a new image for filter output, with size and pixel format according to
+// the last vf_config call.
+struct mp_image *vf_alloc_out_image(struct vf_instance *vf)
{
- mp_image_t *mpi = NULL;
- int w2;
- int number = mp_imgtype >> 16;
-
- assert(w == -1 || w >= vf->w);
- assert(h == -1 || h >= vf->h);
- assert(vf->w > 0);
- assert(vf->h > 0);
-
- if (w == -1)
- w = vf->w;
- if (h == -1)
- h = vf->h;
-
- w2 = (mp_imgflag & MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE) ? FFALIGN(w, 32) : w;
-
- if (vf->put_image == vf_next_put_image) {
- // passthru mode, if the filter uses the fallback/default put_image()
- mpi = vf_get_image(vf->next,outfmt,mp_imgtype,mp_imgflag,w,h);
- mpi->usage_count++;
- return mpi;
- }
-
- // Note: we should call libvo first to check if it supports direct rendering
- // and if not, then fallback to software buffers:
- switch (mp_imgtype & 0xff) {
- case MP_IMGTYPE_EXPORT:
- if (!vf->imgctx.export_images[0])
- vf->imgctx.export_images[0] = new_mp_image(w2, h);
- mpi = vf->imgctx.export_images[0];
- break;
- case MP_IMGTYPE_STATIC:
- if (!vf->imgctx.static_images[0])
- vf->imgctx.static_images[0] = new_mp_image(w2, h);
- mpi = vf->imgctx.static_images[0];
- break;
- case MP_IMGTYPE_TEMP:
- if (!vf->imgctx.temp_images[0])
- vf->imgctx.temp_images[0] = new_mp_image(w2, h);
- mpi = vf->imgctx.temp_images[0];
- break;
- case MP_IMGTYPE_IPB:
- if (!(mp_imgflag & MP_IMGFLAG_READABLE)) { // B frame:
- if (!vf->imgctx.temp_images[0])
- vf->imgctx.temp_images[0] = new_mp_image(w2, h);
- mpi = vf->imgctx.temp_images[0];
- break;
- }
- case MP_IMGTYPE_IP:
- if (!vf->imgctx.static_images[vf->imgctx.static_idx])
- vf->imgctx.static_images[vf->imgctx.static_idx] = new_mp_image(w2, h);
- mpi = vf->imgctx.static_images[vf->imgctx.static_idx];
- vf->imgctx.static_idx ^= 1;
- break;
- case MP_IMGTYPE_NUMBERED:
- if (number == -1) {
- int i;
- for (i = 0; i < NUM_NUMBERED_MPI; i++)
- if (!vf->imgctx.numbered_images[i] ||
- !vf->imgctx.numbered_images[i]->usage_count)
- break;
- number = i;
- }
- if (number < 0 || number >= NUM_NUMBERED_MPI)
- return NULL;
- if (!vf->imgctx.numbered_images[number])
- vf->imgctx.numbered_images[number] = new_mp_image(w2, h);
- mpi = vf->imgctx.numbered_images[number];
- mpi->number = number;
- break;
- }
- if (mpi) {
- int missing_palette = !(mpi->flags & MP_IMGFLAG_RGB_PALETTE) &&
- (mp_imgflag & MP_IMGFLAG_RGB_PALETTE);
- mpi->type = mp_imgtype;
- mpi->w = vf->w;
- mpi->h = vf->h;
- // keep buffer allocation status & color flags only:
- mpi->flags &= MP_IMGFLAG_ALLOCATED | MP_IMGFLAG_TYPE_DISPLAYED |
- MP_IMGFLAGMASK_COLORS;
- // accept restrictions, palette flags only:
- mpi->flags |= mp_imgflag & (MP_IMGFLAGMASK_RESTRICTIONS |
- MP_IMGFLAG_RGB_PALETTE);
- if (mpi->width != w2 || mpi->height != h || missing_palette) {
- if (mpi->flags & MP_IMGFLAG_ALLOCATED) {
- if (mpi->width < w2 || mpi->height < h || missing_palette) {
- // need to re-allocate buffer memory:
- av_free(mpi->planes[0]);
- if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
- av_free(mpi->planes[1]);
- for (int n = 0; n < MP_MAX_PLANES; n++)
- mpi->planes[n] = NULL;
- mpi->flags &= ~MP_IMGFLAG_ALLOCATED;
- mp_msg(MSGT_VFILTER, MSGL_V,
- "vf.c: have to REALLOCATE buffer memory :(\n");
- }
- }
- mpi->width = w2;
- mpi->chroma_width = (w2 + (1 << mpi->chroma_x_shift) - 1) >>
- mpi->chroma_x_shift;
- mpi->height = h;
- mpi->chroma_height = (h + (1 << mpi->chroma_y_shift) - 1) >>
- mpi->chroma_y_shift;
- }
- if (!mpi->bpp)
- mp_image_setfmt(mpi, outfmt);
- if (!(mpi->flags & MP_IMGFLAG_ALLOCATED) &&
- mpi->type > MP_IMGTYPE_EXPORT) {
- // check libvo first!
- if (vf->get_image)
- vf->get_image(vf, mpi);
-
- if (!(mpi->flags & MP_IMGFLAG_DIRECT)) {
- // non-direct and not yet allocated image. allocate it!
- if (!mpi->bpp) { // no way we can allocate this
- mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
- "vf_get_image: Tried to allocate a format that "
- "can not be allocated!\n");
- return NULL;
- }
-
- // check if codec prefer aligned stride:
- if (mp_imgflag & MP_IMGFLAG_PREFER_ALIGNED_STRIDE) {
- int align = (mpi->flags & MP_IMGFLAG_PLANAR &&
- mpi->flags & MP_IMGFLAG_YUV) ?
- (16 << mpi->chroma_x_shift) - 1 : 32; // OK?
- w2 = FFALIGN(w, align);
- if (mpi->width != w2) {
- // we have to change width... check if we CAN co it:
- int flags = vf->query_format(vf, outfmt);
- // should not fail
- if (!(flags & (VFCAP_CSP_SUPPORTED |
- VFCAP_CSP_SUPPORTED_BY_HW)))
- mp_msg(MSGT_DECVIDEO, MSGL_WARN,
- "??? vf_get_image{vf->query_format(outfmt)} "
- "failed!\n");
- if (flags & VFCAP_ACCEPT_STRIDE) {
- mpi->width = w2;
- mpi->chroma_width =
- (w2 + (1 << mpi->chroma_x_shift) - 1) >>
- mpi->chroma_x_shift;
- }
- }
- }
+ 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);
+}
- mp_image_alloc_planes(mpi);
- vf_mpi_clear(mpi, 0, 0, mpi->width, mpi->height);
- }
- }
- if (!(mpi->flags & MP_IMGFLAG_TYPE_DISPLAYED)) {
- mp_msg(MSGT_DECVIDEO, MSGL_V,
- "*** [%s] %s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
- vf->info->name,
- (mpi->type == MP_IMGTYPE_EXPORT) ? "Exporting" :
- ((mpi->flags & MP_IMGFLAG_DIRECT) ?
- "Direct Rendering" : "Allocating"),
- mpi->width, mpi->height, mpi->bpp,
- (mpi->flags & MP_IMGFLAG_YUV) ? "YUV" :
- ((mpi->flags & MP_IMGFLAG_SWAPPED) ? "BGR" : "RGB"),
- (mpi->flags & MP_IMGFLAG_PLANAR) ? "planar" : "packed",
- mpi->bpp * mpi->width * mpi->height / 8);
- mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "(imgfmt: %x, planes: %p,%p,%p "
- "strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
- mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
- mpi->stride[0], mpi->stride[1], mpi->stride[2],
- mpi->chroma_width, mpi->chroma_height,
- mpi->chroma_x_shift, mpi->chroma_y_shift);
- mpi->flags |= MP_IMGFLAG_TYPE_DISPLAYED;
- }
- mpi->qscale = NULL;
- mpi->usage_count++;
- }
- return mpi;
+void vf_make_out_image_writeable(struct vf_instance *vf, struct mp_image *img)
+{
+ 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);
+ mp_image_pool_make_writeable(vf->out_pool, img);
}
//============================================================================
@@ -362,6 +202,14 @@ static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt)
return vf_next_query_format(vf, fmt);
}
+
+static struct mp_image *vf_default_filter(struct vf_instance *vf,
+ struct mp_image *mpi)
+{
+ assert(!vf->filter_ext);
+ return mpi;
+}
+
struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
const vf_info_t *const *filter_list,
vf_instance_t *next, const char *name,
@@ -378,16 +226,15 @@ struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
if (!strcmp(filter_list[i]->name, name))
break;
}
- vf = calloc(1, sizeof *vf);
+ vf = talloc_zero(NULL, struct vf_instance);
vf->opts = opts;
vf->info = filter_list[i];
vf->next = next;
vf->config = vf_next_config;
vf->control = vf_next_control;
vf->query_format = vf_default_query_format;
- vf->put_image = vf_next_put_image;
- vf->default_caps = VFCAP_ACCEPT_STRIDE;
- vf->default_reqs = 0;
+ vf->filter = vf_default_filter;
+ vf->out_pool = talloc_steal(vf, mp_image_pool_new(16));
if (vf->info->opts) { // vf_vo get some special argument
const m_struct_t *st = vf->info->opts;
void *vf_priv = m_struct_alloc(st);
@@ -404,7 +251,7 @@ struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
*retcode = vf->info->vf_open(vf, (char *)args);
if (*retcode > 0)
return vf;
- free(vf);
+ talloc_free(vf);
return NULL;
}
@@ -530,6 +377,7 @@ void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
dst->pict_type = src->pict_type;
dst->fields = src->fields;
dst->qscale_type = src->qscale_type;
+ dst->pts = src->pts;
if (dst->width == src->width && dst->height == src->height) {
dst->qstride = src->qstride;
dst->qscale = src->qscale;
@@ -542,60 +390,84 @@ void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
}
}
-void vf_queue_frame(vf_instance_t *vf, int (*func)(vf_instance_t *))
+// Used by filters to add a filtered frame to the output queue.
+// Ownership of img is transferred from caller to the filter chain.
+void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img)
{
- vf->continue_buffered_image = func;
+ if (img)
+ MP_TARRAY_APPEND(vf, vf->out_queued, vf->num_out_queued, img);
}
-// Output the next buffered image (if any) from the filter chain.
-// The queue could be kept as a simple stack/list instead avoiding the
-// looping here, but there's currently no good context variable where
-// that could be stored so this was easier to implement.
+static struct mp_image *vf_dequeue_output_frame(struct vf_instance *vf)
+{
+ struct mp_image *res = NULL;
+ if (vf->num_out_queued) {
+ res = vf->out_queued[0];
+ MP_TARRAY_REMOVE_AT(vf->out_queued, vf->num_out_queued, 0);
+ }
+ return res;
+}
+
+// Input a frame into the filter chain.
+// 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)
+{
+ 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);
+
+ if (vf->filter_ext) {
+ return vf->filter_ext(vf, img);
+ } else {
+ vf_add_output_frame(vf, vf->filter(vf, img));
+ return 0;
+ }
+}
-int vf_output_queued_frame(vf_instance_t *vf)
+// Output the next queued image (if any) from the full filter chain.
+struct mp_image *vf_chain_output_queued_frame(struct vf_instance *vf)
{
while (1) {
- int ret;
- vf_instance_t *current;
- vf_instance_t *last = NULL;
- int (*tmp)(vf_instance_t *);
- for (current = vf; current; current = current->next)
- if (current->continue_buffered_image)
- last = current;
+ struct vf_instance *last = NULL;
+ for (struct vf_instance * cur = vf; cur; cur = cur->next) {
+ if (cur->num_out_queued)
+ last = cur;
+ }
if (!last)
- return 0;
- tmp = last->continue_buffered_image;
- last->continue_buffered_image = NULL;
- ret = tmp(last);
- if (ret)
- return ret;
+ return NULL;
+ struct mp_image *img = vf_dequeue_output_frame(last);
+ if (!last->next)
+ return img;
+ vf_filter_frame(last->next, img);
}
}
+static void vf_forget_frames(struct vf_instance *vf)
+{
+ for (int n = 0; n < vf->num_out_queued; n++)
+ talloc_free(vf->out_queued[n]);
+ vf->num_out_queued = 0;
+}
-/**
- * \brief Video config() function wrapper
- *
- * Blocks config() calls with different size or format for filters
- * with VFCAP_CONSTANT
- *
- * First call is redirected to vf->config.
- *
- * In following calls, it verifies that the configuration parameters
- * are unchanged, and returns either success or error.
- *
- */
int vf_config_wrapper(struct vf_instance *vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt)
{
- vf->fmt.have_configured = 1;
- vf->fmt.orig_height = height;
- vf->fmt.orig_width = width;
- vf->fmt.orig_fmt = outfmt;
+ 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.have_configured = 0;
+ if (r) {
+ vf->fmt_in = (struct vf_format) {
+ .configured = 1,
+ .w = width,
+ .h = height,
+ .fmt = outfmt,
+ };
+ vf->fmt_out = vf->next ? vf->next->fmt_in : (struct vf_format){0};
+ }
return r;
}
@@ -604,7 +476,6 @@ int vf_next_config(struct vf_instance *vf,
unsigned int voflags, unsigned int outfmt)
{
struct MPOpts *opts = vf->opts;
- int miss;
int flags = vf->next->query_format(vf->next, outfmt);
if (!flags) {
// hmm. colorspace mismatch!!!
@@ -623,19 +494,6 @@ int vf_next_config(struct vf_instance *vf,
return 0; // FAIL
}
}
- mp_msg(MSGT_VFILTER, MSGL_V, "REQ: flags=0x%X req=0x%X \n",
- flags, vf->default_reqs);
- miss = vf->default_reqs - (flags & vf->default_reqs);
- if (miss & VFCAP_ACCEPT_STRIDE) {
- // vf requires stride support but vf->next doesn't support it!
- // let's insert the 'expand' filter, it does the job for us:
- vf_instance_t *vf2 = vf_open_filter(opts, vf->next, "expand", NULL);
- if (!vf2)
- return 0; // shouldn't happen!
- vf->next = vf2;
- }
- vf->next->w = width;
- vf->next->h = height;
return vf_config_wrapper(vf->next, width, height, d_width, d_height,
voflags, outfmt);
}
@@ -653,11 +511,6 @@ int vf_next_query_format(struct vf_instance *vf, unsigned int fmt)
return flags;
}
-int vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
-{
- return vf->next->put_image(vf->next, mpi, pts);
-}
-
//============================================================================
vf_instance_t *append_filters(vf_instance_t *last,
@@ -688,13 +541,8 @@ void vf_uninit_filter(vf_instance_t *vf)
{
if (vf->uninit)
vf->uninit(vf);
- free_mp_image(vf->imgctx.static_images[0]);
- free_mp_image(vf->imgctx.static_images[1]);
- free_mp_image(vf->imgctx.temp_images[0]);
- free_mp_image(vf->imgctx.export_images[0]);
- for (int i = 0; i < NUM_NUMBERED_MPI; i++)
- free_mp_image(vf->imgctx.numbered_images[i]);
- free(vf);
+ vf_forget_frames(vf);
+ talloc_free(vf);
}
void vf_uninit_filter_chain(vf_instance_t *vf)
diff --git a/video/filter/vf.h b/video/filter/vf.h
index 1a850995f3..ac9394024f 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -41,19 +41,9 @@ typedef struct vf_info {
const void *opts;
} vf_info_t;
-#define NUM_NUMBERED_MPI 50
-
-struct vf_image_context {
- mp_image_t *static_images[2];
- mp_image_t *temp_images[1];
- mp_image_t *export_images[1];
- mp_image_t *numbered_images[NUM_NUMBERED_MPI];
- int static_idx;
-};
-
-struct vf_format_context {
- int have_configured;
- int orig_width, orig_height, orig_fmt;
+struct vf_format {
+ int configured;
+ int w, h, fmt;
};
typedef struct vf_instance {
@@ -64,22 +54,31 @@ typedef struct vf_instance {
unsigned int flags, unsigned int outfmt);
int (*control)(struct vf_instance *vf, int request, void *data);
int (*query_format)(struct vf_instance *vf, unsigned int fmt);
- void (*get_image)(struct vf_instance *vf, mp_image_t *mpi);
- int (*put_image)(struct vf_instance *vf, mp_image_t *mpi, double pts);
+
+ // Filter mpi and return the result. The input mpi reference is owned by
+ // the filter, the returned reference is owned by the caller.
+ // Return NULL if the output frame is skipped.
+ struct mp_image *(*filter)(struct vf_instance *vf, struct mp_image *mpi);
+
+ // Like filter(), but can return an error code ( >= 0 means success). This
+ // callback is also more practical when the filter can return multiple
+ // output images. Use vf_add_output_frame() to queue output frames.
+ int (*filter_ext)(struct vf_instance *vf, struct mp_image *mpi);
+
void (*uninit)(struct vf_instance *vf);
- int (*continue_buffered_image)(struct vf_instance *vf);
// caps:
unsigned int default_caps; // used by default query_format()
- unsigned int default_reqs; // used by default config()
// data:
- int w, h;
- struct vf_image_context imgctx;
- struct vf_format_context fmt;
+ struct vf_format fmt_in, fmt_out;
struct vf_instance *next;
- mp_image_t *dmpi;
+
+ struct mp_image_pool *out_pool;
struct vf_priv_s *priv;
struct MPOpts *opts;
+
+ struct mp_image **out_queued;
+ int num_out_queued;
} vf_instance_t;
typedef struct vf_seteq {
@@ -98,7 +97,7 @@ struct vf_ctrl_screenshot {
#define VFCTRL_SET_EQUALIZER 6 // set color options (brightness,contrast etc)
#define VFCTRL_GET_EQUALIZER 8 // get color options (brightness,contrast etc)
#define VFCTRL_HWDEC_DECODER_RENDER 9 // vdpau hw decoding
-#define VFCTRL_HWDEC_GET_SURFACE 10 // vdpau hw decoding
+#define VFCTRL_HWDEC_ALLOC_SURFACE 10 // vdpau hw decoding
#define VFCTRL_SCREENSHOT 14 // Take screenshot, arg is vf_ctrl_screenshot
#define VFCTRL_INIT_OSD 15 // Filter OSD renderer present?
#define VFCTRL_SET_DEINTERLACE 18 // Set deinterlacing status
@@ -111,8 +110,13 @@ struct vf_ctrl_screenshot {
// functions:
void vf_mpi_clear(mp_image_t *mpi, int x0, int y0, int w, int h);
-mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt,
- int mp_imgtype, int mp_imgflag, int w, int h);
+
+struct mp_image *vf_alloc_out_image(struct vf_instance *vf);
+void vf_make_out_image_writeable(struct vf_instance *vf, struct mp_image *img);
+void vf_add_output_frame(struct vf_instance *vf, struct mp_image *img);
+
+int vf_filter_frame(struct vf_instance *vf, struct mp_image *img);
+struct mp_image *vf_chain_output_queued_frame(struct vf_instance *vf);
vf_instance_t *vf_open_plugin(struct MPOpts *opts,
const vf_info_t * const *filter_list, vf_instance_t *next,
@@ -123,14 +127,10 @@ struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
vf_instance_t *vf_open_filter(struct MPOpts *opts, vf_instance_t *next,
const char *name, char **args);
vf_instance_t *vf_add_before_vo(vf_instance_t **vf, char *name, char **args);
-vf_instance_t *vf_open_encoder(struct MPOpts *opts, vf_instance_t *next,
- const char *name, char *args);
unsigned int vf_match_csp(vf_instance_t **vfp, const unsigned int *list,
unsigned int preferred);
void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src);
-void vf_queue_frame(vf_instance_t *vf, int (*)(vf_instance_t *));
-int vf_output_queued_frame(vf_instance_t *vf);
// default wrappers:
int vf_next_config(struct vf_instance *vf,
@@ -138,7 +138,6 @@ int vf_next_config(struct vf_instance *vf,
unsigned int flags, unsigned int outfmt);
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_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);
struct m_obj_settings;
vf_instance_t *append_filters(vf_instance_t *last,
diff --git a/video/filter/vf_crop.c b/video/filter/vf_crop.c
index ed3457da70..692d05bcc9 100644
--- a/video/filter/vf_crop.c
+++ b/video/filter/vf_crop.c
@@ -84,11 +84,9 @@ static int config(struct vf_instance *vf,
return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt);
}
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
- mp_image_t *dmpi;
- dmpi=vf_get_image(vf->next,mpi->imgfmt,
- MP_IMGTYPE_EXPORT, 0,
- vf->priv->crop_w, vf->priv->crop_h);
+static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
+{
+ mp_image_t *dmpi = mpi;
if(mpi->flags&MP_IMGFLAG_PLANAR){
dmpi->planes[0]=mpi->planes[0]+
vf->priv->crop_y*mpi->stride[0]+vf->priv->crop_x;
@@ -102,19 +100,16 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
dmpi->planes[0]=mpi->planes[0]+
vf->priv->crop_y*mpi->stride[0]+
vf->priv->crop_x*(mpi->bpp/8);
- dmpi->planes[1]=mpi->planes[1]; // passthrough rgb8 palette
}
- dmpi->stride[0]=mpi->stride[0];
- dmpi->width=mpi->width;
- return vf_next_put_image(vf,dmpi, pts);
+ mp_image_set_size(dmpi, vf->priv->crop_w, vf->priv->crop_h);
+ return mpi;
}
//===========================================================================//
static int vf_open(vf_instance_t *vf, char *args){
vf->config=config;
- vf->put_image=put_image;
- vf->default_reqs=VFCAP_ACCEPT_STRIDE;
+ vf->filter=filter;
mp_msg(MSGT_VFILTER, MSGL_INFO, "Crop: %d x %d, %d ; %d\n",
vf->priv->crop_w,
vf->priv->crop_h,
diff --git a/video/filter/vf_delogo.c b/video/filter/vf_delogo.c
index f53e5059bd..f709aad4d0 100644
--- a/video/filter/vf_delogo.c
+++ b/video/filter/vf_delogo.c
@@ -101,7 +101,7 @@ static void update_sub(struct vf_priv_s *p, double pts)
}
static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height,
- int logo_x, int logo_y, int logo_w, int logo_h, int band, int show, int direct) {
+ int logo_x, int logo_y, int logo_w, int logo_h, int band, int show) {
int y, x;
int interp, dist;
uint8_t *xdst, *xsrc;
@@ -124,8 +124,6 @@ static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int
topright = src+logo_y1*srcStride+logo_x2-1;
botleft = src+(logo_y2-1)*srcStride+logo_x1;
- if (!direct) memcpy_pic(dst, src, width, height, dstStride, srcStride);
-
dst += (logo_y1+1)*dstStride;
src += (logo_y1+1)*srcStride;
@@ -175,55 +173,26 @@ static int config(struct vf_instance *vf,
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
-
-static void get_image(struct vf_instance *vf, mp_image_t *mpi){
- if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
- if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ
- // ok, we can do pp in-place (or pp disabled):
- mpi->priv =
- vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
- mpi->type, mpi->flags, mpi->w, mpi->h);
- mpi->planes[0]=vf->dmpi->planes[0];
- mpi->stride[0]=vf->dmpi->stride[0];
- mpi->width=vf->dmpi->width;
- if(mpi->flags&MP_IMGFLAG_PLANAR){
- mpi->planes[1]=vf->dmpi->planes[1];
- mpi->planes[2]=vf->dmpi->planes[2];
- mpi->stride[1]=vf->dmpi->stride[1];
- mpi->stride[2]=vf->dmpi->stride[2];
- }
- mpi->flags|=MP_IMGFLAG_DIRECT;
-}
-
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
- mp_image_t *dmpi;
-
- if(mpi->flags&MP_IMGFLAG_DIRECT) {
- vf->dmpi = mpi->priv;
- mpi->priv = NULL;
- } else {
- // no DR, so get a new image! hope we'll get DR buffer:
- vf->dmpi=vf_get_image(vf->next,vf->priv->outfmt,
- MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
- mpi->w,mpi->h);
+static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
+{
+ struct mp_image *dmpi = mpi;
+ if (!mp_image_is_writeable(mpi)) {
+ dmpi = vf_alloc_out_image(vf);
+ mp_image_copy_attributes(dmpi, mpi);
}
- dmpi= vf->dmpi;
if (vf->priv->timed_rect)
- update_sub(vf->priv, pts);
+ update_sub(vf->priv, dmpi->pts);
delogo(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h,
- vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show,
- mpi->flags&MP_IMGFLAG_DIRECT);
+ vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show);
delogo(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2,
- vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show,
- mpi->flags&MP_IMGFLAG_DIRECT);
+ vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show);
delogo(dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2,
- vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show,
- mpi->flags&MP_IMGFLAG_DIRECT);
-
- vf_clone_mpi_attributes(dmpi, mpi);
+ vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show);
- return vf_next_put_image(vf,dmpi, pts);
+ if (dmpi != mpi)
+ talloc_free(mpi);
+ return dmpi;
}
static void uninit(struct vf_instance *vf){
@@ -323,8 +292,7 @@ load_error:
static int vf_open(vf_instance_t *vf, char *args){
vf->config=config;
- vf->put_image=put_image;
- vf->get_image=get_image;
+ vf->filter=filter;
vf->query_format=query_format;
vf->uninit=uninit;
diff --git a/video/filter/vf_divtc.c b/video/filter/vf_divtc.c
index 02386d0d3b..dadccf9a9b 100644
--- a/video/filter/vf_divtc.c
+++ b/video/filter/vf_divtc.c
@@ -46,6 +46,7 @@ struct vf_priv_s
unsigned int *csdata;
int *history;
struct vf_detc_pts_buf ptsbuf;
+ struct mp_image *buffer;
};
/*
@@ -258,19 +259,23 @@ static int match(struct vf_priv_s *p, int *diffs,
return m;
}
-static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
{
- mp_image_t *dmpi, *tmpi=0;
int n, m, f, newphase;
struct vf_priv_s *p=vf->priv;
unsigned int checksum;
double d;
- dmpi=vf_get_image(vf->next, mpi->imgfmt,
- MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
- MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABL