From cf69ad35c5a7aab9cf056f957bfea484e849527c Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Thu, 23 Dec 2010 17:24:19 +0000 Subject: Redesign the libopencv wrapper to make it more generic. Accept both FILTERNAME=ARGS and FILTERNAME:ARGS syntax. The same filter class will be used for managing all the libopencv filtering functions. Originally committed as revision 26079 to svn://svn.ffmpeg.org/ffmpeg/trunk --- Changelog | 1 + configure | 2 +- doc/filters.texi | 27 +++++++++++--- libavfilter/Makefile | 2 +- libavfilter/allfilters.c | 2 +- libavfilter/avfilter.h | 2 +- libavfilter/vf_libopencv.c | 91 +++++++++++++++++++++++++++++++++++++++------- 7 files changed, 103 insertions(+), 24 deletions(-) diff --git a/Changelog b/Changelog index b56a31dcf9..c0bef59891 100644 --- a/Changelog +++ b/Changelog @@ -66,6 +66,7 @@ version : - FLAC parser added - gradfun filter added - AMR-WB decoder +- replace the ocv_smooth filter by a more generic ocv filter version 0.6: diff --git a/configure b/configure index 62f43a3130..3176a89288 100755 --- a/configure +++ b/configure @@ -1413,7 +1413,7 @@ cropdetect_filter_deps="gpl" frei0r_filter_deps="frei0r dlopen strtok_r" frei0r_src_filter_deps="frei0r dlopen strtok_r" hqdn3d_filter_deps="gpl" -ocv_smooth_filter_deps="libopencv" +ocv_filter_deps="libopencv" yadif_filter_deps="gpl" # libraries diff --git a/doc/filters.texi b/doc/filters.texi index 9efed219aa..e217f4e906 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -512,14 +512,31 @@ input to the vflip filter. Pass the video source unchanged to the output. -@section ocv_smooth +@section ocv -Apply smooth transform using libopencv. +Apply video transform using libopencv. To enable this filter install libopencv library and headers and configure FFmpeg with --enable-libopencv. -The filter accepts the following parameters: +The filter takes the parameters: @var{filter_name}@{:=@}@var{filter_params}. + +@var{filter_name} is the name of the libopencv filter to apply. + +@var{filter_params} specifies the parameters to pass to the libopencv +filter. If not specified the default values are assumed. + +Refer to the official libopencv documentation for more precise +informations: +@url{http://opencv.willowgarage.com/documentation/c/image_filtering.html} + +Follows the list of supported libopencv filters. + +@subsection smooth + +Smooth the input video. + +The filter takes the following parameters: @var{type}:@var{param1}:@var{param2}:@var{param3}:@var{param4}. @var{type} is the type of smooth filter to apply, and can be one of @@ -535,9 +552,7 @@ The default value for @var{param1} is 3, the default value for the other parameters is 0. These parameters correspond to the parameters assigned to the -libopencv function @code{cvSmooth}. Refer to the official libopencv -documentation for the exact meaning of the parameters: -@url{http://opencv.willowgarage.com/documentation/c/image_filtering.html} +libopencv function @code{cvSmooth}. @section overlay diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 14666458f8..a010fd90b1 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -31,7 +31,7 @@ OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NULL_FILTER) += vf_null.o -OBJS-$(CONFIG_OCV_SMOOTH_FILTER) += vf_libopencv.o +OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 7f7e46d448..886a50a677 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -52,7 +52,7 @@ void avfilter_register_all(void) REGISTER_FILTER (HQDN3D, hqdn3d, vf); REGISTER_FILTER (NOFORMAT, noformat, vf); REGISTER_FILTER (NULL, null, vf); - REGISTER_FILTER (OCV_SMOOTH, ocv_smooth, vf); + REGISTER_FILTER (OCV, ocv, vf); REGISTER_FILTER (OVERLAY, overlay, vf); REGISTER_FILTER (PAD, pad, vf); REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf); diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index a4bc978eba..01cda126c2 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -27,7 +27,7 @@ #include "libavcore/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 1 -#define LIBAVFILTER_VERSION_MINOR 69 +#define LIBAVFILTER_VERSION_MINOR 70 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 0eafeb6789..dce22f7ae6 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -63,7 +63,13 @@ static int query_formats(AVFilterContext *ctx) static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } -#if CONFIG_OCV_SMOOTH_FILTER +typedef struct { + const char *name; + int (*init)(AVFilterContext *ctx, const char *args, void *opaque); + void (*uninit)(AVFilterContext *ctx); + void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg); + void *priv; +} OCVContext; typedef struct { int type; @@ -73,7 +79,8 @@ typedef struct { static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opaque) { - SmoothContext *smooth = ctx->priv; + OCVContext *ocv = ctx->priv; + SmoothContext *smooth = ocv->priv; char type_str[128] = "gaussian"; smooth->param1 = 3; @@ -113,17 +120,74 @@ static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opa return 0; } -static void smooth_end_frame(AVFilterLink *inlink) +static void smooth_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg) { - SmoothContext *smooth = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; + OCVContext *ocv = ctx->priv; + SmoothContext *smooth = ocv->priv; + cvSmooth(inimg, outimg, smooth->type, smooth->param1, smooth->param2, smooth->param3, smooth->param4); +} + +typedef struct { + const char *name; + size_t priv_size; + int (*init)(AVFilterContext *ctx, const char *args, void *opaque); + void (*uninit)(AVFilterContext *ctx); + void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg); +} OCVFilterEntry; + +static OCVFilterEntry ocv_filter_entries[] = { + { "smooth", sizeof(SmoothContext), smooth_init, NULL, smooth_end_frame_filter }, +}; + +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + OCVContext *ocv = ctx->priv; + char name[128], priv_args[1024]; + int i; + char c; + + sscanf(args, "%127[^=:]%c%1023s", name, &c, priv_args); + + for (i = 0; i < FF_ARRAY_ELEMS(ocv_filter_entries); i++) { + OCVFilterEntry *entry = &ocv_filter_entries[i]; + if (!strcmp(name, entry->name)) { + ocv->name = entry->name; + ocv->init = entry->init; + ocv->uninit = entry->uninit; + ocv->end_frame_filter = entry->end_frame_filter; + + if (!(ocv->priv = av_mallocz(entry->priv_size))) + return AVERROR(ENOMEM); + return ocv->init(ctx, priv_args, opaque); + } + } + + av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", name); + return AVERROR(EINVAL); +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + OCVContext *ocv = ctx->priv; + + if (ocv->uninit) + ocv->uninit(ctx); + av_free(ocv->priv); + memset(ocv, 0, sizeof(*ocv)); +} + +static void end_frame(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + OCVContext *ocv = ctx->priv; + AVFilterLink *outlink= inlink->dst->outputs[0]; AVFilterBufferRef *inpicref = inlink ->cur_buf; AVFilterBufferRef *outpicref = outlink->out_buf; IplImage inimg, outimg; fill_iplimage_from_picref(&inimg , inpicref , inlink->format); fill_iplimage_from_picref(&outimg, outpicref, inlink->format); - cvSmooth(&inimg, &outimg, smooth->type, smooth->param1, smooth->param2, smooth->param3, smooth->param4); + ocv->end_frame_filter(ctx, &inimg, &outimg); fill_picref_from_iplimage(outpicref, &outimg, inlink->format); avfilter_unref_buffer(inpicref); @@ -132,19 +196,20 @@ static void smooth_end_frame(AVFilterLink *inlink) avfilter_unref_buffer(outpicref); } -AVFilter avfilter_vf_ocv_smooth = { - .name = "ocv_smooth", - .description = NULL_IF_CONFIG_SMALL("Apply smooth transform using libopencv."), +AVFilter avfilter_vf_ocv = { + .name = "ocv", + .description = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."), - .priv_size = sizeof(SmoothContext), + .priv_size = sizeof(OCVContext), .query_formats = query_formats, - .init = smooth_init, + .init = init, + .uninit = uninit, .inputs = (AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .draw_slice = null_draw_slice, - .end_frame = smooth_end_frame, + .end_frame = end_frame, .min_perms = AV_PERM_READ }, { .name = NULL}}, @@ -152,5 +217,3 @@ AVFilter avfilter_vf_ocv_smooth = { .type = AVMEDIA_TYPE_VIDEO, }, { .name = NULL}}, }; - -#endif /* CONFIG_OCV_SMOOTH_FILTER */ -- cgit v1.2.3