Reworked the audio resampler.
authorWim Taymans <wim.taymans@gmail.com>
Sun, 11 Jun 2000 12:11:41 +0000 (12:11 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sun, 11 Jun 2000 12:11:41 +0000 (12:11 +0000)
Original commit message from CVS:
Reworked the audio resampler.
Added first frames skipping to the mp3 and ac3 parser (this allows you to
skip a number of frames before pushing them).
Removed wrong mmx code from the encoder.
Added Macroblocks per slice to the encoder.
added bilinear and bicubic interpolation to the videoscaler.
Added a MPEG1 multiplexer (no SCR or mux rate calculations yet)
Added some options (framerate to the encoder/decoder)

configure.in
gst/elements/gstpipefilter.c
libs/videoscale/gstvideoscale.c
plugins/elements/gstpipefilter.c
test/aviparse.c
test/mp1parse.c
test/mp2tomp1.c

index b3349b3..2284d21 100644 (file)
@@ -345,6 +345,7 @@ plugins/mpeg2/mpeg2enc/Makefile
 plugins/mpeg1/Makefile
 plugins/mpeg1/mpeg_play/Makefile
 plugins/mpeg1/parse/Makefile
+plugins/mpeg1/system_encode/Makefile
 plugins/mpeg1/mpeg1encoder/Makefile
 plugins/mpeg1video/Makefile
 plugins/mpeg1video/parse/Makefile
index a660592..64b4dbb 100644 (file)
@@ -124,41 +124,19 @@ GstElement *gst_pipefilter_new(gchar *name) {
   return pipefilter;
 }
 
-void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
-  GstPipefilter *pipefilter;
-  GstBuffer *newbuf;
-  glong readbytes, writebytes;
-  guchar *data;
-  gulong size;
-
-  g_return_if_fail(pad != NULL);
-  g_return_if_fail(GST_IS_PAD(pad));
-  g_return_if_fail(buf != NULL);
-
-  pipefilter = GST_PIPEFILTER(pad->parent);
-
-  data = GST_BUFFER_DATA(buf);
-  size = GST_BUFFER_SIZE(buf);
-
-  DEBUG("attemting to write %d bytes\n", size);
-  writebytes = write(pipefilter->fdin[1],data,size);
-  DEBUG("written %d bytes\n", writebytes);
-  if (writebytes < 0) {
-    perror("write");
-    gst_element_error(GST_ELEMENT(pipefilter),"writing");
-    return;
-  }
-  gst_buffer_unref(buf);
 
+static gboolean gst_pipefilter_read_and_push(GstPipefilter *pipefilter) {
+  GstBuffer *newbuf;
+  glong readbytes;
 
   /* create the buffer */
   // FIXME: should eventually use a bufferpool for this
   newbuf = gst_buffer_new();
-  g_return_if_fail(newbuf);
+  g_return_val_if_fail(newbuf, FALSE);
 
   /* allocate the space for the buffer data */
   GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read);
-  g_return_if_fail(GST_BUFFER_DATA(newbuf) != NULL);
+  g_return_val_if_fail(GST_BUFFER_DATA(newbuf) != NULL, FALSE);
 
   /* read it in from the file */
   DEBUG("attemting to read %d bytes\n", pipefilter->bytes_per_read);
@@ -168,17 +146,17 @@ void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
     if (errno == EAGAIN) {
       DEBUG("no input yet\n");
       gst_buffer_unref(newbuf);
-      return;
+      return FALSE;
     }
     else {
       perror("read");
       gst_element_error(GST_ELEMENT(pipefilter),"reading");
-      return;
+      return FALSE;
     }
   }
   if (readbytes == 0) {
     gst_buffer_unref(newbuf);
-    return;
+    return FALSE;
   }
   /* if we didn't get as many bytes as we asked for, we're at EOF */
   if (readbytes < pipefilter->bytes_per_read)
@@ -189,6 +167,36 @@ void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
 
   /* we're done, push the buffer off now */
   gst_pad_push(pipefilter->srcpad,newbuf);
