Bring the plugins in sync with the new core capsnego system.
authorWim Taymans <wim.taymans@gmail.com>
Sun, 13 Jan 2002 22:27:25 +0000 (22:27 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sun, 13 Jan 2002 22:27:25 +0000 (22:27 +0000)
Original commit message from CVS:
Bring the plugins in sync with the new core capsnego system.
Added some features, enhancements...

21 files changed:
ext/Makefile.am
ext/audiofile/gstafsrc.c
ext/gsm/gstgsmdec.c
ext/gsm/gstgsmenc.c
ext/hermes/Makefile.am
ext/hermes/gstcolorspace.c
ext/hermes/gstcolorspace.h
ext/hermes/rgb2yuv.c [new file with mode: 0644]
ext/ladspa/gstladspa.c
gst/chart/gstchart.c
gst/deinterlace/gstdeinterlace.c
gst/flx/gstflxdec.c
gst/flx/gstflxdec.h
gst/mpeg1videoparse/gstmp1videoparse.c
gst/mpegaudioparse/gstmpegaudioparse.c
gst/passthrough/gstpassthrough.c
gst/playondemand/gstplayondemand.c
gst/smooth/gstsmooth.c
gst/speed/gstspeed.c
gst/y4m/gsty4mencode.c
sys/qcam/gstqcamsrc.c

index bd24b63..4676b25 100644 (file)
@@ -151,7 +151,8 @@ RTP_DIR=
 endif
 
 if USE_SDL
-SDL_DIR=sdl
+#SDL_DIR=sdl
+SDL_DIR=
 else
 SDL_DIR=
 endif
index 630e79d..ae4e54a 100644 (file)
@@ -350,21 +350,20 @@ gst_afsrc_open_file (GstAFSrc *src)
   
   /* set caps on src */
   //FIXME: add all the possible formats, especially float ! */
-  gst_pad_set_caps (src->srcpad, gst_caps_new (
-    "af_src",
-    "audio/raw",
-    gst_props_new (
-        "format",       GST_PROPS_STRING ("int"),
-          "law",        GST_PROPS_INT (0),              //FIXME
-          "endianness", GST_PROPS_INT (G_BYTE_ORDER),   //FIXME
-          "signed",     GST_PROPS_BOOLEAN (src->is_signed),
-          "width",      GST_PROPS_INT (src->width),
-          "depth",      GST_PROPS_INT (src->width),
-          "rate",       GST_PROPS_INT (src->rate),
-          "channels",   GST_PROPS_INT (src->channels),
-          NULL
-        )
-      ));
+  gst_pad_try_set_caps (src->srcpad, 
+                 GST_CAPS_NEW (
+                   "af_src",
+                    "audio/raw",
+                      "format",     GST_PROPS_STRING ("int"),
+                      "law",        GST_PROPS_INT (0),              //FIXME
+                      "endianness", GST_PROPS_INT (G_BYTE_ORDER),   //FIXME
+                      "signed",     GST_PROPS_BOOLEAN (src->is_signed),
+                      "width",      GST_PROPS_INT (src->width),
+                      "depth",      GST_PROPS_INT (src->width),
+                      "rate",       GST_PROPS_INT (src->rate),
+                      "channels",   GST_PROPS_INT (src->channels)
+                  )
+                 );
 
   GST_FLAG_SET (src, GST_AFSRC_OPEN);
 
index 5ead519..8a61453 100644 (file)
@@ -45,11 +45,11 @@ enum {
   /* FILL ME */
 };
 
-static void    gst_gsmdec_class_init   (GstGSMDec *klass);
-static void    gst_gsmdec_init         (GstGSMDec *gsmdec);
+static void                    gst_gsmdec_class_init   (GstGSMDec *klass);
+static void                    gst_gsmdec_init         (GstGSMDec *gsmdec);
 
-static void    gst_gsmdec_chain        (GstPad *pad, GstBuffer *buf);
-static void    gst_gsmdec_newcaps      (GstPad *pad, GstCaps *caps);
+static void                    gst_gsmdec_chain        (GstPad *pad, GstBuffer *buf);
+static GstPadConnectReturn     gst_gsmdec_sinkconnect  (GstPad *pad, GstCaps *caps);
 
 static GstElementClass *parent_class = NULL;
 //static guint gst_gsmdec_signals[LAST_SIGNAL] = { 0 };
@@ -93,7 +93,7 @@ gst_gsmdec_init (GstGSMDec *gsmdec)
   gsmdec->sinkpad = gst_pad_new_from_template (gsmdec_sink_template, "sink");
   gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
   gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
-  gst_pad_set_newcaps_function (gsmdec->sinkpad, gst_gsmdec_newcaps);
+  gst_pad_set_connect_function (gsmdec->sinkpad, gst_gsmdec_sinkconnect);
 
   gsmdec->srcpad = gst_pad_new_from_template (gsmdec_src_template, "src");
   gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
@@ -102,13 +102,18 @@ gst_gsmdec_init (GstGSMDec *gsmdec)
   gsmdec->bufsize = 0;
 }
 
-static void
-gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstGSMDec *gsmdec;
   
   gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
-  gst_pad_set_caps (gsmdec->srcpad, GST_CAPS_NEW (
+
+  if (!GST_CAPS_IS_FIXED (caps))
+    return GST_PAD_CONNECT_DELAYED;
+  
+  if (gst_pad_try_set_caps (gsmdec->srcpad, 
+                     GST_CAPS_NEW (
                        "gsm_raw",
                        "audio/raw",
                          "format",       GST_PROPS_STRING ("int"),
@@ -119,7 +124,11 @@ gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps)
                            "depth",      GST_PROPS_INT (16),
                            "rate",       GST_PROPS_INT (gst_caps_get_int (caps, "rate")),
                            "channels",   GST_PROPS_INT (1)
-                          ));
+                          )))
+  {
+    return GST_PAD_CONNECT_OK;
+  }
+  return GST_PAD_CONNECT_REFUSED;
 }
 
 static void
index b5ad0bc..abe4279 100644 (file)
@@ -46,22 +46,11 @@ enum {
   /* FILL ME */
 };
 
-GST_PADTEMPLATE_FACTORY (src_factory,
-  "src",
-  GST_PAD_SRC,
-  GST_PAD_ALWAYS,
-  GST_CAPS_NEW (
-    "gsm_enc",
-    "audio/x-gsm",
-      "rate",       GST_PROPS_INT_RANGE (1000, 48000)
-  )
-);
-
-static void            gst_gsmenc_class_init   (GstGSMEnc *klass);
-static void            gst_gsmenc_init         (GstGSMEnc *gsmenc);
-
-static void            gst_gsmenc_chain        (GstPad *pad,GstBuffer *buf);
-static void            gst_gsmenc_newcaps      (GstPad *pad, GstCaps *caps);
+static void                    gst_gsmenc_class_init   (GstGSMEnc *klass);
+static void                    gst_gsmenc_init         (GstGSMEnc *gsmenc);
+
+static void                    gst_gsmenc_chain        (GstPad *pad,GstBuffer *buf);
+static GstPadConnectReturn     gst_gsmenc_sinkconnect  (GstPad *pad, GstCaps *caps);
 
 static GstElementClass *parent_class = NULL;
 static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 };
@@ -113,7 +102,7 @@ gst_gsmenc_init (GstGSMEnc *gsmenc)
   gsmenc->sinkpad = gst_pad_new_from_template (gsmenc_sink_template, "sink");
   gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
   gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
-  gst_pad_set_newcaps_function (gsmenc->sinkpad, gst_gsmenc_newcaps);
+  gst_pad_set_connect_function (gsmenc->sinkpad, gst_gsmenc_sinkconnect);
 
   gsmenc->srcpad = gst_pad_new_from_template (gsmenc_src_template, "src");
   gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad);
@@ -124,19 +113,27 @@ gst_gsmenc_init (GstGSMEnc *gsmenc)
   gsmenc->rate = 8000;
 }
 
-static void
-gst_gsmenc_newcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstGSMEnc *gsmenc;
 
   gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
 
+  if (!GST_CAPS_IS_FIXED (caps)) 
+    return GST_PAD_CONNECT_DELAYED;
+
   gsmenc->rate = gst_caps_get_int (caps, "rate");
-  gst_pad_set_caps (gsmenc->srcpad, GST_CAPS_NEW (
+  if (gst_pad_try_set_caps (gsmenc->srcpad, GST_CAPS_NEW (
                               "gsm_gsm",
                               "audio/x-gsm",
                                 "rate",       GST_PROPS_INT (gsmenc->rate)
-                               ));
+                               )))
+  {
+    return GST_PAD_CONNECT_OK;
+  }
+  return GST_PAD_CONNECT_REFUSED;
+
 }
 
 static void
