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
This commit is contained in:
Stefano Sabatini 2010-12-23 17:24:19 +00:00
parent 8399d23517
commit cf69ad35c5
7 changed files with 103 additions and 24 deletions

View File

@ -66,6 +66,7 @@ version <next>:
- FLAC parser added - FLAC parser added
- gradfun filter added - gradfun filter added
- AMR-WB decoder - AMR-WB decoder
- replace the ocv_smooth filter by a more generic ocv filter
version 0.6: version 0.6:

2
configure vendored
View File

@ -1413,7 +1413,7 @@ cropdetect_filter_deps="gpl"
frei0r_filter_deps="frei0r dlopen strtok_r" frei0r_filter_deps="frei0r dlopen strtok_r"
frei0r_src_filter_deps="frei0r dlopen strtok_r" frei0r_src_filter_deps="frei0r dlopen strtok_r"
hqdn3d_filter_deps="gpl" hqdn3d_filter_deps="gpl"
ocv_smooth_filter_deps="libopencv" ocv_filter_deps="libopencv"
yadif_filter_deps="gpl" yadif_filter_deps="gpl"
# libraries # libraries

View File

@ -512,14 +512,31 @@ input to the vflip filter.
Pass the video source unchanged to the output. 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 To enable this filter install libopencv library and headers and
configure FFmpeg with --enable-libopencv. 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}:@var{param1}:@var{param2}:@var{param3}:@var{param4}.
@var{type} is the type of smooth filter to apply, and can be one of @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. other parameters is 0.
These parameters correspond to the parameters assigned to the These parameters correspond to the parameters assigned to the
libopencv function @code{cvSmooth}. Refer to the official libopencv libopencv function @code{cvSmooth}.
documentation for the exact meaning of the parameters:
@url{http://opencv.willowgarage.com/documentation/c/image_filtering.html}
@section overlay @section overlay

View File

@ -31,7 +31,7 @@ OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o
OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o
OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o
OBJS-$(CONFIG_NULL_FILTER) += vf_null.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_OVERLAY_FILTER) += vf_overlay.o
OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o
OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o

View File

@ -52,7 +52,7 @@ void avfilter_register_all(void)
REGISTER_FILTER (HQDN3D, hqdn3d, vf); REGISTER_FILTER (HQDN3D, hqdn3d, vf);
REGISTER_FILTER (NOFORMAT, noformat, vf); REGISTER_FILTER (NOFORMAT, noformat, vf);
REGISTER_FILTER (NULL, null, 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 (OVERLAY, overlay, vf);
REGISTER_FILTER (PAD, pad, vf); REGISTER_FILTER (PAD, pad, vf);
REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf); REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf);

View File

@ -27,7 +27,7 @@
#include "libavcore/samplefmt.h" #include "libavcore/samplefmt.h"
#define LIBAVFILTER_VERSION_MAJOR 1 #define LIBAVFILTER_VERSION_MAJOR 1
#define LIBAVFILTER_VERSION_MINOR 69 #define LIBAVFILTER_VERSION_MINOR 70
#define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \

View File

@ -63,7 +63,13 @@ static int query_formats(AVFilterContext *ctx)
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } 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 { typedef struct {
int type; int type;
@ -73,7 +79,8 @@ typedef struct {
static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opaque) 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"; char type_str[128] = "gaussian";
smooth->param1 = 3; smooth->param1 = 3;
@ -113,17 +120,74 @@ static av_cold int smooth_init(AVFilterContext *ctx, const char *args, void *opa
return 0; 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; OCVContext *ocv = ctx->priv;
AVFilterLink *outlink = inlink->dst->outputs[0]; 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 *inpicref = inlink ->cur_buf;
AVFilterBufferRef *outpicref = outlink->out_buf; AVFilterBufferRef *outpicref = outlink->out_buf;
IplImage inimg, outimg; IplImage inimg, outimg;
fill_iplimage_from_picref(&inimg , inpicref , inlink->format); fill_iplimage_from_picref(&inimg , inpicref , inlink->format);
fill_iplimage_from_picref(&outimg, outpicref, 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); fill_picref_from_iplimage(outpicref, &outimg, inlink->format);
avfilter_unref_buffer(inpicref); avfilter_unref_buffer(inpicref);
@ -132,19 +196,20 @@ static void smooth_end_frame(AVFilterLink *inlink)
avfilter_unref_buffer(outpicref); avfilter_unref_buffer(outpicref);
} }
AVFilter avfilter_vf_ocv_smooth = { AVFilter avfilter_vf_ocv = {
.name = "ocv_smooth", .name = "ocv",
.description = NULL_IF_CONFIG_SMALL("Apply smooth transform using libopencv."), .description = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."),
.priv_size = sizeof(SmoothContext), .priv_size = sizeof(OCVContext),
.query_formats = query_formats, .query_formats = query_formats,
.init = smooth_init, .init = init,
.uninit = uninit,
.inputs = (AVFilterPad[]) {{ .name = "default", .inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.draw_slice = null_draw_slice, .draw_slice = null_draw_slice,
.end_frame = smooth_end_frame, .end_frame = end_frame,
.min_perms = AV_PERM_READ }, .min_perms = AV_PERM_READ },
{ .name = NULL}}, { .name = NULL}},
@ -152,5 +217,3 @@ AVFilter avfilter_vf_ocv_smooth = {
.type = AVMEDIA_TYPE_VIDEO, }, .type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}}, { .name = NULL}},
}; };
#endif /* CONFIG_OCV_SMOOTH_FILTER */