+  return TRUE;
+}
+void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
+  GstPipefilter *pipefilter;
+  glong writebytes;
+  guchar *data;
+  gulong size;
+
+  g_return_if_fail(pad != NULL);
+  g_return_if_fail(GST_IS_PAD(pad));
+  g_return_if_fail(buf != NULL);
+
+  pipefilter = GST_PIPEFILTER(pad->parent);
+
+  while (gst_pipefilter_read_and_push(pipefilter));
+
+  data = GST_BUFFER_DATA(buf);
+  size = GST_BUFFER_SIZE(buf);
+
+  DEBUG("attemting to write %d bytes\n", size);
+  writebytes = write(pipefilter->fdin[1],data,size);
+  DEBUG("written %d bytes\n", writebytes);
+  if (writebytes < 0) {
+    perror("write");
+    gst_element_error(GST_ELEMENT(pipefilter),"writing");
+    return;
+  }
+  gst_buffer_unref(buf);
+
+  while (gst_pipefilter_read_and_push(pipefilter));
 }
 
 static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id) {
@@ -250,7 +258,6 @@ static gboolean gst_pipefilter_open_file(GstPipefilter *src) {
     // child
     dup2(src->fdin[0], STDIN_FILENO);  /* set the childs input stream */
     dup2(src->fdout[1], STDOUT_FILENO);  /* set the childs output stream */
-    //execlp("lame", "lame", "-x", "-s", "48", "--resample", "44.1", "-", "-", NULL);
     execvp(src->command[0], &src->command[0]);
     // will only reach if error
     perror("exec");
index 0b78c63..a3dd08c 100644 (file)
  */
 
 //#define DEBUG_ENABLED
+#include <math.h>
+
 #include <gst/gst.h>
 
 #include <gstvideoscale.h>
 #include <gst/meta/videoraw.h>
 
 static void gst_videoscale_scale_plane(unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
+static void gst_videoscale_scale_plane_slow(unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
 
 GstBuffer *gst_videoscale_scale(GstBuffer *src, int sw, int sh, int dw, int dh, int format) {
   GstBuffer *outbuf;
@@ -44,10 +47,10 @@ GstBuffer *gst_videoscale_scale(GstBuffer *src, int sw, int sh, int dw, int dh,
     ((MetaVideoRaw *)meta)->width = dw;
     ((MetaVideoRaw *)meta)->height = dh;
 
-    gst_buffer_add_meta(outbuf, meta);
+   gst_buffer_add_meta(outbuf, meta);
   }
 
-  gst_videoscale_scale_plane(source, dest, sw, sh, dw, dh);
+  gst_videoscale_scale_plane_slow(source, dest, sw, sh, dw, dh);
 
   source += sw*sh;
   dest += dw*dh;
@@ -57,64 +60,94 @@ GstBuffer *gst_videoscale_scale(GstBuffer *src, int sw, int sh, int dw, int dh,
   sh = sh>>1;
   sw = sw>>1;
 
-  gst_videoscale_scale_plane(source, dest, sw, sh, dw, dh);
+  gst_videoscale_scale_plane_slow(source, dest, sw, sh, dw, dh);
 
   source += sw*sh;
   dest += dw*dh;
 
-  gst_videoscale_scale_plane(source, dest, sw, sh, dw, dh);
+  gst_videoscale_scale_plane_slow(source, dest, sw, sh, dw, dh);
 
   gst_buffer_unref(src);
 
   return outbuf;
 }
 
-static char gst_videoscale_interp_simple(unsigned char *src, int x, int y, int dw, int dh, int sw, int sh, int ix, int iy) {
-  unsigned char *isourcep;
-  int interp;
-  int i,j;
+#define RC(x,y) *(src+(int)(x)+(int)((y)*sw))
 
-  //printf("scale: %d %d %p\n", ix, iy, src);
-  if (x>=ix) src-=(ix);
-  if (y>=iy) src-=(sw*iy);
+static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, double y, int sw) {
+  int j=floor(x);
+  int k=floor(y);
+  double a=x-j;
+  double b=y-k;
+  double dest;
+  int color;
 
-  isourcep = src;
-  interp =0;
+  dest=(1-a)*(1-b)*RC(j,k)+
+       a*(1-b)*RC(j+1,k)+
+       b*(1-a)*RC(j,k+1)+
+       a*b*RC(j+1,k+1);
 
-  for (i =0; i<iy; i++) {
-    for (j =0; j<ix; j++) {
-      //printf("%d ", *isourcep);
-      interp += *isourcep++;
-    }
-    //printf("\n");
-    isourcep = isourcep-ix+sw;
-  }
-  return interp/(ix*iy);
+  color=rint(dest);
+  if (color<0) color=abs(color);  // cannot have negative values !
+  //if (color<0) color=0;  // cannot have negative values !
+  if (color>255) color=255;
+
+  return (unsigned char) color;
 }
 
-static char gst_videoscale_interp_other(unsigned char *src, int x, int y, int dw, int dh, int sw, int sh, int ix, int iy) {
-  unsigned char *isourcep;
-  int interp;
-  int i,j;
-  static int matrix[3][3] = {{1,2,1}, {2,3,2},{1,2,1}};
+static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double y, int sw, int sh) {
+  int j=floor(x);
+  int k=floor(y), k2;
+  double a=x-j;
+  double b=y-k;
+  double dest;
+  int color;
+  double t1, t2, t3, t4;
+  double a1, a2, a3, a4;
+
+  a1 = -a*(1-a)*(1-a);
+  a2 = (1-2*a*a+a*a*a);
+  a3 = a*(1+a-a*a);
+  a4 = a*a*(1-a);
+
+  k2 = MAX(0, k-1);
+  t1=a1*RC(j-1,k2)+    a2*RC(j,k2)+    a3*RC(j+1,k2)-  a4*RC(j+2,k2);
+  t2=a1*RC(j-1,k)+     a2*RC(j,k)+     a3*RC(j+1,k)-   a4*RC(j+2,k); 
+  k2 = MIN(sh, k+1);
+  t3=a1*RC(j-1,k2)+    a2*RC(j,k2)+    a3*RC(j+1,k2)-  a4*RC(j+2,k2);
+  k2 = MIN(sh, k+2);
+  t4=a1*RC(j-1,k2)+    a2*RC(j,k2)+    a3*RC(j+1,k2)-  a4*RC(j+2,k2);
+
+  dest= -b*(1-b)*(1-b)*t1+ (1-2*b*b+b*b*b)*t2+ b*(1+b-b*b)*t3+ b*b*(b-1)*t4;
+
+  color=rint(dest);
+  if (color<0) color=abs(color);  // cannot have negative values !
+  if (color>255) color=255;
+
+  return (unsigned char) color;
+}
 
-  if (x>0) src--;
-  if (x>dw-1) src--;
-  if (y>0) src-=sw;
-  if (y>dh-1) src-=sw;
+static void gst_videoscale_scale_plane_slow(unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh) {
+  double zoomx = ((double)dw)/(double)sw;
+  double zoomy = ((double)dh)/(double)sh;
+  double xr, yr;
+  int x, y;
 
-  isourcep = src;
-  interp =0;
+  for (y=0; y<dh; y++) {
+    yr = ((double)y)/zoomy;
+    for (x=0; x<dw; x++) {
+      xr = ((double)x)/zoomx;
 
-  for (i =0; i<iy; i++) {
-    for (j =0; j<ix; j++) {
-      //printf("%d %d %d %d\n", i, j, *isourcep, matrix[i][j]);
-      interp += matrix[i][j]*(*isourcep++);
+      if (floor(xr) == xr && floor(yr) == yr){
+       *dest++ = RC(xr, yr);
+      }
+      else {
+       //*dest++ = gst_videoscale_bilinear(src, xr, yr, sw);
+       *dest++ = gst_videoscale_bicubic(src, xr, yr, sw, sh);
+      }
     }
-    isourcep = isourcep-ix+sw;
   }
-  //printf("%d\n", interp/15);
-  return interp/15;
+  
 }
 
 static void gst_videoscale_scale_plane(unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh) {
@@ -154,8 +187,7 @@ static void gst_videoscale_scale_plane(unsigned char *src, unsigned char *dest,
       }
       sourcep += xinc;
 
-      *dest++ = gst_videoscale_interp_simple(sourcep, x, y, dw, dh, sw, sh, xinc+xskip, yinc+yskip);
-      //*dest++ = *sourcep;
+      *dest++ = *sourcep;
     }
     if (dy <= 0) {
       dy += incyE;
index a660592..64b4dbb 100644 (file)
@@ -124,41 +124,19 @@ GstElement *gst_pipefilter_new(gchar *name) {
   return pipefilter;
 }
 
-void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
-  GstPipefilter *pipefilter;
-  GstBuffer *newbuf;
-  glong readbytes, writebytes;
-  guchar *data;
-  gulong size;
-
-  g_return_if_fail(pad != NULL);
-  g_return_if_fail(GST_IS_PAD(pad));
-  g_return_if_fail(buf != NULL);
-
-  pipefilter = GST_PIPEFILTER(pad->parent);
-
-  data = GST_BUFFER_DATA(buf);
-  size = GST_BUFFER_SIZE(buf);
-
-  DEBUG("attemting to write %d bytes\n", size);
-  writebytes = write(pipefilter->fdin[1],data,size);
-  DEBUG("written %d bytes\n", writebytes);
-  if (writebytes < 0) {
-    perror("write");
-    gst_element_error(GST_ELEMENT(pipefilter),"writing");
-    return;
-  }
-  gst_buffer_unref(buf);
 
+static gboolean gst_pipefilter_read_and_push(GstPipefilter *pipefilter) {
+  GstBuffer *newbuf;
+  glong readbytes;
 
   /* create the buffer */
   // FIXME: should eventually use a bufferpool for this
   newbuf = gst_buffer_new();
-  g_return_if_fail(newbuf);
+  g_return_val_if_fail(newbuf, FALSE);
 
   /* allocate the space for the buffer data */
   GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read);
-  g_return_if_fail(GST_BUFFER_DATA(newbuf) != NULL);
+  g_return_val_if_fail(GST_BUFFER_DATA(newbuf) != NULL, FALSE);
 
   /* read it in from the file */
   DEBUG("attemting to read %d bytes\n", pipefilter->bytes_per_read);
@@ -168,17 +146,17 @@ void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
     if (errno == EAGAIN) {
       DEBUG("no input yet\n");
       gst_buffer_unref(newbuf);
-      return;
+      return FALSE;
     }
     else {
       perror("read");
       gst_element_error(GST_ELEMENT(pipefilter),"reading");
-      return;
+      return FALSE;
     }
   }
   if (readbytes == 0) {
     gst_buffer_unref(newbuf);
-    return;
+    return FALSE;
   }
   /* if we didn't get as many bytes as we asked for, we're at EOF */
   if (readbytes < pipefilter->bytes_per_read)
@@ -189,6 +167,36 @@ void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
 
   /* we're done, push the buffer off now */
   gst_pad_push(pipefilter->srcpad,newbuf);
+  return TRUE;
+}
+void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) {
+  GstPipefilter *pipefilter;
+  glong writebytes;
+  guchar *data;
+  gulong size;
+
+  g_return_if_fail(pad != NULL);
+  g_return_if_fail(GST_IS_PAD(pad));
+  g_return_if_fail(buf != NULL);
+
+  pipefilter = GST_PIPEFILTER(pad->parent);
+
+  while (gst_pipefilter_read_and_push(pipefilter));
+
+  data = GST_BUFFER_DATA(buf);
+  size = GST_BUFFER_SIZE(buf);
+
+  DEBUG("attemting to write %d bytes\n", size);
+  writebytes = write(pipefilter->fdin[1],data,size);
+  DEBUG("written %d bytes\n", writebytes);
+  if (writebytes < 0) {
+    perror("write");
+    gst_element_error(GST_ELEMENT(pipefilter),"writing");
+    return;
+  }
+  gst_buffer_unref(buf);
+
+  while (gst_pipefilter_read_and_push(pipefilter));
 }
 
 static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id) {
@@ -250,7 +258,6 @@ static gboolean gst_pipefilter_open_file(GstPipefilter *src) {
     // child
     dup2(src->fdin[0], STDIN_FILENO);  /* set the childs input stream */
     dup2(src->fdout[1], STDOUT_FILENO);  /* set the childs output stream */
-    //execlp("lame", "lame", "-x", "-s", "48", "--resample", "44.1", "-", "-", NULL);
     execvp(src->command[0], &src->command[0]);
     // will only reach if error
     perror("exec");
index 2ed80f5..556254e 100644 (file)
@@ -11,7 +11,7 @@ void eof(GstSrc *src) {
 }
 
 void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
-  GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *show;
+  GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *show, *scale;
   GstElement *audio_queue, *video_queue;
   GstElement *audio_thread, *video_thread;
 
@@ -53,8 +53,12 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
   } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
        //} else if (0) {
 
+    gst_plugin_load("videoscale");
     gst_plugin_load("videosink");
     // construct internal pipeline elements
+    scale = gst_elementfactory_make("videoscale","videoscale");
+    g_return_if_fail(scale != NULL);
+    gtk_object_set(GTK_OBJECT(scale),"width",704, "height", 570,NULL);
     show = gst_elementfactory_make("videosink","show");
     g_return_if_fail(show != NULL);
     //gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL);
@@ -67,11 +71,14 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
     // create the thread and pack stuff into it
     video_thread = gst_thread_new("video_thread");
     g_return_if_fail(video_thread != NULL);
+    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(scale));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show));
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(video_thread),
-                              gst_element_get_pad(show,"sink"));
+                              gst_element_get_pad(scale,"sink"));
+    gst_pad_connect(gst_element_get_pad(scale,"src"),
+                    gst_element_get_pad(show,"sink"));
 
     // construct queue and connect everything in the main pipeline
     video_queue = gst_elementfactory_make("queue","video_queue");