@@ -153,7 +150,7 @@ gst_gsmenc_chain (GstPad *pad, GstBuffer *buf)
   gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad));
              
   if (!GST_PAD_CAPS (gsmenc->srcpad)) {
-      gst_pad_set_caps (gsmenc->srcpad,
+      gst_pad_try_set_caps (gsmenc->srcpad,
                      GST_CAPS_NEW (
                        "gsm_enc",
                        "audio/x-gsm",
index 15e7c1e..b221c5c 100644 (file)
@@ -14,7 +14,7 @@ else
 PLUGIN_EXTRA_LIBS =
 endif
 
-libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c $(ARCHSRCS)
+libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c rgb2yuv.c $(ARCHSRCS)
 libgstcolorspace_la_CFLAGS = $(GST_CFLAGS)
 libgstcolorspace_la_LIBADD = $(GST_LIBS) $(PLUGIN_EXTRA_LIBS)
 
index eebe19b..40ada82 100644 (file)
@@ -52,7 +52,13 @@ GST_PADTEMPLATE_FACTORY (colorspace_src_template_factory,
   GST_CAPS_NEW (
     "colorspace_src",
     "video/raw",
-     NULL
+      "format",                GST_PROPS_LIST (
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")),
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
+                       ),
+      "width",                 GST_PROPS_INT_RANGE (0, G_MAXINT),
+      "height",                GST_PROPS_INT_RANGE (0, G_MAXINT) 
   )
 )
 
@@ -63,20 +69,41 @@ GST_PADTEMPLATE_FACTORY (colorspace_sink_template_factory,
   GST_CAPS_NEW (
     "colorspace_sink",
     "video/raw",
-    NULL
+      "format",                GST_PROPS_LIST (
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")),
+                         GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
+                       ),
+      "width",                 GST_PROPS_INT_RANGE (0, G_MAXINT),
+      "height",                GST_PROPS_INT_RANGE (0, G_MAXINT) 
   )
 )
 
 static void            gst_colorspace_class_init               (GstColorspaceClass *klass);
 static void            gst_colorspace_init                     (GstColorspace *space);
 
-static void            gst_colorspace_set_property                     (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void            gst_colorspace_get_property                     (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-
+static void            gst_colorspace_set_property             (GObject *object, guint prop_id, 
+                                                                const GValue *value, GParamSpec *pspec);
+static void            gst_colorspace_get_property             (GObject *object, guint prop_id, 
+                                                                GValue *value, GParamSpec *pspec);
+
+static GstPadConnectReturn
+                       gst_colorspace_sinkconnect              (GstPad *pad, GstCaps *caps);
+static GstPadConnectReturn
+                       gst_colorspace_srcconnect               (GstPad *pad, GstCaps *caps);
+static GstPadConnectReturn
+                       gst_colorspace_srcconnect_func          (GstPad *pad, GstCaps *caps, gboolean newcaps);
 static void            gst_colorspace_chain                    (GstPad *pad, GstBuffer *buf);
+static GstElementStateReturn
+                       gst_colorspace_change_state             (GstElement *element);
 
 // FIXME
-extern void gst_colorspace_yuy2_to_i420(unsigned char *src, unsigned char *dest, guint width, guint height);
+extern void    gst_colorspace_yuy2_to_i420     (unsigned char *src, unsigned char *dest, 
+                                                guint width, guint height);
+extern void    gst_colorspace_rgb32_to_i420    (unsigned char *src, unsigned char *dest, 
+                                                guint width, guint height);
+extern void    gst_colorspace_rgb32_to_yv12    (unsigned char *src, unsigned char *dest, 
+                                                guint width, guint height);
 
 static GstElementClass *parent_class = NULL;
 //static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 };
@@ -88,20 +115,16 @@ colorspace_get_bufferpool (GstPad *pad)
 
   space = GST_COLORSPACE (gst_pad_get_parent (pad));
 
-  if (space->type == GST_COLORSPACE_NONE)
+  if (space->type == GST_COLORSPACE_NONE && !space->disabled)
     return gst_pad_get_bufferpool (space->srcpad);
   else
     return NULL;
 }
 
 static gboolean 
-colorspace_setup_converter (GstColorspace *space)
+colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *to_caps)
 {
   gulong from_space, to_space;
-  GstCaps *from_caps, *to_caps;
-
-  from_caps = space->sinkcaps;
-  to_caps = space->srccaps;
 
   g_return_val_if_fail (to_caps != NULL, FALSE);
   g_return_val_if_fail (from_caps != NULL, FALSE);
@@ -109,26 +132,29 @@ colorspace_setup_converter (GstColorspace *space)
   from_space = gst_caps_get_fourcc_int (from_caps, "format");
   to_space = gst_caps_get_fourcc_int (to_caps, "format");
 
-  g_warning ("set up converter for %08lx to %08lx\n", from_space, to_space);
+  GST_INFO (GST_CAT_NEGOTIATION, "set up converter for %08lx to %08lx", from_space, to_space);
 
   switch (from_space) {
     case GST_MAKE_FOURCC ('R','G','B',' '):
+    {
+      gint from_bpp = gst_caps_get_int (from_caps, "bpp");
+
       switch (to_space) {
-#ifdef HAVE_LIBHERMES
         case GST_MAKE_FOURCC ('R','G','B',' '):
+#ifdef HAVE_HERMES
         {
          space->source.r = gst_caps_get_int (from_caps, "red_mask");
          space->source.g = gst_caps_get_int (from_caps, "green_mask");
          space->source.b = gst_caps_get_int (from_caps, "blue_mask");
          space->source.a = 0;
-         space->srcbpp = space->source.bits = gst_caps_get_int (from_caps, "bpp");
+         space->srcbpp = space->source.bits = from_bpp;
          space->source.indexed = 0;
          space->source.has_colorkey = 0;
 
-         GST_INFO (0,"source red mask   %08x\n", space->source.r);
-         GST_INFO (0, "source green mask %08x\n", space->source.g);
-         GST_INFO (0, "source blue mask  %08x\n", space->source.b);
-         GST_INFO (0, "source bpp        %08x\n", space->srcbpp);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "source red mask   %08x", space->source.r);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "source green mask %08x", space->source.g);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "source blue mask  %08x", space->source.b);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "source bpp        %08x", space->srcbpp);
 
          space->dest.r = gst_caps_get_int (to_caps, "red_mask");
          space->dest.g = gst_caps_get_int (to_caps, "green_mask");
@@ -138,173 +164,189 @@ colorspace_setup_converter (GstColorspace *space)
          space->dest.indexed = 0;
          space->dest.has_colorkey = 0;
 
-         GST_INFO (0, "dest red mask   %08x\n", space->dest.r);
-         GST_INFO (0, "dest green mask %08x\n", space->dest.g);
-         GST_INFO (0, "dest blue mask  %08x\n", space->dest.b);
-         GST_INFO (0, "dest bpp        %08x\n", space->destbpp);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "dest red mask   %08x", space->dest.r);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "dest green mask %08x", space->dest.g);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "dest blue mask  %08x", space->dest.b);
+         GST_INFO (GST_CAT_PLUGIN_INFO, "dest bpp        %08x", space->destbpp);
 
          if (!Hermes_ConverterRequest (space->h_handle, &space->source, &space->dest)) {
-           g_warning ("could not get converter\n");
+           g_warning ("Hermes: could not get converter\n");
            return FALSE;
          }
-         GST_INFO (0, "converter set up\n");
+         GST_INFO (GST_CAT_PLUGIN_INFO, "converter set up");
           space->type = GST_COLORSPACE_HERMES;
-          break;
+         return TRUE;
        }
+#else
+         g_warning ("colorspace: compiled without hermes!");
+         return FALSE;
 #endif
-        case GST_MAKE_FOURCC ('Y','U','Y','2'):
+        case GST_MAKE_FOURCC ('Y','V','1','2'):
+         if (from_bpp == 32) {
+            space->type = GST_COLORSPACE_RGB32_YV12;
+           space->destbpp = 12;
+           return TRUE;
+         }
         case GST_MAKE_FOURCC ('I','4','2','0'):
-          g_error ("colorspace: RGB to YUV implement me");
-          break;
+         if (from_bpp == 32) {
+            space->type = GST_COLORSPACE_RGB32_I420;
+           space->destbpp = 12;
+           return TRUE;
+         }
+        case GST_MAKE_FOURCC ('Y','U','Y','2'):
+          GST_INFO (GST_CAT_NEGOTIATION, "colorspace: RGB to YUV with bpp %d not implemented!!", from_bpp);
+         return FALSE;
       }
       break;
