Index: allfilters.c
===================================================================
--- allfilters.c	(revision 2168)
+++ allfilters.c	(working copy)
@@ -50,6 +50,7 @@
     REGISTER_FILTER(SPLIT,split,vf);
     REGISTER_FILTER(TRANSPOSE,transpose,vf);
     REGISTER_FILTER(VFLIP,vflip,vf);
+    REGISTER_FILTER(EXPAND,expand,vf);
 
     REGISTER_FILTER(MOVIE,movie,vsrc);
 }
Index: vf_expand.c
===================================================================
--- vf_expand.c	(revision 0)
+++ vf_expand.c	(revision 0)
@@ -0,0 +1,317 @@
+/*
+* video expand filter (replacement of pad syntax)
+ * copyright (c) 2008 Ryo Hirafuji
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "avfilter.h"
+
+typedef struct{
+    int  x,  y;
+    int ew, eh;
+
+	int osd; //checked, but not used in this version.
+    double aspect;
+    int round;
+
+    int bpp;                // bytes per pixel
+    int hsub, vsub;         // chroma subsampling
+} Context;
+
+static char** split(char* str,int str_len,int* argc,char delim){
+	if(!str || delim=='\0' || str_len < 0){
+		return 0;
+	}
+	char** argv = av_malloc(sizeof(char*));
+	if(!argv){
+		return 0;
+	}
+	int last = 0;
+	int i;
+	int arg_cnt = 0;
+	for(i=0;i<str_len;i++){
+		if(str[i] == delim){
+			str[i] = '\0';
+			argv[arg_cnt] = &str[last];
+			arg_cnt++;
+			last = i+1;
+			argv = av_realloc(argv,sizeof(char*) * (arg_cnt+1));
+		}
+	}
+	argv[arg_cnt] = &str[last];
+	*argc = arg_cnt + 1;
+	return argv;
+}
+
+static int init(AVFilterContext *ctx, const char *args, void *opaque){
+    Context *expand = ctx->priv;
+
+    /* default parameters */
+    expand->x =  -1;
+    expand->y =  -1;
+    expand->ew = -1;
+    expand->eh = -1;
+	expand->osd = 0;
+	expand->aspect = 0.0f;
+	expand->round = 0;
+
+	expand->bpp = 0;
+	expand->hsub = 0;
+	expand->vsub = 0;
+
+	if(args){
+		int argc;
+		int length = strlen(args);
+		char* copy_arg = av_malloc(length+1);
+
+		memcpy(copy_arg,args,length);
+		copy_arg[length] = '\0';
+
+		char** argv = split(copy_arg,length,&argc,':');
+		if(argc >= 1 && strlen(argv[0]) > 0){
+			expand->ew = atoi(argv[0]);
+		}
+		if(argc >= 2 && strlen(argv[1]) > 0){
+			expand->eh = atoi(argv[1]);
+		}
+		if(argc >= 3 && strlen(argv[2]) > 0){
+			expand->x = atoi(argv[2]);
+		}
+		if(argc >= 4 && strlen(argv[3]) > 0){
+			expand->y = atoi(argv[3]);
+		}
+
+		if(argc >= 5 &&  strlen(argv[4]) > 0){ //checked, but not used in this version.
+			if(!strncmp(argv[4],"true",4)){
+				expand->osd = 1;
+			}else{
+				expand->osd = atoi(argv[4]);
+			}
+		}
+
+		if(argc >= 6 &&  strlen(argv[5]) > 0){
+			int a,b;
+			double eval;
+
+			sscanf(argv[5],"%d/%d",&a,&b);
+			if(a != 0 && b != 0 && (a*b) > 0){
+				expand->aspect = ((double)a)/b;
+			}else if((eval = atof(argv[5])) >= 0.0f){
+				expand->aspect = eval;
+			}else{
+			}
+		}
+
+		if(argc >= 7 &&  strlen(argv[6]) > 0){
+			expand->round = atoi(argv[6]);
+		}
+
+		av_log(0, AV_LOG_INFO, "Expand: %dx%d , (%d,%d) , osd: %d, aspect: %lf, round: %d\n",
+	    expand->ew, expand->eh, expand->x, expand->y, expand->osd, expand->aspect, expand->round);
+
+		av_free(copy_arg);
+		av_free(argv);
+	}
+    return 0;
+}
+
+static int config_input(AVFilterLink *link){
+    Context *expand = link->dst->priv;
+	int width = link->w;
+	int height = link->h;
+
+	if (expand->ew == -1){
+		expand->ew=width;
+	} else if (expand->ew < -1){
+		expand->ew=width - expand->ew;
+	} else if (expand->ew < width){
+		expand->ew=width;
+	}
+
+	if (expand->eh == -1){
+		expand->eh=height;
+	} else if (expand->eh < -1){
+		expand->eh=height - expand->eh;
+	} else if (expand->eh < height){
+		expand->eh=height;
+	}
+
+    if (expand->aspect > 0.0f) {
+        if (expand->eh < (expand->ew / expand->aspect)) {
+        	expand->eh = (expand->ew / expand->aspect) + 0.5;
+        } else {
+        	expand->ew = (expand->eh * expand->aspect) + 0.5;
+        }
+    }
+    if (expand->round > 1) {
+        expand->ew = (1+(expand->ew-1)/expand->round)*expand->round;
+        expand->eh = (1+(expand->eh-1)/expand->round)*expand->round;
+    }
+	if(expand->x < 0 || (expand->x+width) > expand->ew){
+		expand->x = (expand->ew - width)>>1;
+	}
+	if(expand->y < 0 || (expand->y+height) > expand->eh){
+		expand->y = (expand->eh - height)>>1;
+	}
+	av_log(0, AV_LOG_INFO, "x:%d y:%d\n",expand->x,expand->y);
+
+    switch(link->format) {
+	    case PIX_FMT_RGB32:
+	    case PIX_FMT_BGR32:
+	        expand->bpp = 4;
+	        break;
+	    case PIX_FMT_RGB24:
+	    case PIX_FMT_BGR24:
+	        expand->bpp = 3;
+	        break;
+	    case PIX_FMT_RGB565:
+	    case PIX_FMT_RGB555:
+	    case PIX_FMT_BGR565:
+	    case PIX_FMT_BGR555:
+	    case PIX_FMT_GRAY16BE:
+	    case PIX_FMT_GRAY16LE:
+	        expand->bpp = 2;
+	        break;
+	    default:
+	        expand->bpp = 1;
+    }
+
+    avcodec_get_chroma_sub_sample(link->format, &expand->hsub, &expand->vsub);
+    expand->ew &= ~((1 << expand->hsub) - 1);
+    expand->eh &= ~((1 << expand->vsub) - 1);
+    return 0;
+}
+
+static int config_output(AVFilterLink *link){
+    Context *expand = link->src->priv;
+
+    link->w = expand->ew;
+    link->h = expand->eh;
+
+    return 0;
+}
+
+static void start_frame(AVFilterLink *link, AVFilterPicRef *picref){
+    Context *expand = link->dst->priv;
+	AVFilterLink *out = link->dst->outputs[0];
+	int i;
+	int is_yuv;
+	out->outpic      = avfilter_get_video_buffer(out, AV_PERM_WRITE);
+    out->outpic->pts = picref->pts;
+	is_yuv = out->outpic->data[1] != 0;
+	if(is_yuv){
+       	char* mem = out->outpic->data[0];
+		for(i=0;i<out->outpic->h;i++){
+			memset(mem,16,out->outpic->w);
+			mem += out->outpic->linesize[0];
+		}
+		for(i=1;i<3;i++) {
+	        if(out->outpic->data[i]) {
+	        	int j;
+	        	int h = out->outpic->h;
+	        	mem = out->outpic->data[i];
+	        	for(j=0;j<h;j+=(1<<expand->vsub)){
+	        		memset(mem,128,out->outpic->w >> expand->hsub);
+	        		mem += out->outpic->linesize[i];
+				}
+
+	        }
+		}
+	}else{
+		memset(out->outpic->data[0],0x00,out->outpic->linesize[0] * out->outpic->h);
+	}
+	avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0));
+}
+
+static void draw_slice(AVFilterLink *link, int y, int h){
+    Context *expand = link->dst->priv;
+	AVFilterPicRef *pic = link->dst->outputs[0]->outpic;
+	AVFilterPicRef *cur_pic = link->cur_pic;
+	int i;
+	unsigned int out_linesize = pic->linesize[0];
+	unsigned char* out_buff = pic->data[0];
+	unsigned int in_linesize = cur_pic->linesize[0];
+	const unsigned char* in_buff = cur_pic->data[0];
+	int copy_length = cur_pic->w * expand->bpp;
+	out_buff += out_linesize * expand->y;
+	out_buff += expand->bpp * expand->x;
+	for(i=0;i<h;i++){
+		memcpy(out_buff,in_buff,cur_pic->w * expand->bpp);
+		out_buff += out_linesize;
+		in_buff += in_linesize;
+	}
+	for(i=1;i<4;i++) {
+        if(pic->data[i]) {
+        	int j;
+			out_linesize = pic->linesize[i];
+			out_buff = pic->data[i];
+
+        	in_linesize = cur_pic->linesize[i];
+			in_buff = cur_pic->data[i];
+ 
+        	copy_length = cur_pic->w >> expand->hsub;
+
+        	out_buff += out_linesize * (expand->y >> expand->vsub);
+        	out_buff += expand->x >> expand->hsub;
+
+        	for(j=0;j<h;j+=(1<<expand->vsub)){
+				memcpy(out_buff,in_buff,copy_length);
+				out_buff += out_linesize;
+				in_buff += in_linesize;
+			}
+
+        }
+	}
+	if(y == 0){
+		avfilter_draw_slice(link->dst->outputs[0], 0, expand->y + h);
+	}else{
+    	avfilter_draw_slice(link->dst->outputs[0], expand->y+y, h);
+	}
+}
+
+static void end_frame(AVFilterLink *link){
+    Context *expand = link->dst->priv;
+	AVFilterPicRef *pic = link->dst->outputs[0]->outpic;
+	AVFilterPicRef *cur_pic = link->cur_pic;
+
+    avfilter_draw_slice(link->dst->outputs[0], cur_pic->h + expand->y, pic->h - cur_pic->h - expand->y);
+
+    avfilter_end_frame(link->dst->outputs[0]);
+}
+
+AVFilter avfilter_vf_expand = {
+    .name      = "expand",
+    .priv_size = sizeof(Context),
+
+    .init      = init,
+
+    .inputs    = (AVFilterPad[]) {{ .name            = "default",
+                                    .type            = CODEC_TYPE_VIDEO,
+                                    .start_frame     = start_frame,
+                                    .draw_slice      = draw_slice,
+                                    .end_frame       = end_frame,
+                                    .config_props    = config_input, },
+                                  { .name = NULL}},
+    .outputs   = (AVFilterPad[]) {{ .name            = "default",
+                                    .type            = CODEC_TYPE_VIDEO,
+                                    .config_props    = config_output, },
+                                  { .name = NULL}},
+};
+
Index: Makefile
===================================================================
--- Makefile	(revision 2168)
+++ Makefile	(working copy)
@@ -28,6 +28,7 @@
 OBJS-$(CONFIG_SPLIT_FILTER)      += vf_split.o
 OBJS-$(CONFIG_TRANSPOSE_FILTER)  += vf_transpose.o
 OBJS-$(CONFIG_VFLIP_FILTER)      += vf_vflip.o
+OBJS-$(CONFIG_EXPAND_FILTER)     += vf_expand.o
 
 OBJS-$(CONFIG_MOVIE_FILTER)      += vsrc_movie.o
 