index b84a44a..06f5743 100644 (file)
@@ -1,4 +1,7 @@
 
+#define BUFFER 1
+#define VIDEO_DECODER "mpeg_play"
+
 #include <gnome.h>
 #include <gst/gst.h>
 
@@ -49,7 +52,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
 
     // construct queue and connect everything in the main pipelie
     audio_queue = gst_elementfactory_make("queue","audio_queue");
-    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",300,NULL);
+    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",BUFFER,NULL);
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
     gst_pad_connect(pad,
@@ -67,14 +70,12 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
   //} else if (0) {
 
     gst_plugin_load("mp1videoparse");
-    gst_plugin_load("mpeg_play");
-    //gst_plugin_load("mpeg2play");
+    gst_plugin_load(VIDEO_DECODER);
     gst_plugin_load("videosink");
     // construct internal pipeline elements
     parse_video = gst_elementfactory_make("mp1videoparse","parse_video");
     g_return_if_fail(parse_video != NULL);
-    decode_video = gst_elementfactory_make("mpeg_play","decode_video");
-    //decode_video = gst_elementfactory_make("mpeg2play","decode_video");
+    decode_video = gst_elementfactory_make(VIDEO_DECODER,"decode_video");
     g_return_if_fail(decode_video != NULL);
     show = gst_elementfactory_make("videosink","show");
     g_return_if_fail(show != NULL);
@@ -102,7 +103,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
 
     // construct queue and connect everything in the main pipeline
     video_queue = gst_elementfactory_make("queue","video_queue");
-    gtk_object_set(GTK_OBJECT(video_queue),"max_level",300,NULL);
+    gtk_object_set(GTK_OBJECT(video_queue),"max_level",BUFFER,NULL);
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue));
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread));
     gst_pad_connect(pad,
index ee6bdd0..dce2398 100644 (file)
@@ -5,9 +5,7 @@
 #include <glib.h>
 #include <gst/gst.h>
 
-int fd;
-int audiofd;
-char *outfile;
+GstElement *mux;
 
 void eof(GstSrc *src) {
   g_print("have eos, quitting\n");
@@ -15,12 +13,11 @@ void eof(GstSrc *src) {
 }
 
 void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
-  GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *encode;
+  GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *encode, *audio_resample;
+  GstElement *smooth, *median;
   GstElement *audio_queue, *video_queue;
   GstElement *audio_thread, *video_thread;
   GstElement *videoscale, *audio_encode;
-  GstElement *fdsink, *audiofdsink;
-  GstElementFactory *fdsinkfactory, *audiofdsinkfactory;
 
   g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
 
@@ -29,30 +26,30 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
   if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
     gst_plugin_load("ac3parse");
     gst_plugin_load("ac3dec");
+    gst_plugin_load("audioscale");
     // construct internal pipeline elements
     parse_audio = gst_elementfactory_make("ac3parse","parse_audio");
     g_return_if_fail(parse_audio != NULL);
+    gtk_object_set(GTK_OBJECT(parse_audio),"skip", 0, NULL);
     decode = gst_elementfactory_make("ac3dec","decode_audio");
     g_return_if_fail(decode != NULL);
+    audio_resample = gst_elementfactory_make("audioscale","audioscale");
+    g_return_if_fail(audio_resample != NULL);
+    gtk_object_set(GTK_OBJECT(audio_resample),"frequency", 44100, NULL);
     audio_encode = gst_elementfactory_make("pipefilter","audio_encode");
     g_return_if_fail(audio_encode != NULL);
     gtk_object_set(GTK_OBJECT(audio_encode),"command",
-         "lame -x -s 48 --resample 44.1 - -", NULL);
+         "lame -x - -", NULL);
 
     // create the thread and pack stuff into it
     audio_thread = gst_thread_new("audio_thread");
     g_return_if_fail(audio_thread != NULL);
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
+    gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audio_resample));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audio_encode));
 