-    case GST_MAKE_FOURCC ('Y','U','Y','2'):
+    }
     case GST_MAKE_FOURCC ('I','4','2','0'):
       switch (to_space) {
         case GST_MAKE_FOURCC ('R','G','B',' '):
-          g_warning ("colorspace: YUV to RGB");
+          GST_INFO (GST_CAT_NEGOTIATION, "colorspace: YUV to RGB");
 
          space->destbpp = gst_caps_get_int (to_caps, "bpp");
          space->converter = gst_colorspace_yuv2rgb_get_converter (from_caps, to_caps);
           space->type = GST_COLORSPACE_YUV_RGB;
-          break;
+         return TRUE;
+        case GST_MAKE_FOURCC ('I','4','2','0'):
+          space->type = GST_COLORSPACE_NONE;
+         space->destbpp = 12;
+         return TRUE;
+
+      }
+      break;
+    case GST_MAKE_FOURCC ('Y','U','Y','2'):
+      switch (to_space) {
         case GST_MAKE_FOURCC ('I','4','2','0'):
           space->type = GST_COLORSPACE_YUY2_I420;
          space->destbpp = 12;
-          break;
+         return TRUE;
+        case GST_MAKE_FOURCC ('Y','U','Y','2'):
+          space->type = GST_COLORSPACE_NONE;
+         space->destbpp = 16;
+         return TRUE;
       }
       break;
   }
-  return TRUE;
+  return FALSE;
 }
 
-static GstPadNegotiateReturn
-colorspace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
+static GstCaps*
+gst_colorspace_getcaps (GstPad *pad, GstCaps *caps)
 {
-  GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad)));
-  GstCaps *original;
-  gint src_width, src_height;
-
-  GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: src negotiate\n");
-
-  g_return_val_if_fail (space->sinkcaps != NULL, GST_PAD_NEGOTIATE_FAIL);
-
-  src_width = gst_caps_get_int (space->sinkcaps, "width");
-  src_height = gst_caps_get_int (space->sinkcaps, "height");
-
-  space->width = src_width;
-  space->height = src_height;
-
-  if (*caps==NULL)  {
-    *caps = gst_caps_new ("colorspace_caps",
-                   "video/raw",
-                   gst_props_new (
-                           "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
-                           "width",  GST_PROPS_INT (src_width),
-                           "height",  GST_PROPS_INT (src_height),
-                           NULL));
-    space->srccaps = gst_caps_ref (*caps);
-    return GST_PAD_NEGOTIATE_TRY;
-    //return gst_pad_negotiate_proxy (pad, space->sinkpad, caps);
-  }
+  GstColorspace *space;
+  GstCaps *result;
+  GstCaps *peercaps;
+  GstCaps *ourcaps;
+  
+  space = GST_COLORSPACE (gst_pad_get_parent (pad));
 
+  /* we can do everything our peer can... */
+  peercaps = gst_caps_copy (gst_pad_get_allowed_caps (space->srcpad));
+  /* and our own template of course */
+  ourcaps = gst_caps_copy (gst_pad_get_padtemplate_caps (pad));
 
-  original = gst_caps_copy (*caps);
-  //g_print ("%d %d\n", src_width, src_height);
+  /* merge them together, we prefer the peercaps first */
+  result = gst_caps_prepend (ourcaps, peercaps);
 
-  // peers couldn't agree, we need to help
-  switch (gst_caps_get_fourcc_int (original, "format")) {
-    case GST_MAKE_FOURCC ('R','G','B',' '):
-      gst_caps_ref (*caps);
-      if (gst_caps_get_int (*caps, "width") == src_width &&
-          gst_caps_get_int (*caps, "height") == src_height) 
-      {
-        space->srccaps = *caps;
-        if (colorspace_setup_converter (space)) {
-          return GST_PAD_NEGOTIATE_AGREE;
-       }
-      }
-      else {
-        gst_caps_set (*caps, "width", GST_PROPS_INT (src_width));
-        gst_caps_set (*caps, "height", GST_PROPS_INT (src_height));
+  return result;
+}
 
-        space->srccaps = *caps;
-       // FIXME
-       GST_PAD_CAPS (space->srcpad) = gst_caps_ref (*caps);
+static GstPadConnectReturn
+gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps)
+{
+  GstColorspace *space;
+  GstPad *peer;
 
-        return GST_PAD_NEGOTIATE_TRY;
-      }
-      break;
-    case GST_MAKE_FOURCC ('Y','U','Y','2'):
-    case GST_MAKE_FOURCC ('I','4','2','0'):
-      //space->srccaps = original;
-      //fprintf (stderr, "found something suitable\n");
-      return GST_PAD_NEGOTIATE_AGREE;
-    default:
-      *caps = NULL;
-      return GST_PAD_NEGOTIATE_TRY;
-      break;
+  space = GST_COLORSPACE (gst_pad_get_parent (pad));
+
+  if (!GST_CAPS_IS_FIXED (caps)) {
+    return GST_PAD_CONNECT_DELAYED;
+  }
+
+  space->width = gst_caps_get_int (caps, "width");
+  space->height = gst_caps_get_int (caps, "height");
+
+  GST_INFO (GST_CAT_PROPERTIES, "size: %dx%d", space->width, space->height);
+
+  space->sinkcaps = caps;
+
+  peer = gst_pad_get_peer (pad);
+  if (peer) {
+    if (!gst_colorspace_srcconnect_func (pad, gst_pad_get_allowed_caps (space->srcpad), FALSE)) {
+      space->sinkcaps = NULL;
+      return GST_PAD_CONNECT_REFUSED;
+    }
   }
-  return GST_PAD_NEGOTIATE_FAIL;
+
+  return GST_PAD_CONNECT_OK;
 }
 
-static GstPadNegotiateReturn
-colorspace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
+static GstPadConnectReturn
+gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps)
 {
-  GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad)));
-  GstCaps *original;
+  return gst_colorspace_srcconnect_func (pad, caps, TRUE);
+}
 
-  GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: sink negotiate\n");
+static GstPadConnectReturn
+gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps)
+{
+  GstColorspace *space;
+  GstCaps *peercaps;
+  GstCaps *ourcaps;
   
-  if (*caps==NULL) 
-    return gst_pad_negotiate_proxy (pad, space->srcpad, caps);
-    //return GST_PAD_NEGOTIATE_FAIL;
-
+  space = GST_COLORSPACE (gst_pad_get_parent (pad));
 
-  space->type = GST_COLORSPACE_NONE;
+  /* we cannot operate if we didn't get src caps */
+  ourcaps = space->sinkcaps;
+  if (!ourcaps) {
+    if (newcaps)
+      gst_pad_recalc_allowed_caps (space->sinkpad);
 
-  original = gst_caps_copy (*caps);
+    return GST_PAD_CONNECT_DELAYED;
+  }
 
-  // see if a common format exists between both peers...
-  switch (gst_pad_negotiate_proxy (pad, space->srcpad, caps)) {
-    case GST_PAD_NEGOTIATE_AGREE:
-      //g_print ("colorspace: common format found\n");
-      return GST_PAD_NEGOTIATE_AGREE;
-    default:
-      break;
+  /* first see if we can do the format natively by filtering the peer caps 
+   * with our incomming caps */
+  peercaps = gst_caps_intersect (caps, ourcaps); 
+  if (peercaps) {
+    /* see if the peer likes it too, it should as the caps say so.. */
+    if (gst_pad_try_set_caps (space->srcpad, peercaps)) {
+      space->type = GST_COLORSPACE_NONE;
+      space->disabled = FALSE;
+      return GST_PAD_CONNECT_OK;
+    }
   }
-  g_warning ("colorspace: no common format found\n");
-  g_warning ("colorspace: src: %08lx\n", gst_caps_get_fourcc_int (original, "format"));
-
-  // peers couldn't agree, we need to help
-  space->sinkcaps = original;
-
-  /*
-  space->width = gst_caps_get_int (original, "width");
-  space->height = gst_caps_get_int (original, "height");
-
-  space->srccaps = gst_caps_new (
-                 "testcaps",
-                 "video/raw",
-                 gst_props_new (
-                   "format",   GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
-                    "width",   GST_PROPS_INT (gst_caps_get_int (original, "width")),
-                    "height",  GST_PROPS_INT (gst_caps_get_int (original, "height")),
-                    NULL
-                    ));
-
-  GST_PAD_CAPS (space->srcpad) = space->srccaps;
-  */
-
-  if (gst_pad_renegotiate (space->srcpad)) {
-    g_warning ("found something suitable\n");
-    if (colorspace_setup_converter (space)) {
-      return GST_PAD_NEGOTIATE_AGREE;
+  /* then see what the peer has that matches the size */
+  peercaps = gst_caps_intersect (caps,
+                 GST_CAPS_NEW (
+                  "colorspace_filter",
+                  "video/raw",
+                    "width",   GST_PROPS_INT (space->width),
+                    "height",  GST_PROPS_INT (space->height)
+                 ));
+
+  /* we are looping over the caps, so we have to get rid of the lists */
+  peercaps = gst_caps_normalize (peercaps);
+
+  /* loop over all possibilities and select the first one we can convert and
+   * is accepted by the peer */
+  while (peercaps) {
+    if (colorspace_setup_converter (space, ourcaps, peercaps)) {
+      if (gst_pad_try_set_caps (space->srcpad, peercaps)) {
+        space->disabled = FALSE;
+        return GST_PAD_CONNECT_OK;
+      }
     }
+    peercaps = peercaps->next;
   }
+  
+  gst_element_error (GST_ELEMENT (space), "could not agree on caps with peer pads");
+  /* we disable ourself here */
+  space->disabled = TRUE;
 
-  return GST_PAD_NEGOTIATE_FAIL;
-}              
+  return GST_PAD_CONNECT_REFUSED;
+}
 
 GType
 gst_colorspace_get_type (void)
@@ -340,6 +382,8 @@ gst_colorspace_class_init (GstColorspaceClass *klass)
 
   gobject_class->set_property = gst_colorspace_set_property;
   gobject_class->get_property = gst_colorspace_get_property;
+
+  gstelement_class->change_state = gst_colorspace_change_state;
 }
 
 static void
@@ -347,21 +391,23 @@ gst_colorspace_init (GstColorspace *space)
 {
   space->sinkpad = gst_pad_new_from_template (
                  GST_PADTEMPLATE_GET (colorspace_sink_template_factory), "sink");
-  gst_pad_set_negotiate_function (space->sinkpad, colorspace_negotiate_sink);
+  gst_pad_set_connect_function (space->sinkpad, gst_colorspace_sinkconnect);
+  gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps);
   gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool);
   gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain);
   gst_element_add_pad(GST_ELEMENT(space),space->sinkpad);
 
   space->srcpad = gst_pad_new_from_template (
                  GST_PADTEMPLATE_GET (colorspace_src_template_factory), "src");
