[FFmpeg-soc] [soc]: r316 - in libavfilter: avfilter.c avfilter.h filter_test.c vf_crop.c vo_sdl.c vsrc_dummy.c
koorogi
subversion at mplayerhq.hu
Thu Jul 5 22:48:48 CEST 2007
Author: koorogi
Date: Thu Jul 5 22:48:48 2007
New Revision: 316
Log:
Rework filter initialization sequence. Now supports passing user parameters,
querying supported colorspaces, etc.
Modified:
libavfilter/avfilter.c
libavfilter/avfilter.h
libavfilter/filter_test.c
libavfilter/vf_crop.c
libavfilter/vo_sdl.c
libavfilter/vsrc_dummy.c
Modified: libavfilter/avfilter.c
==============================================================================
--- libavfilter/avfilter.c (original)
+++ libavfilter/avfilter.c Thu Jul 5 22:48:48 2007
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -91,6 +92,7 @@ int avfilter_link(AVFilterContext *src,
AVFilterContext *dst, unsigned dstpad)
{
AVFilterLink *link;
+ int *fmts[2], i, j;
if(src->outputs[srcpad] || dst->inputs[dstpad])
return -1;
@@ -104,7 +106,29 @@ int avfilter_link(AVFilterContext *src,
link->dstpad = dstpad;
link->cur_pic = NULL;
- src->filter->outputs[dstpad].set_video_props(link);
+ /* find a format both filters support - TODO: auto-insert conversion filter */
+ fmts[0] = src->filter->outputs[srcpad].query_formats(link);
+ fmts[1] = dst->filter->inputs[dstpad].query_formats(link);
+ for(i = 0; fmts[0][i] != -1; i ++)
+ for(j = 0; fmts[1][j] != -1; j ++)
+ if(fmts[0][i] == fmts[1][j]) {
+ link->format = fmts[0][i];
+ goto format_done;
+ }
+
+format_done:
+ av_free(fmts[0]);
+ av_free(fmts[1]);
+ if(link->format == -1) {
+ /* failed to find a format. fail at creating the link */
+ av_free(link);
+ src->outputs[srcpad] = NULL;
+ dst->inputs[dstpad] = NULL;
+ return -1;
+ }
+
+ src->filter->outputs[srcpad].config_props(link);
+ dst->filter->inputs[dstpad].config_props(link);
return 0;
}
@@ -263,9 +287,21 @@ int avfilter_init_filter(AVFilterContext
if(filter->filter->init)
if((ret = filter->filter->init(filter, args))) return ret;
- for(i = 0; i < pad_count(filter->filter->outputs); i ++)
- if(filter->outputs[i])
- filter->filter->outputs[i].set_video_props(filter->outputs[i]);
return 0;
}
+int *avfilter_make_format_list(int len, ...)
+{
+ int *ret, i;
+ va_list vl;
+
+ ret = av_malloc(sizeof(int) * (len + 1));
+ va_start(vl, len);
+ for(i = 0; i < len; i ++)
+ ret[i] = va_arg(vl, int);
+ va_end(vl);
+ ret[len] = -1;
+
+ return ret;
+}
+
Modified: libavfilter/avfilter.h
==============================================================================
--- libavfilter/avfilter.h (original)
+++ libavfilter/avfilter.h Thu Jul 5 22:48:48 2007
@@ -99,6 +99,13 @@ struct AVFilterPad
#define AV_PAD_VIDEO 0
/**
+ * Callback to get a list of supported formats. The returned list should
+ * be terminated by -1. This is used for both input and output pads and
+ * is required for both.
+ */
+ int *(*query_formats)(AVFilterLink *link);
+
+ /**
* Callback called before passing the first slice of a new frame. If
* NULL, the filter layer will default to storing a reference to the
* picture inside the link structure.
@@ -131,11 +138,15 @@ struct AVFilterPad
void (*request_frame)(AVFilterLink *link);
/**
- * Callback to set properties of the link. Only for video output pads.
- * XXX: this is not acceptable as is. it needs reworked to allow for
- * negotiation of colorspace, etc.
+ * Link configuration callback. For output pads, this should set the link
+ * properties such as width/height. NOTE: this should not set the format
+ * property - that is negotiated between filters by the filter system using
+ * the query_formats() callback.
+ *
+ * For input pads, this should check the properties of the link, and update
+ * the filter's internal state as necessary.
*/
- int (*set_video_props)(AVFilterLink *link);
+ int (*config_props)(AVFilterLink *link);
};
/* the default implementations of start_frame() and end_frame() */
@@ -206,4 +217,6 @@ AVFilterContext *avfilter_create_by_name
int avfilter_init_filter(AVFilterContext *filter, const char *args);
void avfilter_destroy(AVFilterContext *filter);
+int *avfilter_make_format_list(int len, ...);
+
#endif /* FFMPEG_AVFILTER_H */
Modified: libavfilter/filter_test.c
==============================================================================
--- libavfilter/filter_test.c (original)
+++ libavfilter/filter_test.c Thu Jul 5 22:48:48 2007
@@ -36,12 +36,13 @@ int main()
crop = avfilter_create_by_name("crop");
out = avfilter_create_by_name("sdl");
- avfilter_link(src, 0, crop, 0);
- avfilter_link(crop, 0, out, 0);
avfilter_init_filter(src, NULL);
avfilter_init_filter(crop, "20:40:320:240");
avfilter_init_filter(out, NULL);
+ avfilter_link(src, 0, crop, 0);
+ avfilter_link(crop, 0, out, 0);
+
for(i = 0; i < 10; i ++) {
sdl_display(out);
sleep(1);
Modified: libavfilter/vf_crop.c
==============================================================================
--- libavfilter/vf_crop.c (original)
+++ libavfilter/vf_crop.c Thu Jul 5 22:48:48 2007
@@ -27,22 +27,18 @@
typedef struct
{
int x, y, w, h;
+ int cx, cy, cw, ch;
} CropContext;
static int init(AVFilterContext *ctx, const char *args)
{
CropContext *crop = ctx->priv;
- if(ctx->inputs[0]->format != PIX_FMT_RGB24) {
- av_log(ctx, AV_LOG_FATAL, "unsupported input format\n");
- return -1;
- }
-
/* default parameters */
crop->x = 0;
crop->y = 0;
- crop->w = 640;
- crop->h = 480;
+ crop->w = -1;
+ crop->h = -1;
if(args)
sscanf(args, "%d:%d:%d:%d", &crop->x, &crop->y, &crop->w, &crop->h);
@@ -50,13 +46,37 @@ static int init(AVFilterContext *ctx, co
return 0;
}
-static int set_video_props(AVFilterLink *link)
+static int *query_in_formats(AVFilterLink *link)
+{
+ return avfilter_make_format_list(1, PIX_FMT_RGB24);
+}
+
+static int *query_out_formats(AVFilterLink *link)
+{
+ return avfilter_make_format_list(1, link->src->inputs[0]->format);
+}
+
+static int config_input(AVFilterLink *link)
+{
+ CropContext *crop = link->dst->priv;
+
+ crop->cx = FFMIN(crop->x, link->w - 1);
+ crop->cy = FFMIN(crop->y, link->h - 1);
+ crop->cw = FFMIN(crop->w, link->w - crop->cx);
+ crop->ch = FFMIN(crop->h, link->h - crop->cy);
+
+ if(crop->cw <= 0) crop->cw = link->w - crop->cx;
+ if(crop->ch <= 0) crop->ch = link->h - crop->cy;
+
+ return 0;
+}
+
+static int config_output(AVFilterLink *link)
{
CropContext *crop = link->src->priv;
- link->w = crop->w;
- link->h = crop->h;
- link->format = link->src->inputs[0]->format;
+ link->w = crop->cw;
+ link->h = crop->ch;
return 0;
}
@@ -66,10 +86,10 @@ static void start_frame(AVFilterLink *li
CropContext *crop = link->dst->priv;
AVFilterPicRef *ref2 = avfilter_ref_pic(picref);
- ref2->w = crop->w;
- ref2->h = crop->h;
- ref2->data[0] += crop->y * ref2->linesize[0];
- ref2->data[0] += 3 * crop->x;
+ ref2->w = crop->cw;
+ ref2->h = crop->ch;
+ ref2->data[0] += crop->cy * ref2->linesize[0];
+ ref2->data[0] += crop->cx * 3;
av_log(link->dst, AV_LOG_INFO, "start_frame()\n");
avfilter_default_start_frame(link, picref);
@@ -97,20 +117,20 @@ static void draw_slice(AVFilterLink *lin
av_log(link->dst, AV_LOG_INFO, "draw_slice()\n");
- if(y >= crop->y + crop->h || y + h <= crop->y) return;
+ if(y >= crop->cy + crop->ch || y + h <= crop->cy) return;
memcpy(src, data, sizeof(uint8_t *) * 4);
- if(top < crop->y) {
- height -= crop->y - top;
- src[0] += (crop->y - top) * pic->linesize[0];
- top = crop->y;
+ if(top < crop->cy) {
+ height -= crop->cy - top;
+ src[0] += (crop->cy - top) * pic->linesize[0];
+ top = crop->cy;
}
- if(top + height > crop->y + crop->h)
- height = crop->y + crop->h - top;
- src[0] += 3 * crop->x;
+ if(top + height > crop->cy + crop->ch)
+ height = crop->cy + crop->ch - top;
+ src[0] += 3 * crop->cx;
- avfilter_draw_slice(ctx->outputs[0], src, top - crop->y, height);
+ avfilter_draw_slice(ctx->outputs[0], src, top - crop->cy, height);
}
/* XXX: maybe make the default implementation do this? */
@@ -131,12 +151,15 @@ AVFilter vf_crop =
.type = AV_PAD_VIDEO,
.start_frame = start_frame,
.draw_slice = draw_slice,
- .end_frame = end_frame, },
+ .end_frame = end_frame,
+ .query_formats = query_in_formats,
+ .config_props = config_input, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AV_PAD_VIDEO,
.request_frame = request_frame,
- .set_video_props = set_video_props},
+ .query_formats = query_out_formats,
+ .config_props = config_output, },
{ .name = NULL}},
};
Modified: libavfilter/vo_sdl.c
==============================================================================
--- libavfilter/vo_sdl.c (original)
+++ libavfilter/vo_sdl.c Thu Jul 5 22:48:48 2007
@@ -34,24 +34,32 @@ static int init(AVFilterContext *ctx, co
{
SDLContext *sdl = ctx->priv;
- if(ctx->inputs[0]->format != PIX_FMT_RGB24) {
- av_log(ctx, AV_LOG_FATAL, "unsupported input format\n");
- return -1;
- }
-
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE)) {
av_log(ctx, AV_LOG_FATAL, "unable to initialize SDL: %s\n",
SDL_GetError());
return -1;
}
- sdl->surface = SDL_SetVideoMode(ctx->inputs[0]->w,
- ctx->inputs[0]->h,
- 24, SDL_HWSURFACE | SDL_DOUBLEBUF);
-
return 0;
}
+static int *query_formats(AVFilterLink *link)
+{
+ return avfilter_make_format_list(1, PIX_FMT_RGB24);
+}
+
+static int config_props(AVFilterLink *link)
+{
+ SDLContext *sdl = link->dst->priv;
+
+ /* SDL docs claim that calling this a second time to resize the
+ * surface will automatically free the old surface for us */
+ sdl->surface = SDL_SetVideoMode(link->w, link->h, 24,
+ SDL_HWSURFACE | SDL_DOUBLEBUF);
+
+ return !sdl->surface;
+}
+
static void uninit(AVFilterContext *ctx)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
@@ -117,7 +125,9 @@ AVFilter vo_sdl =
.type = AV_PAD_VIDEO,
.start_frame = start_frame,
.end_frame = end_frame,
- .draw_slice = draw_slice, },
+ .draw_slice = draw_slice,
+ .query_formats = query_formats,
+ .config_props = config_props, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = NULL}},
};
Modified: libavfilter/vsrc_dummy.c
==============================================================================
--- libavfilter/vsrc_dummy.c (original)
+++ libavfilter/vsrc_dummy.c Thu Jul 5 22:48:48 2007
@@ -27,11 +27,15 @@
#define GREEN 0x60
#define BLUE 0xC0
-static int set_video_props(AVFilterLink *link)
+static int *query_formats(AVFilterLink *link)
+{
+ return avfilter_make_format_list(1, PIX_FMT_RGB24);
+}
+
+static int config_props(AVFilterLink *link)
{
link->w = 640;
link->h = 480;
- link->format = PIX_FMT_RGB24;
return 0;
}
@@ -73,7 +77,8 @@ AVFilter vsrc_dummy =
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AV_PAD_VIDEO,
.request_frame = request_frame,
- .set_video_props = set_video_props, },
+ .query_formats = query_formats,
+ .config_props = config_props, },
{ .name = NULL}},
};
More information about the FFmpeg-soc
mailing list