-    audiofd = open("/opt2/audio.mp3",O_CREAT|O_RDWR|O_TRUNC);
-    audiofdsinkfactory = gst_elementfactory_find("fdsink");
-    g_return_if_fail(audiofdsinkfactory != NULL);
-    audiofdsink = gst_elementfactory_create(audiofdsinkfactory,"fdsink");
-    g_return_if_fail(audiofdsink != NULL);
-    gtk_object_set(GTK_OBJECT(audiofdsink),"fd",audiofd,NULL);
-    gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audiofdsink));
+    gtk_object_set(GTK_OBJECT(mux),"audio","00",NULL);
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
@@ -60,13 +57,15 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
     gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
                     gst_element_get_pad(decode,"sink"));
     gst_pad_connect(gst_element_get_pad(decode,"src"),
+                    gst_element_get_pad(audio_resample,"sink"));
+    gst_pad_connect(gst_element_get_pad(audio_resample,"src"),
                     gst_element_get_pad(audio_encode,"sink"));
     gst_pad_connect(gst_element_get_pad(audio_encode,"src"),
-                    gst_element_get_pad(audiofdsink,"sink"));
+                    gst_element_get_pad(mux,"audio_00"));
 
     // construct queue and connect everything in the main pipelie
     audio_queue = gst_elementfactory_make("queue","audio_queue");