-  gst_pad_set_negotiate_function (space->srcpad, colorspace_negotiate_src);
   gst_element_add_pad(GST_ELEMENT(space),space->srcpad);
+  gst_pad_set_connect_function (space->srcpad, gst_colorspace_srcconnect);
 
-#ifdef HAVE_LIBHERMES
+#ifdef HAVE_HERMES
   space->h_handle = Hermes_ConverterInstance (0);
 #endif
   space->pool = NULL;
   space->converter = NULL;
+  space->disabled = TRUE;
 }
 
 static void
@@ -380,16 +426,17 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
   g_return_if_fail (space != NULL);
   g_return_if_fail (GST_IS_COLORSPACE (space));
 
+  if (space->disabled) {
+    gst_buffer_unref (buf);
+    return;
+  }
+
   if (space->type == GST_COLORSPACE_NONE) {
     outbuf = buf;
   }
   else {
     gint dest_bytes, src_bytes;
 
-    if (!space->pool) {
-      space->pool = gst_pad_get_bufferpool (space->srcpad);
-    }
-
     size = space->width * space->height;
     dest_bytes = ((space->destbpp+7)/8);
     src_bytes = ((space->srcbpp+7)/8);
@@ -408,7 +455,7 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
     if (space->type == GST_COLORSPACE_YUV_RGB) {
       gst_colorspace_convert (space->converter, GST_BUFFER_DATA (buf), GST_BUFFER_DATA (outbuf));
     }
-#ifdef HAVE_LIBHERMES
+#ifdef HAVE_HERMES
     else if (space->type == GST_COLORSPACE_HERMES) {
       Hermes_ConverterCopy (space->h_handle, 
                    GST_BUFFER_DATA (buf), 0, 0, space->width, space->height, space->width * src_bytes, 
@@ -421,6 +468,18 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
                                   space->width,
                                   space->height);
     }
+    else if (space->type == GST_COLORSPACE_RGB32_I420) {
+      gst_colorspace_rgb32_to_i420 (GST_BUFFER_DATA (buf),
+                                  GST_BUFFER_DATA (outbuf),
+                                  space->width,
+                                  space->height);
+    }
+    else if (space->type == GST_COLORSPACE_RGB32_YV12) {
+      gst_colorspace_rgb32_to_yv12 (GST_BUFFER_DATA (buf),
+                                  GST_BUFFER_DATA (outbuf),
+                                  space->width,
+                                  space->height);
+    }
 
     GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
 
@@ -429,6 +488,27 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
   gst_pad_push (space->srcpad, outbuf);
 }
 
+static GstElementStateReturn
+gst_colorspace_change_state (GstElement *element)
+{
+  GstColorspace *space;
+
+  space = GST_COLORSPACE (element);
+
+  switch (GST_STATE_TRANSITION (element)) {
+    case GST_STATE_PAUSED_TO_PLAYING:
+      space->pool = gst_pad_get_bufferpool (space->srcpad);
+      break;
+    case GST_STATE_PLAYING_TO_PAUSED:
+      space->pool = NULL;
+      break;
+  }
+
+  parent_class->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
 static void
 gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
@@ -464,7 +544,7 @@ static gboolean
 plugin_init (GModule *module, GstPlugin *plugin)
 {
   GstElementFactory *factory;
-#ifdef HAVE_LIBHERMES
+#ifdef HAVE_HERMES
   gint hermes_res;
 
   hermes_res = Hermes_Init();
index 8d780b4..ca345fd 100644 (file)
@@ -26,7 +26,7 @@
 #include <gst/gst.h>
 #include "yuv2rgb.h"
 
-#ifdef HAVE_LIBHERMES
+#ifdef HAVE_HERMES
 #  include <Hermes/Hermes.h>
 #endif
 
@@ -57,6 +57,8 @@ typedef enum {
   GST_COLORSPACE_HERMES,
   GST_COLORSPACE_YUV_RGB,
   GST_COLORSPACE_YUY2_I420,
+  GST_COLORSPACE_RGB32_I420,
+  GST_COLORSPACE_RGB32_YV12,
 } GstColorSpaceConverterType;
 
 struct _GstColorspace {
@@ -64,7 +66,7 @@ struct _GstColorspace {
 
   GstPad *sinkpad,*srcpad;
 
-#ifdef HAVE_LIBHERMES
+#ifdef HAVE_HERMES
   HermesHandle h_handle;
   HermesFormat source, dest;
 #endif
@@ -74,8 +76,8 @@ struct _GstColorspace {
   GstColorSpaceConverterType type;
   gint width, height;
   gint srcbpp, destbpp;
+  gboolean disabled;
 
-  GstCaps *srccaps;
   GstCaps *sinkcaps;
 
   GstBufferPool *pool;
diff --git a/ext/hermes/rgb2yuv.c b/ext/hermes/rgb2yuv.c
new file mode 100644 (file)
index 0000000..7495c71
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *
+ *  rgb2rgb.c, Software RGB to YUV convertor
+ *  Written by Nick Kurshev.
+ *  palette & yuv & runtime cpu stuff by Michael (michaelni@gmx.at) (under GPL)
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+#include <gst/gst.h>
+
+#define RGB2YUV_SHIFT 8
+#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
+#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
+#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
+#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
+#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
+#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
+#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
+#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
+#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))
+
+/**
+ *
+ * height should be a multiple of 2 and width should be a multiple of 2 (if this is a
+ * problem for anyone then tell me, and ill fix it)
+ * chrominance data is only taken from every secound line others are ignored FIXME write HQ version
+ */
+void
+gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height)
+{
+  int y;
+  const int chrom_width = width >> 1;
+  const int chrom_size = (width * height) >> 2;
+
+  unsigned char *ydst = dest;
+  unsigned char *udst = ydst + (width * height);
+  unsigned char *vdst = udst + chrom_size;
+
+  for (y = 0; y < height; y += 2) {
+    int i;
+
+    for (i = 0; i < chrom_width; i++) {
+      unsigned int b = src[8 * i + 0];
+      unsigned int g = src[8 * i + 1];
+      unsigned int r = src[8 * i + 2];
+
+      unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
+      unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
+
+      udst[i] = U;
+      vdst[i] = V;
+      ydst[2 * i] = Y;
+
+      b = src[8 * i + 4];
+      g = src[8 * i + 5];
+      r = src[8 * i + 6];
+
+      Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      ydst[2 * i + 1] = Y;
+    }
+    ydst += width;
+    src += (width * 4);
+
+    for (i = 0; i < chrom_width; i++) {
+      unsigned int b = src[8 * i + 0];
+      unsigned int g = src[8 * i + 1];
+      unsigned int r = src[8 * i + 2];
+
+      unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+
+      ydst[2 * i] = Y;
+
+      b = src[8 * i + 4];
+      g = src[8 * i + 5];
+      r = src[8 * i + 6];
+
+      Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      ydst[2 * i + 1] = Y;
+    }
+    udst += chrom_width;
+    vdst += chrom_width;
+    ydst += width;
+    src += (width * 4);
+  }
+}
+
+void
+gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height)
+{
+  int y;
+  const int chrom_width = width >> 1;
+  const int chrom_size = (width * height) >> 2;
+
+  unsigned char *ydst = dest;
+  unsigned char *vdst = ydst + (width * height);
+  unsigned char *udst = vdst + chrom_size;
+
+  for (y = 0; y < height; y += 2) {
+    int i;
+
+    for (i = 0; i < chrom_width; i++) {
+      unsigned int b = src[8 * i + 0];
+      unsigned int g = src[8 * i + 1];
+      unsigned int r = src[8 * i + 2];
+
+      unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
+      unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
+
+      udst[i] = U;
+      vdst[i] = V;
+      ydst[2 * i] = Y;
+
+      b = src[8 * i + 4];
+      g = src[8 * i + 5];
+      r = src[8 * i + 6];
+
+      Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      ydst[2 * i + 1] = Y;
+    }
+    ydst += width;
+    src += (width * 4);
+
+    for (i = 0; i < chrom_width; i++) {
+      unsigned int b = src[8 * i + 0];
+      unsigned int g = src[8 * i + 1];
+      unsigned int r = src[8 * i + 2];
+
+      unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+
+      ydst[2 * i] = Y;
+
+      b = src[8 * i + 4];
+      g = src[8 * i + 5];
+      r = src[8 * i + 6];
+
+      Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
+      ydst[2 * i + 1] = Y;
+    }
+    udst += chrom_width;
+    vdst += chrom_width;
+    ydst += width;
+    src += (width * 4);
+  }
+}
index b83f026..53f1d5e 100644 (file)
@@ -85,9 +85,9 @@ static GstPadTemplate *srctempl, *sinktempl;
 static void                    gst_ladspa_class_init           (GstLADSPAClass *klass);
 static void                    gst_ladspa_init                 (GstLADSPA *ladspa);
 
-static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data);
-static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data);
-static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data);
+//static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data);
+//static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data);
+//static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data);
 static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad);
 
 static void                    gst_ladspa_set_property         (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@@ -347,9 +347,9 @@ gst_ladspa_init (GstLADSPA *ladspa)
   // mono chain
   if (sinkcount==1 && srccount==1){
     //g_print("inplace mono chain mode\n");
-    gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono);
+    //gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono);
     gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono);
