diff options
Diffstat (limited to 'video/filter')
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_ |