-    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",30,NULL);
+    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",1,NULL);
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
     gst_pad_connect(pad,
@@ -98,6 +97,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play));
 
+
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
                               gst_element_get_pad(parse_audio,"sink"));
@@ -108,7 +108,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
 
     // construct queue and connect everything in the main pipelie
     audio_queue = gst_elementfactory_make("queue","audio_queue");
-    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",30,NULL);
+    gtk_object_set(GTK_OBJECT(audio_queue),"max_level",1,NULL);
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
     gst_pad_connect(pad,
@@ -127,6 +127,8 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
 
     gst_plugin_load("mp1videoparse");
     gst_plugin_load("mpeg2play");
+    gst_plugin_load("smooth");
+    gst_plugin_load("median");
     gst_plugin_load("videoscale");
     gst_plugin_load("mpeg2enc");
     //gst_plugin_load("mpeg1encoder");
@@ -137,27 +139,32 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
     g_return_if_fail(decode_video != NULL);
     videoscale = gst_elementfactory_make("videoscale","videoscale");
     g_return_if_fail(videoscale != NULL);
-    gtk_object_set(GTK_OBJECT(videoscale),"width",352, "height", 224,NULL);
+    g_return_if_fail(median != NULL);
+    median = gst_elementfactory_make("median","median");
+    gtk_object_set(GTK_OBJECT(median),"filtersize",5,NULL);
+    smooth = gst_elementfactory_make("smooth","smooth");
+    g_return_if_fail(smooth != NULL);
+    gtk_object_set(GTK_OBJECT(smooth),"filtersize",5,NULL);
+    gtk_object_set(GTK_OBJECT(smooth),"tolerance",9,NULL);
+
+    gtk_object_set(GTK_OBJECT(videoscale),"width",352, "height", 240,NULL);
     encode = gst_elementfactory_make("mpeg2enc","encode");
-    //encode = gst_elementfactory_make("mpeg1encoder","encode");
+    gtk_object_set(GTK_OBJECT(encode),"frames_per_second",29.97,NULL);
     g_return_if_fail(encode != NULL);
+    //encode = gst_elementfactory_make("mpeg1encoder","encode");
     //gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL);
-    fd = open(outfile,O_CREAT|O_RDWR|O_TRUNC);
 
-    fdsinkfactory = gst_elementfactory_find("fdsink");
-    g_return_if_fail(fdsinkfactory != NULL);
-    fdsink = gst_elementfactory_create(fdsinkfactory,"fdsink");
-    g_return_if_fail(fdsink != NULL);
-    gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL);
+    gtk_object_set(GTK_OBJECT(mux),"video","00",NULL);
 
     // create the thread and pack stuff into it
     video_thread = gst_thread_new("video_thread");
     g_return_if_fail(video_thread != NULL);
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(parse_video));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(decode_video));
+    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(median));
+    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(smooth));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(videoscale));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(encode));
-    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(fdsink));
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(video_thread),
@@ -167,13 +174,17 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
     gst_pad_connect(gst_element_get_pad(decode_video,"src"),
                     gst_element_get_pad(videoscale,"sink"));
     gst_pad_connect(gst_element_get_pad(videoscale,"src"),
+                    gst_element_get_pad(median,"sink"));
+    gst_pad_connect(gst_element_get_pad(median,"src"),
+    //                gst_element_get_pad(smooth,"sink"));
+    //gst_pad_connect(gst_element_get_pad(smooth,"src"),
                     gst_element_get_pad(encode,"sink"));
     gst_pad_connect(gst_element_get_pad(encode,"src"),
-                    gst_element_get_pad(fdsink,"sink"));
+                    gst_element_get_pad(mux,"video_00"));
 
     // construct queue and connect everything in the main pipeline
     video_queue = gst_elementfactory_make("queue","video_queue");