-    gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono);
+    //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono);
   }
   
   // mono get (no sink pads)
@@ -359,7 +359,7 @@ gst_ladspa_init (GstLADSPA *ladspa)
     ladspa->samplerate = 44100;
     ladspa->buffersize = 64;
     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono);
-    gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
+    //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
     gst_ladspa_instantiate(ladspa);
   }
   
@@ -370,12 +370,13 @@ gst_ladspa_init (GstLADSPA *ladspa)
     ladspa->samplerate = 44100;
     ladspa->buffersize = 64;
     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get);
-    gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
+    //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
     gst_ladspa_instantiate(ladspa);
     ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads);
   }
 }
 
+#if 0
 static GstPadNegotiateReturn
 gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data)
 {
@@ -416,12 +417,13 @@ gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data)
   }
   return GST_PAD_NEGOTIATE_FAIL;
 }
+#endif
 
 static void
 gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) {
   
   // g_print("forcing caps\n");
-  gst_pad_set_caps (pad, gst_caps_new (
+  gst_pad_try_set_caps (pad, gst_caps_new (
     "ladspa_src_caps",
     "audio/raw",
     gst_props_new (
index 1ec2597..a08c475 100644 (file)
@@ -44,6 +44,7 @@ struct _GstChart {
   gint depth;
   gint width;
   gint height;
+  gboolean first_buffer;
 
   gint samplerate;
   gint framerate; // desired frame rate
@@ -162,10 +163,10 @@ static void       gst_chart_get_property  (GObject *object, guint prop_id, GValue *valu
 
 static void    gst_chart_chain         (GstPad *pad, GstBuffer *buf);
 
-static GstElementClass *parent_class = NULL;
+static GstPadConnectReturn 
+               gst_chart_sinkconnect   (GstPad *pad, GstCaps *caps);
 
-static void gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps);
-static void gst_chart_newsrccaps (GstPad *pad, GstCaps *caps);
+static GstElementClass *parent_class = NULL;
 
 GType
 gst_chart_get_type (void)
@@ -211,9 +212,7 @@ gst_chart_init (GstChart *chart)
   gst_element_add_pad (GST_ELEMENT (chart), chart->srcpad);
 
   gst_pad_set_chain_function (chart->sinkpad, gst_chart_chain);
-  gst_pad_set_newcaps_function (chart->sinkpad, gst_chart_newsinkcaps);
-  gst_pad_set_newcaps_function (chart->srcpad, gst_chart_newsrccaps);
-
+  gst_pad_set_connect_function (chart->sinkpad, gst_chart_sinkconnect);
 
   chart->next_time = 0;
   chart->peerpool = NULL;
@@ -221,8 +220,9 @@ gst_chart_init (GstChart *chart)
   // reset the initial video state
   chart->bpp = 16;
   chart->depth = 16;
-  chart->width = -1;
-  chart->height = -1;
+  chart->first_buffer = TRUE;
+  chart->width = 256;
+  chart->height = 128;
 
   chart->samplerate = -1;
   chart->framerate = 25; // desired frame rate
@@ -230,8 +230,8 @@ gst_chart_init (GstChart *chart)
   chart->samples_since_last_frame = 0;
 }
 
-static void
-gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_chart_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstChart *chart;
   chart = GST_CHART (gst_pad_get_parent (pad));
@@ -242,22 +242,8 @@ gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps)
   GST_DEBUG (0, "CHART: new sink caps: rate %d\n",
             chart->samplerate);
   //gst_chart_sync_parms (chart);
-}
-
-static void
-gst_chart_newsrccaps (GstPad *pad, GstCaps *caps)
-{
-  GstChart *chart;
-  chart = GST_CHART (gst_pad_get_parent (pad));
-
-  chart->bpp = gst_caps_get_int (caps, "bpp");
-  chart->depth = gst_caps_get_int (caps, "depth");
-  chart->width = gst_caps_get_int (caps, "width");
-  chart->height = gst_caps_get_int (caps, "height");
-
-  GST_DEBUG (0, "CHART: new src caps: bpp %d, depth %d, width %d, height %d\n",
-            chart->bpp, chart->depth, chart->width, chart->height);
-  //gst_chart_sync_parms (chart);
+  //
+  return GST_PAD_CONNECT_OK;
 }
 
 static void
@@ -347,28 +333,6 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
   if (chart->samples_between_frames <= chart->samples_since_last_frame) {
       chart->samples_since_last_frame = 0;
 
-      // Check if we need to renegotiate size.
-      if (chart->width == -1 || chart->height == -1) {
-         chart->width = 256;
-         chart->height = 128;
-         GST_DEBUG (0, "making new pad\n");
-         gst_pad_set_caps (chart->srcpad,
-                           gst_caps_new (
-                                         "chartsrc",
-                                         "video/raw",
-                                         gst_props_new (
-                                                        "format",      GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')),
-                                                        "bpp",         GST_PROPS_INT (chart->bpp),
-                                                        "depth",       GST_PROPS_INT (chart->depth),
-                                                        "endianness",  GST_PROPS_INT (G_BYTE_ORDER),
-                                                        "red_mask",    GST_PROPS_INT (0xf800),
-                                                        "green_mask",  GST_PROPS_INT (0x07e0),
-                                                        "blue_mask",   GST_PROPS_INT (0x001f),
-                                                        "width",       GST_PROPS_INT (chart->width),
-                                                        "height",      GST_PROPS_INT (chart->height),
-                                                        NULL)));
-      }
-
       // get data to draw into buffer
       if (samples_in >= chart->width) {
          // make a new buffer for the output
@@ -384,9 +348,35 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
          // FIXME: call different routines for different properties
          draw_chart_16bpp(dataout, chart->width, chart->height, (gint16 *)datain, samples_in);
 
+          gst_buffer_unref(bufin);
+
          // set timestamp
          GST_BUFFER_TIMESTAMP (bufout) = chart->next_time;
 
+          // Check if we need to renegotiate size.
+          if (chart->first_buffer) {
+           GST_DEBUG (0, "making new pad\n");
+           if (!gst_pad_try_set_caps (chart->srcpad,
+                           GST_CAPS_NEW (
+                             "chartsrc",
+                             "video/raw",
+                               "format",       GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')),
+                               "bpp",          GST_PROPS_INT (chart->bpp),
+                               "depth",        GST_PROPS_INT (chart->depth),
+                               "endianness",   GST_PROPS_INT (G_BYTE_ORDER),
+                               "red_mask",     GST_PROPS_INT (0xf800),
+                               "green_mask",   GST_PROPS_INT (0x07e0),
+                               "blue_mask",    GST_PROPS_INT (0x001f),
+                               "width",        GST_PROPS_INT (chart->width),
+                               "height",       GST_PROPS_INT (chart->height)
+                           )))
+           {
+             gst_element_error (GST_ELEMENT (chart), "could not set caps");
+             return;
+           }
+           chart->first_buffer = FALSE;
+          }
+
          GST_DEBUG (0, "CHART: outputting buffer\n");
          // output buffer
          GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_READONLY);
@@ -394,9 +384,9 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
       }
   } else {
       GST_DEBUG (0, "CHART: skipping buffer\n");
+      gst_buffer_unref(bufin);
   }
 
-  gst_buffer_unref(bufin);
   GST_DEBUG (0, "CHART: exiting chainfunc\n");
 }
 
index 99a70c8..0ad6ea8 100644 (file)
@@ -54,7 +54,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_src_factory,
   GST_CAPS_NEW (
    "deinterlace_src",
    "video/raw",
-     "format",   GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))
+     "format",   GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
+     "width",    GST_PROPS_INT_POSITIVE,
+     "height",   GST_PROPS_INT_POSITIVE
   )
 )
 
@@ -65,7 +67,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_sink_factory,
   GST_CAPS_NEW (
    "deinterlace_src",
    "video/raw",
-     "format",   GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))
+     "format",   GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
+     "width",    GST_PROPS_INT_POSITIVE,
+     "height",   GST_PROPS_INT_POSITIVE
   )
 )
 
@@ -74,36 +78,16 @@ static GType                gst_deinterlace_get_type                (void);
 static void            gst_deinterlace_class_init              (GstDeInterlaceClass *klass);
 static void            gst_deinterlace_init                    (GstDeInterlace *filter);
 
-static void            gst_deinterlace_set_property                    (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void            gst_deinterlace_get_property                    (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void            gst_deinterlace_set_property            (GObject *object, guint prop_id, 
+                                                                const GValue *value, GParamSpec *pspec);
+static void            gst_deinterlace_get_property            (GObject *object, guint prop_id, 
+                                                                GValue *value, GParamSpec *pspec);
 
 static void            gst_deinterlace_chain                   (GstPad *pad, GstBuffer *buf);
 
 static GstElementClass *parent_class = NULL;
 //static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
 
-static GstPadNegotiateReturn
-deinterlace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
-{
-  GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad));
-  
-  if (*caps==NULL) 
-    return GST_PAD_NEGOTIATE_FAIL;
-  
-  return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps);
-}
-
-static GstPadNegotiateReturn
-deinterlace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
-{
-  GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad));
-  
-  if (*caps==NULL) 
-    return GST_PAD_NEGOTIATE_FAIL;
-  
-  return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
-}              
-
 static GType
 gst_deinterlace_get_type(void) {
   static GType deinterlace_type = 0;
@@ -152,12 +136,15 @@ gst_deinterlace_class_init (GstDeInterlaceClass *klass)
   gobject_class->get_property = gst_deinterlace_get_property;
 }
 
-static void
-gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_deinterlace_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstDeInterlace *filter;
 
   filter = GST_DEINTERLACE(gst_pad_get_parent (pad));
+  
+  if (!GST_CAPS_IS_FIXED (caps))
+    return GST_PAD_CONNECT_DELAYED;
 
   filter->width = gst_caps_get_int (caps, "width");
   filter->height = gst_caps_get_int (caps, "height");
@@ -168,19 +155,21 @@ gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps)
     filter->picsize = filter->width*filter->height;
     filter->src = g_malloc(filter->picsize);
   }
+  if (gst_pad_try_set_caps (filter->srcpad, caps)) {
+    return GST_PAD_CONNECT_OK;
+  }
+  return GST_PAD_CONNECT_REFUSED;
 }
 
 static void
 gst_deinterlace_init (GstDeInterlace *filter)
 {
   filter->sinkpad = gst_pad_new_from_template(deinterlace_sink_factory (),"sink");
-  gst_pad_set_negotiate_function(filter->sinkpad,deinterlace_negotiate_sink);
   gst_pad_set_chain_function(filter->sinkpad,gst_deinterlace_chain);
-  gst_pad_set_newcaps_function(filter->sinkpad,gst_deinterlace_newcaps);
+  gst_pad_set_connect_function(filter->sinkpad,gst_deinterlace_sinkconnect);
   gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
 
   filter->srcpad = gst_pad_new_from_template(deinterlace_src_factory (),"src");
-  gst_pad_set_negotiate_function(filter->srcpad,deinterlace_negotiate_src);
   gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
 
   filter->show_deinterlaced_area_only = FALSE;
index 5fd5eb2..95e55cc 100644 (file)
@@ -22,6 +22,8 @@
 #include "flx_fmt.h"
 #include "gstflxdec.h"
 
+#define JIFFIE  (1000000/70)
+
 static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private);
 
 /* flx element information */
@@ -89,6 +91,9 @@ static void   gst_flxdec_init         (GstFlxDec *flxdec);
 
 static void    gst_flxdec_loop         (GstElement *element);
 
+static GstElementStateReturn 
+               gst_flxdec_change_state (GstElement *element);
+
 static void    gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 static void    gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 
@@ -108,10 +113,10 @@ flxdec_typefind (GstBuffer *buf, gpointer private)
   guchar *data = GST_BUFFER_DATA(buf);
   GstCaps *new;
 
-  // check magic 
+  /* check magic */
   if ((data[4] == 0x11 || data[4] == 0x12
        || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) {
-      // check the frame type of the first frame
+      /* check the frame type of the first frame */
       if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) {
         g_print("GstFlxDec: found supported flx format\n");
         new = gst_caps_new("flxdec_typefind","video/fli", NULL);
@@ -158,6 +163,7 @@ gst_flxdec_class_init (GstFlxDecClass *klass)
   gobject_class->set_property = NULL;  
   gobject_class->get_property = NULL;
 
+  gstelement_class->change_state = gst_flxdec_change_state;
 }
 
 
@@ -175,9 +181,9 @@ gst_flxdec_init(GstFlxDec *flxdec)
   gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad);
 
   flxdec->buf = NULL;
-  flxdec->offset = 0;
-  flxdec->new_buf = TRUE;
-
+  flxdec->bs = NULL;
+  flxdec->frame = NULL;
+  flxdec->delta = NULL;
 }
 
 static void
@@ -428,15 +434,13 @@ flx_get_data(GstFlxDec *flxdec, gulong size)
 
   g_return_val_if_fail (flxdec != NULL, NULL);
 
-  if (flxdec->new_buf) {
-    retbuf = gst_pad_pullregion(flxdec->sinkpad, 
-        GST_REGION_OFFSET_LEN, 0, size);
-    flxdec->new_buf = FALSE;
-    flxdec->offset = size;
-  } else {
-    retbuf = gst_pad_pullregion(flxdec->sinkpad, GST_REGION_OFFSET_LEN, 
-        flxdec->offset, size);
-    flxdec->offset += size;
+  retbuf = gst_bytestream_read (flxdec->bs, size);
+  if (!retbuf) {
+    GstEvent *event;
+    guint32 remaining;
+
+    gst_bytestream_get_status (flxdec->bs, &remaining, &event);
+    gst_pad_event_default (flxdec->sinkpad, event);
   }
 
   return retbuf;
@@ -461,33 +465,41 @@ gst_flxdec_loop (GstElement *element)
   
   flxdec = GST_FLXDEC(element);
 
-  databuf = flx_get_data(flxdec, FlxHeaderSize);
-
-  g_return_if_fail (databuf != NULL);
+  if (flxdec->state == GST_FLXDEC_READ_HEADER) {
+    databuf = flx_get_data(flxdec, FlxHeaderSize);
 
-  data = GST_BUFFER_DATA(databuf);
+    data = GST_BUFFER_DATA(databuf);
 
-  memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader));
+    memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader));
 
-  gst_buffer_unref (databuf);
+    gst_buffer_unref (databuf);
 
-  flxh = &flxdec->hdr;
+    flxh = &flxdec->hdr;
 
-  // check header
-  if (flxh->type != FLX_MAGICHDR_FLI &&
+    /* check header */
+    if (flxh->type != FLX_MAGICHDR_FLI &&
       flxh->type != FLX_MAGICHDR_FLC &&
       flxh->type != FLX_MAGICHDR_FLX) 
       return;
   
   
-  g_print("GstFlxDec:       size      :  %d\n", flxh->size);
-  g_print("GstFlxDec:       frames    :  %d\n", flxh->frames);
-  g_print("GstFlxDec:       width     :  %d\n", flxh->width);
-  g_print("GstFlxDec:       height    :  %d\n", flxh->height);
-  g_print("GstFlxDec:       depth     :  %d\n", flxh->depth);
-  g_print("GstFlxDec:       speed     :  %d\n", flxh->speed);
-
-  gst_pad_set_caps (flxdec->srcpad,
+    g_print("GstFlxDec:       size      :  %d\n", flxh->size);
+    g_print("GstFlxDec:       frames    :  %d\n", flxh->frames);
+    g_print("GstFlxDec:       width     :  %d\n", flxh->width);
+    g_print("GstFlxDec:       height    :  %d\n", flxh->height);
+    g_print("GstFlxDec:       depth     :  %d\n", flxh->depth);
+    g_print("GstFlxDec:       speed     :  %d\n", flxh->speed);
+
+    flxdec->next_time = 0;
+
+    if (flxh->type == FLX_MAGICHDR_FLI) {
+      flxdec->frame_time = JIFFIE * flxh->speed;
+    }
+    else {
+      flxdec->frame_time = flxh->speed * 1000;
+    }
+    
+    gst_pad_try_set_caps (flxdec->srcpad,
                gst_caps_new (
                  "src_video",
                  "video/raw",
@@ -503,41 +515,37 @@ gst_flxdec_loop (GstElement *element)
                      "height",     GST_PROPS_INT (flxh->height),
                    NULL)));
 
-  if (flxh->depth <= 8) 
-    flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height);
-
-  if (flxh->type == FLX_MAGICHDR_FLC || 
-      flxh->type == FLX_MAGICHDR_FLX) {
-    g_print("GstFlxDec: (FLC) aspect_dx :  %d\n", 
-      flxh->aspect_dx);
-    g_print("GstFlxDec: (FLC) aspect_dy :  %d\n", 
-      flxh->aspect_dy);
-    g_print("GstFlxDec: (FLC) oframe1   :  0x%08x\n", 
-      flxh->oframe1);
-    g_print("GstFlxDec: (FLC) oframe2   :  0x%08x\n", 
-      flxh->oframe2);
-  }
+    if (flxh->depth <= 8) 
+      flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height);
+
+    if (flxh->type == FLX_MAGICHDR_FLC || 
+        flxh->type == FLX_MAGICHDR_FLX) {
+      g_print("GstFlxDec: (FLC) aspect_dx :  %d\n", flxh->aspect_dx);
+      g_print("GstFlxDec: (FLC) aspect_dy :  %d\n", flxh->aspect_dy);
+      g_print("GstFlxDec: (FLC) oframe1   :  0x%08x\n", flxh->oframe1);
+      g_print("GstFlxDec: (FLC) oframe2   :  0x%08x\n", flxh->oframe2);
+    }
 
   
-  flxdec->size = (flxh->width * flxh->height);
+    flxdec->size = (flxh->width * flxh->height);
   
-  // create delta and output frame 
-  flxdec->frame = gst_buffer_new();
-  flxdec->delta = gst_buffer_new();
-  GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size);
-  GST_BUFFER_SIZE(flxdec->frame) = flxdec->size;
-  GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size);
-  GST_BUFFER_SIZE(flxdec->delta) = flxdec->size;
-
-  do
-  {
+    /* create delta and output frame */
+    flxdec->frame = gst_buffer_new();
+    flxdec->delta = gst_buffer_new();
+    GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size);
+    GST_BUFFER_SIZE(flxdec->frame) = flxdec->size;
+    GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size);
+    GST_BUFFER_SIZE(flxdec->delta) = flxdec->size;
+
+    flxdec->state = GST_FLXDEC_PLAYING;
+  }
+  else if (flxdec->state == GST_FLXDEC_PLAYING) {
 
     databuf = flx_get_data(flxdec, FlxFrameChunkSize);
 
     flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf);
     
-    switch(flxfh->id)
-    {
+    switch(flxfh->id) {
       case FLX_FRAME_TYPE:
         buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize);
  
@@ -546,43 +554,74 @@ gst_flxdec_loop (GstElement *element)
         if (((FlxFrameType *)chunk)->chunks == 0)
           break;
 
-        // create 32 bits output frame
+        /* create 32 bits output frame */
         flxdec->out = gst_buffer_new();
         GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4);
         GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4;
 
 
-        // decode chunks 
+        /* decode chunks */
         flx_decode_chunks(flxdec, 
                          ((FlxFrameType *)chunk)->chunks, 
                          GST_BUFFER_DATA(buf) + FlxFrameTypeSize,
                          GST_BUFFER_DATA(flxdec->frame));
  
-        // destroy input buffer
+        /* destroy input buffer*/
         gst_buffer_unref(buf);
     
-        // save copy of the current frame for possible delta.
+        /* save copy of the current frame for possible delta. */
         memcpy(GST_BUFFER_DATA(flxdec->delta), 
                GST_BUFFER_DATA(flxdec->frame), 
                GST_BUFFER_SIZE(flxdec->delta));
 
-        // convert current frame.
+        /* convert current frame. */
         flx_colorspace_convert(flxdec->converter,
              GST_BUFFER_DATA(flxdec->frame),
              GST_BUFFER_DATA(flxdec->out));
 
+       GST_BUFFER_TIMESTAMP (flxdec->out) = flxdec->next_time;
+       flxdec->next_time += flxdec->frame_time;
+
         gst_pad_push(flxdec->srcpad, flxdec->out);
         
         break;
     }
 
-    // destroy header buffer 
+    /* destroy header buffer */
     gst_buffer_unref(databuf);
+  }
+}
+
+static GstElementStateReturn 
+gst_flxdec_change_state (GstElement *element)
+{
+  GstFlxDec *flxdec;
+
+  flxdec = GST_FLXDEC(element);
 
-    gst_element_yield (element);
+  switch (GST_STATE_TRANSITION (element)) {
+    case GST_STATE_NULL_TO_READY:
+      flxdec->bs = gst_bytestream_new (flxdec->sinkpad);
+      break;
+    case GST_STATE_READY_TO_PAUSED:
+      flxdec->state = GST_FLXDEC_READ_HEADER;
+      break;
+    case GST_STATE_PAUSED_TO_PLAYING:
+      break;
+    case GST_STATE_PLAYING_TO_PAUSED:
+      break;
+    case GST_STATE_PAUSED_TO_READY:
+      gst_buffer_unref (flxdec->frame);
+      gst_buffer_unref (flxdec->delta);
+      break;
+    case GST_STATE_READY_TO_NULL:
+      gst_bytestream_destroy (flxdec->bs);
+      break;
   }
-  while (TRUE);
+  
+  parent_class->change_state (element);
 
+  return GST_STATE_SUCCESS;
 }
 
 static void 
@@ -622,6 +661,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
   GstElementFactory *factory;
   GstTypeFactory *type;
 
+  /* this filter needs the bytestream package */
+  if (!gst_library_load("gstbytestream")) {
+    gst_info("flxdec:: could not load support library: 'gstbytestream'\n");
+    return FALSE;
+  }
+
   factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details);
   g_return_val_if_fail(factory != NULL, FALSE);
 
index cc4c94d..5b06252 100644 (file)
 #include <gst/gst.h>
 
 #include "flx_color.h"
+#include <gst/bytestream/bytestream.h>
+
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
+typedef enum {
+  GST_FLXDEC_READ_HEADER,
+  GST_FLXDEC_PLAYING,
+} GstFlxDecState;
+       
 
 /* Definition of structure storing data for this element. */
 typedef struct _GstFlxDec  GstFlxDec;
+
 struct _GstFlxDec {
   GstElement element;
 
   GstPad *sinkpad,*srcpad;
 
-  gboolean active, new_meta, new_buf;
+  gboolean active, new_meta;
 
   GstBuffer *buf, *out, *delta, *frame;
-  gulong offset, size;
+  GstByteStream *bs;
+  gulong size;
+  GstFlxDecState state;
+  glong frame_time;
+  gint64 next_time;
 
   FlxColorSpaceConverter *converter;
 
@@ -64,9 +76,6 @@ struct _GstFlxDecClass {
 #define GST_IS_FLXDEC_CLASS(obj) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC))
 
-#define FLXDEC_BUFSIZE(buf, offset) \
-  ((GST_BUFFER_OFFSET(buf) + GST_BUFFER_SIZE(buf)) - offset)
-
 /* Standard function returning type information. */
 GType gst_flxdec_get_type(void);
 
index 39fdfa2..0d54d27 100644 (file)
@@ -138,12 +138,10 @@ static void
 gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse)
 {
   mp1videoparse->sinkpad = gst_pad_new_from_template (sink_template, "sink");
-  gst_pad_set_caps (mp1videoparse->sinkpad, gst_pad_get_padtemplate_caps (mp1videoparse->sinkpad));
   gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->sinkpad);
   gst_pad_set_chain_function(mp1videoparse->sinkpad,gst_mp1videoparse_chain);
 
   mp1videoparse->srcpad = gst_pad_new_from_template (src_template, "src");
-  gst_pad_set_caps (mp1videoparse->srcpad, gst_pad_get_padtemplate_caps (mp1videoparse->srcpad));
   gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->srcpad);
 
   mp1videoparse->partialbuf = NULL;
index 220d6dd..9e19b31 100644 (file)
@@ -142,7 +142,6 @@ static void
 gst_mp3parse_init (GstMPEGAudioParse *mp3parse)
 {
   mp3parse->sinkpad = gst_pad_new_from_template(sink_temp, "sink");
-  //gst_pad_set_caps(mp3parse->sinkpad, gst_pad_get_padtemplate_caps (mp3parse->sinkpad));
   gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->sinkpad);
 
 #if 1  // set this to one to use the old chaining code
index 0faa878..d9f0bac 100644 (file)
@@ -107,6 +107,7 @@ passthrough_get_bufferpool (GstPad *pad)
   return gst_pad_get_bufferpool (filter->srcpad);
 }
 
+/*
 static GstPadNegotiateReturn
 passthrough_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
@@ -134,6 +135,7 @@ passthrough_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
   
   return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
 }      
+*/
 
 static gint
 passthrough_parse_caps (GstPassthrough *filter, GstCaps *caps)
@@ -222,10 +224,10 @@ static void
 passthrough_init (GstPassthrough *filter)
 {
   filter->sinkpad = gst_pad_new_from_template(passthrough_sink_factory (),"sink");
-  gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink);
+  //gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink);
   gst_pad_set_bufferpool_function(filter->sinkpad,passthrough_get_bufferpool);
   filter->srcpad = gst_pad_new_from_template(passthrough_src_factory (),"src");
-  gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src);
+  //gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src);
   
   gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
   gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
index 2f7ebb0..b3d9984 100644 (file)
@@ -117,6 +117,7 @@ play_on_demand_get_bufferpool (GstPad *pad)
   return gst_pad_get_bufferpool(filter->srcpad);
 }
 
+/*
 static GstPadNegotiateReturn
 play_on_demand_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
@@ -144,6 +145,7 @@ play_on_demand_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
   
   return gst_pad_negotiate_proxy(pad, filter->srcpad, caps);
 }      
+*/
 
 static gint
 play_on_demand_parse_caps (GstPlayOnDemand *filter, GstCaps *caps)
@@ -264,11 +266,11 @@ play_on_demand_init (GstPlayOnDemand *filter)
   guint i;
   
   filter->sinkpad = gst_pad_new_from_template(play_on_demand_sink_factory(), "sink");
-  gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink);
+  //gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink);
   gst_pad_set_bufferpool_function(filter->sinkpad, play_on_demand_get_bufferpool);
 
   filter->srcpad = gst_pad_new_from_template(play_on_demand_src_factory(), "src");
-  gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src);
+  //gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src);
   
   gst_element_add_pad(GST_ELEMENT(filter), filter->sinkpad);
   gst_element_add_pad(GST_ELEMENT(filter), filter->srcpad);
index 5f1f507..ea32194 100644 (file)
@@ -80,28 +80,6 @@ static void  gst_smooth_get_property (GObject *object, guint prop_id, GValue *val
 static GstElementClass *parent_class = NULL;
 //static guint gst_smooth_signals[LAST_SIGNAL] = { 0 };
 
-static GstPadNegotiateReturn
-smooth_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
-{
-  GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad));
-
-  if (*caps==NULL)
-    return GST_PAD_NEGOTIATE_FAIL;
-
-  return gst_pad_negotiate_proxy (pad, filter->sinkpad, caps);
-}
-
-static GstPadNegotiateReturn
-smooth_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
-{
-  GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad));
-
-  if (*caps==NULL)
-    return GST_PAD_NEGOTIATE_FAIL;
-
-  return gst_pad_negotiate_proxy (pad, filter->srcpad, caps);
-}
-
 GType
 gst_smooth_get_type (void)
 {
@@ -149,15 +127,20 @@ gst_smooth_class_init (GstSmoothClass *klass)
 
 }
 
-static void
-gst_smooth_newcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_smooth_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstSmooth *filter;
 
   filter = GST_SMOOTH (gst_pad_get_parent (pad));
 
+  if (!GST_CAPS_IS_FIXED (caps))
+    return GST_PAD_CONNECT_DELAYED;
+
   filter->width = gst_caps_get_int (caps, "width");
   filter->height = gst_caps_get_int (caps, "height");
+
+  return GST_PAD_CONNECT_OK;
 }
 
 static void
@@ -165,14 +148,12 @@ gst_smooth_init (GstSmooth *smooth)
 {
   smooth->sinkpad = gst_pad_new_from_template (
                   GST_PADTEMPLATE_GET (smooth_sink_factory), "sink");
-  gst_pad_set_negotiate_function (smooth->sinkpad, smooth_negotiate_sink);
-  gst_pad_set_newcaps_function (smooth->sinkpad, gst_smooth_newcaps);
+  gst_pad_set_connect_function (smooth->sinkpad, gst_smooth_sinkconnect);
   gst_pad_set_chain_function (smooth->sinkpad, gst_smooth_chain);
   gst_element_add_pad (GST_ELEMENT (smooth), smooth->sinkpad);
 
   smooth->srcpad = gst_pad_new_from_template (
                   GST_PADTEMPLATE_GET (smooth_src_factory), "src");
-  gst_pad_set_negotiate_function (smooth->srcpad, smooth_negotiate_src);
   gst_element_add_pad (GST_ELEMENT (smooth), smooth->srcpad);
 
   smooth->active = TRUE;
index feca253..8cf9019 100644 (file)
@@ -109,6 +109,7 @@ static void         speed_loop              (GstElement *element);
 static GstElementClass *parent_class = NULL;
 //static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
 
+/*
 static GstPadNegotiateReturn
 speed_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
@@ -136,6 +137,7 @@ speed_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
   
   return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
 }      
+*/
 
 static gint
 speed_parse_caps (GstSpeed *filter, GstCaps *caps)
@@ -228,10 +230,10 @@ static void
 speed_init (GstSpeed *filter)
 {
   filter->sinkpad = gst_pad_new_from_template(speed_sink_factory (),"sink");
-  gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink);
+  //gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink);
   gst_pad_set_bufferpool_function (filter->sinkpad, speed_sink_get_bufferpool);
   filter->srcpad = gst_pad_new_from_template(speed_src_factory (),"src");
-  gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src);
+  //gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src);
   
   gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
   gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
index 69fc58d..ac82d65 100644 (file)
@@ -115,15 +115,20 @@ gst_lavencode_class_init (GstLavEncodeClass *klass)
   gobject_class->get_property = gst_lavencode_get_property;
 }
 
-static void
-gst_lavencode_newcaps (GstPad *pad, GstCaps *caps)
+static GstPadConnectReturn
+gst_lavencode_sinkconnect (GstPad *pad, GstCaps *caps)
 {
   GstLavEncode *filter;
 
   filter = GST_LAVENCODE (gst_pad_get_parent (pad));
 
+  if (!GST_CAPS_IS_FIXED (caps))
+    return GST_PAD_CONNECT_DELAYED;
+
   filter->width = gst_caps_get_int (caps, "width");
   filter->height = gst_caps_get_int (caps, "height");
+
+  return GST_PAD_CONNECT_OK;
 }
 
 static void
@@ -133,7 +138,7 @@ gst_lavencode_init (GstLavEncode *filter)
                  GST_PADTEMPLATE_GET (lavencode_sink_factory), "sink");
   gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
   gst_pad_set_chain_function (filter->sinkpad, gst_lavencode_chain);
-  gst_pad_set_newcaps_function (filter->sinkpad, gst_lavencode_newcaps);
+  gst_pad_set_connect_function (filter->sinkpad, gst_lavencode_sinkconnect);
 
   filter->srcpad = gst_pad_new_from_template(
                  GST_PADTEMPLATE_GET (lavencode_src_factory), "src");
index ed1afe9..22ab35c 100644 (file)
@@ -245,7 +245,7 @@ gst_qcamsrc_get (GstPad *pad)
 
   qc_set (qcamsrc->qcam);
   if (!GST_PAD_CAPS (pad)) {
-    gst_pad_set_caps (pad, GST_CAPS_NEW (
+    gst_pad_try_set_caps (pad, GST_CAPS_NEW (
                            "qcam_caps",
                            "video/raw",
                              "format",         GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),