-    gtk_object_set(GTK_OBJECT(video_queue),"max_level",30,NULL);
+    gtk_object_set(GTK_OBJECT(video_queue),"max_level",1,NULL);
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue));
     gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread));
     gst_pad_connect(pad,
@@ -195,12 +206,16 @@ int main(int argc,char *argv[]) {
   GstPipeline *pipeline;
   GstElement *src, *parse, *out;
   GstPad *infopad;
+  GstElement *fdsink;
+  GstElementFactory *fdsinkfactory;
+  int fd;
   int i,c;
 
   g_print("have %d args\n",argc);
 
   gst_init(&argc,&argv);
   gst_plugin_load("mpeg2parse");
+  gst_plugin_load("system_encode");
 
   pipeline = gst_pipeline_new("pipeline");
   g_return_if_fail(pipeline != NULL);
@@ -216,13 +231,23 @@ int main(int argc,char *argv[]) {
   g_print("should be using file '%s'\n",argv[1]);
 
   g_print("should be using output file '%s'\n",argv[2]);
-  outfile = argv[2];
 
   parse = gst_elementfactory_make("mpeg2parse","parse");
   g_return_if_fail(parse != NULL);
 
+  mux = gst_elementfactory_make("system_encode","mux");
+  g_return_if_fail(mux != NULL);
+  fd = open(argv[2],O_CREAT|O_RDWR|O_TRUNC);
+  fdsinkfactory = gst_elementfactory_find("fdsink");
+  g_return_if_fail(fdsinkfactory != NULL);
+  fdsink = gst_elementfactory_create(fdsinkfactory,"fdsink");
+  g_return_if_fail(fdsink != NULL);
+  gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL);
+
   gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src));
   gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse));
+  gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(mux));
+  gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(fdsink));
 
   gtk_signal_connect(GTK_OBJECT(parse),"new_pad",mp2tomp1, pipeline);
 
@@ -230,6 +255,8 @@ int main(int argc,char *argv[]) {
 
   gst_pad_connect(gst_element_get_pad(src,"src"),
                   gst_element_get_pad(parse,"sink"));
+  gst_pad_connect(gst_element_get_pad(mux,"src"),
+                  gst_element_get_pad(fdsink,"sink"));
 
   g_print("setting to RUNNING state\n");
   gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING);