Negotiation fixes.
authorDavid Schleef <ds@schleef.org>
Wed, 31 Dec 2003 08:02:04 +0000 (08:02 +0000)
committerDavid Schleef <ds@schleef.org>
Wed, 31 Dec 2003 08:02:04 +0000 (08:02 +0000)
Original commit message from CVS:
Negotiation fixes.

ChangeLog
gst-libs/gst/video/gstvideofilter.c
gst-libs/gst/video/gstvideofilter.h
gst/audioconvert/gstaudioconvert.c
gst/audioscale/gstaudioscale.c
gst/audioscale/gstaudioscale.h
gst/videoscale/gstvideoscale.c
gst/videoscale/videoscale.c
gst/videoscale/videoscale.h
sys/ximage/ximagesink.c

index f1a8323..61812f9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2003-12-30  David Schleef  <ds@schleef.org>
+
+       * ext/ffmpeg/gstffmpegcolorspace.c:
+       (gst_ffmpegcsp_caps_remove_format_info), (gst_ffmpegcsp_getcaps),
+       (gst_ffmpegcsp_pad_link), (gst_ffmpegcsp_init),
+       (gst_ffmpegcsp_chain): Negotiation fixes
+       * ext/mad/gstmad.c: (gst_mad_chain): Negotiation fixes
+       * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_chain),
+       (gst_audio_convert_link), (gst_audio_convert_channels):
+       * gst/audioscale/gstaudioscale.c: (gst_audioscale_getcaps),
+       (gst_audioscale_link), (gst_audioscale_get_buffer),
+       (gst_audioscale_chain): Negotiation fixes
+       * gst/audioscale/gstaudioscale.h:
+       * gst/videofilter/gstvideofilter.c:
+       (gst_videofilter_format_get_structure), (gst_videofilter_getcaps),
+       (gst_videofilter_link), (gst_videofilter_init),
+       (gst_videofilter_set_output_size), (gst_videofilter_setup),
+       (gst_videofilter_find_format_by_structure):
+       * gst/videofilter/gstvideofilter.h: Negotiation fixes
+       * gst/videoscale/gstvideoscale.c: (gst_videoscale_getcaps),
+       (gst_videoscale_link):
+       * gst/videoscale/videoscale.c: (videoscale_get_structure),
+       (videoscale_find_by_structure), (gst_videoscale_setup):
+       * gst/videoscale/videoscale.h: Negotiation fixes
+       * sys/ximage/ximagesink.c: (gst_ximagesink_handle_xevents),
+       (gst_ximagesink_fixate), (gst_ximagesink_init): Add a fixate
+       function, restrict resizing to a multiple of 4 (hack until
+       everyone supports odd sizes correctly).
+
 2003-12-29  Colin Walters  <walters@verbum.org>
 
        * ext/esd/esdsink.c (gst_esdsink_link): Fix typo; get depth instead of
index 86ab15a..95e3b00 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #endif
 
+#include <string.h>
 /*#define DEBUG_ENABLED */
 #include <gstvideofilter.h>
 
@@ -117,10 +118,10 @@ static GstStructure *gst_videofilter_format_get_structure(GstVideofilterFormat *
 
   fourcc = GST_MAKE_FOURCC(format->fourcc[0],format->fourcc[1],format->fourcc[2],format->fourcc[3]);
 
-  if(format->bpp){
+  if(format->depth){
     structure = gst_structure_new ("video/x-raw-rgb",
-       "depth", G_TYPE_INT, format->bpp,
-       "bpp", G_TYPE_INT, format->depth,
+       "depth", G_TYPE_INT, format->depth,
+       "bpp", G_TYPE_INT, format->bpp,
        "endianness", G_TYPE_INT, format->endianness,
        "red_mask", G_TYPE_INT, format->red_mask,
        "green_mask", G_TYPE_INT, format->green_mask,
@@ -155,22 +156,27 @@ GstCaps * gst_videofilter_class_get_capslist(GstVideofilterClass *klass)
 }
 
 static GstCaps *
-gst_videofilter_sink_getcaps (GstPad *pad)
+gst_videofilter_getcaps (GstPad *pad)
 {
   GstVideofilter *videofilter;
   GstVideofilterClass *klass;
-  GstCaps *caps;
-  GstCaps *peercaps;
-  int i;
+  //GstCaps *caps;
+  GstCaps *othercaps;
+  GstPad *otherpad;
+  //int i;
 
-  GST_DEBUG("gst_videofilter_sink_getcaps");
+  GST_DEBUG("gst_videofilter_getcaps");
   videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad));
   
   klass = GST_VIDEOFILTER_CLASS(G_OBJECT_GET_CLASS(videofilter));
 
-  /* get list of peer's caps */
-  peercaps = gst_pad_get_allowed_caps (videofilter->srcpad);
+  otherpad = (pad == videofilter->srcpad) ? videofilter->sinkpad :
+    videofilter->srcpad;
 
+  othercaps = gst_pad_get_allowed_caps (otherpad);
+
+  return othercaps;
+#if 0
   /* FIXME videofilter doesn't allow passthru of video formats it
    * doesn't understand. */
   /* Look through our list of caps and find those that match with
@@ -182,7 +188,7 @@ gst_videofilter_sink_getcaps (GstPad *pad)
     GstCaps *fromcaps;
     
     fromcaps = gst_caps_new_full (gst_videofilter_format_get_structure (
-         g_ptr_array_index (klass->formats,i)));
+         g_ptr_array_index (klass->formats,i)), NULL);
 
     icaps = gst_caps_intersect (fromcaps, peercaps);
     if(icaps != NULL){
@@ -195,58 +201,57 @@ gst_videofilter_sink_getcaps (GstPad *pad)
   gst_caps_free (peercaps);
 
   return caps;
+#endif
 }
 
 static GstPadLinkReturn
-gst_videofilter_src_link (GstPad *pad, const GstCaps *caps)
+gst_videofilter_link (GstPad *pad, const GstCaps *caps)
 {
   GstVideofilter *videofilter;
   GstStructure *structure;
   gboolean ret;
+  int width, height;
+  double framerate;
+  GstPadLinkReturn lret;
+  GstPad *otherpad;
 
   GST_DEBUG("gst_videofilter_src_link");
   videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad));
 
+  otherpad = (pad == videofilter->srcpad) ? videofilter->sinkpad :
+    videofilter->srcpad;
+
   structure = gst_caps_get_structure (caps, 0);
 
-  videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps);
+  videofilter->format = gst_videofilter_find_format_by_structure (
+      videofilter, structure);
   g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED);
 
-  ret = gst_structure_get_int (structure, "width", &videofilter->to_width);
-  ret &= gst_structure_get_int (structure, "height", &videofilter->to_height);
-  ret &= gst_structure_get_double (structure, "framerate", &videofilter->framerate);
+  ret = gst_structure_get_int (structure, "width", &width);
+  ret &= gst_structure_get_int (structure, "height", &height);
+  ret &= gst_structure_get_double (structure, "framerate", &framerate);
 
   if (!ret) return GST_PAD_LINK_REFUSED;
 
-  GST_DEBUG("width %d height %d",videofilter->to_width,videofilter->to_height);
-
-  gst_videofilter_setup(videofilter);
-
-  return GST_PAD_LINK_OK;
-}
-
-static GstPadLinkReturn
-gst_videofilter_sink_link (GstPad *pad, const GstCaps *caps)
-{
-  GstVideofilter *videofilter;
-  GstPadLinkReturn ret;
-  GstStructure *structure;
+  lret = gst_pad_try_set_caps (otherpad, caps);
+  if (GST_PAD_LINK_FAILED (lret)) return lret;
 
-  GST_DEBUG("gst_videofilter_sink_link");
-  videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad));
+  GST_DEBUG("width %d height %d",width,height);
 
-  structure = gst_caps_get_structure (caps, 0);
-
-  videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps);
-  g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED);
-
-  ret = gst_structure_get_int (structure, "width", &videofilter->from_width);
-  ret &= gst_structure_get_int (structure, "height", &videofilter->from_height);
-  ret &= gst_structure_get_double (structure, "framerate", &videofilter->framerate);
-
-  if (!ret) return GST_PAD_LINK_REFUSED;
-
-  GST_DEBUG("width %d height %d",videofilter->from_width,videofilter->from_height);
+#if 0
+  if (pad == videofilter->srcpad) {
+    videofilter->to_width = width;
+    videofilter->to_height = height;
+  } else {
+    videofilter->from_width = width;
+    videofilter->from_height = height;
+  }
+#endif
+  videofilter->to_width = width;
+  videofilter->to_height = height;
+  videofilter->from_width = width;
+  videofilter->from_height = height;
+  videofilter->framerate = framerate;
 
   gst_videofilter_setup(videofilter);
 
@@ -267,16 +272,16 @@ gst_videofilter_init (GTypeInstance *instance, gpointer g_class)
   videofilter->sinkpad = gst_pad_new_from_template(pad_template, "sink");
   gst_element_add_pad(GST_ELEMENT(videofilter),videofilter->sinkpad);
   gst_pad_set_chain_function(videofilter->sinkpad,gst_videofilter_chain);
-  gst_pad_set_link_function(videofilter->sinkpad,gst_videofilter_sink_link);
-  gst_pad_set_getcaps_function(videofilter->sinkpad,gst_videofilter_sink_getcaps);
+  gst_pad_set_link_function(videofilter->sinkpad,gst_videofilter_link);
+  gst_pad_set_getcaps_function(videofilter->sinkpad,gst_videofilter_getcaps);
 
   pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
       "src");
   g_return_if_fail(pad_template != NULL);
   videofilter->srcpad = gst_pad_new_from_template(pad_template, "src");
   gst_element_add_pad(GST_ELEMENT(videofilter),videofilter->srcpad);
-  gst_pad_set_link_function(videofilter->srcpad,gst_videofilter_src_link);
-  //gst_pad_set_getcaps_function(videofilter->srcpad,gst_videofilter_src_getcaps);
+  gst_pad_set_link_function(videofilter->srcpad,gst_videofilter_link);
+  gst_pad_set_getcaps_function(videofilter->srcpad,gst_videofilter_getcaps);
 
   videofilter->inited = FALSE;
 }
@@ -400,7 +405,7 @@ void gst_videofilter_set_output_size(GstVideofilter *videofilter,
   videofilter->to_height = height;
 
   videofilter->to_buf_size = (videofilter->to_width * videofilter->to_height
-      * videofilter->format->depth)/8;
+      * videofilter->format->bpp)/8;
 
   srccaps = gst_caps_copy(gst_pad_get_caps(videofilter->srcpad));
   structure = gst_caps_get_structure (srccaps, 0);
@@ -439,37 +444,61 @@ static void gst_videofilter_setup(GstVideofilter *videofilter)
   g_return_if_fail(videofilter->to_height > 0);
 
   videofilter->from_buf_size = (videofilter->from_width * videofilter->from_height *
-      videofilter->format->depth) / 8;
+      videofilter->format->bpp) / 8;
   videofilter->to_buf_size = (videofilter->to_width * videofilter->to_height *
-      videofilter->format->depth) / 8;
+      videofilter->format->bpp) / 8;
 
   videofilter->inited = TRUE;
 }
 
-GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *videofilter,
-    const GstCaps *caps)
+GstVideofilterFormat *gst_videofilter_find_format_by_structure (
+    GstVideofilter *videofilter, const GstStructure *structure)
 {
   int i;
   GstVideofilterClass *klass;
   GstVideofilterFormat *format;
   gboolean ret;
-  GstStructure *structure;
 
   klass = GST_VIDEOFILTER_CLASS(G_OBJECT_GET_CLASS(videofilter));
 
-  g_return_val_if_fail(caps != NULL, NULL);
+  g_return_val_if_fail(structure != NULL, NULL);
 
-  for(i=0;i<klass->formats->len;i++){
-    format = g_ptr_array_index(klass->formats,i);
-    structure = gst_videofilter_format_get_structure(format);
-
-    if(structure){
-      GstCaps *format_caps;
-      format_caps = gst_caps_new_full (structure, NULL);
-      ret = gst_caps_is_always_compatible (caps, format_caps);
-      gst_caps_free (format_caps);
+  if (strcmp (gst_structure_get_name (structure), "video/x-raw-yuv") == 0) {
+    guint32 fourcc;
 
-      if (ret) return format;
+    ret = gst_structure_get_fourcc (structure, "format", &fourcc);
+    if (!ret) return NULL;
+    for(i=0;i<klass->formats->len;i++){
+      guint32 format_fourcc;
+      format = g_ptr_array_index(klass->formats,i);
+      format_fourcc = GST_STR_FOURCC (format->fourcc);
+      if (format->depth == 0 && format_fourcc == fourcc) {
+        return format;
+      }
+    }
+  } else if (strcmp (gst_structure_get_name (structure), "video/x-raw-rgb")
+      == 0) {
+    int bpp;
+    int depth;
+    int endianness;
+    int red_mask;
+    int green_mask;
+    int blue_mask;
+
+    ret = gst_structure_get_int (structure, "bpp", &bpp);
+    ret &= gst_structure_get_int (structure, "depth", &depth);
+    ret &= gst_structure_get_int (structure, "endianness", &endianness);
+    ret &= gst_structure_get_int (structure, "red_mask", &red_mask);
+    ret &= gst_structure_get_int (structure, "green_mask", &green_mask);
+    ret &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
+    if (!ret) return NULL;
+    for(i=0;i<klass->formats->len;i++){
+      format = g_ptr_array_index(klass->formats,i);
+      if (format->bpp == bpp && format->depth == depth &&
+          format->endianness == endianness && format->red_mask == red_mask &&
+          format->green_mask == green_mask && format->blue_mask == blue_mask) {
+        return format;
+      }
     }
   }
 
index 9ec7593..e6c346c 100644 (file)
@@ -38,9 +38,9 @@ typedef void (*GstVideofilterSetupFunc)(GstVideofilter *filter);
 typedef struct _GstVideofilterFormat GstVideofilterFormat;
 struct _GstVideofilterFormat {
   char *fourcc;
-  int depth;
-  GstVideofilterFilterFunc filter_func;
   int bpp;
+  GstVideofilterFilterFunc filter_func;
+  int depth;
   unsigned int endianness;
   unsigned int red_mask;
   unsigned int green_mask;
@@ -94,8 +94,8 @@ int gst_videofilter_get_input_width(GstVideofilter *videofilter);
 int gst_videofilter_get_input_height(GstVideofilter *videofilter);
 void gst_videofilter_set_output_size(GstVideofilter *videofilter,
     int width, int height);
-GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *filter,
-    const GstCaps *caps);
+GstVideofilterFormat *gst_videofilter_find_format_by_structure (GstVideofilter *filter,
+    const GstStructure *structure);
 GstCaps *gst_videofilter_class_get_capslist(GstVideofilterClass *videofilterclass);
 
 void gst_videofilter_class_add_format(GstVideofilterClass *videofilterclass,
index 3618fd2..7461f64 100644 (file)
@@ -125,7 +125,9 @@ static GstPadLinkReturn      gst_audio_convert_link         (GstPad *pad, const
 static GstElementStateReturn gst_audio_convert_change_state (GstElement *element);
 
 /* actual work */
+#if 0
 static gboolean    gst_audio_convert_set_caps (GstPad *pad);
+#endif
 
 static GstBuffer * gst_audio_convert_buffer_to_default_format   (GstAudioConvert *this, GstBuffer *buf);
 static GstBuffer * gst_audio_convert_buffer_from_default_format (GstAudioConvert *this, GstBuffer *buf);
@@ -165,7 +167,7 @@ GST_STATIC_PAD_TEMPLATE (
 static GstStaticPadTemplate gst_audio_convert_sink_template =
 GST_STATIC_PAD_TEMPLATE (
   "sink",
-  GST_PAD_SRC,
+  GST_PAD_SINK,
   GST_PAD_ALWAYS,
   GST_STATIC_CAPS (
     GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
@@ -344,15 +346,6 @@ gst_audio_convert_chain (GstPad *pad, GstData *_data)
     return;
   }
 
-  if (!this->caps_set[1]) {
-    if (!gst_audio_convert_set_caps (this->src)) {
-      gst_element_error (GST_ELEMENT (this),
-                         "AudioConvert: could not set caps on pad %s",
-                         GST_PAD_NAME(this->src));
-      return;
-    }
-  }
-
   g_assert(this->caps_set[0] && this->caps_set[1]);
 
   /**
@@ -401,12 +394,27 @@ gst_audio_convert_link (GstPad *pad, const GstCaps *caps)
     ret &= gst_structure_get_int (structure, "endianness", &endianness);
   }
 
-  if (!ret) return GST_PAD_LINK_REFUSED;
+  if (!ret) {
+    return GST_PAD_LINK_REFUSED;
+  }
 
   /* we can't convert rate changes yet */
   if ((this->caps_set[1 - nr]) &&
-      (rate != this->rate[1 - nr]))
-    return GST_PAD_LINK_REFUSED;
+      (rate != this->rate[1 - nr])) {
+    GstPad *otherpad;
+    GstCaps *othercaps;
+    GstPadLinkReturn ret;
+    
+    otherpad = (nr) ? this->src : this->sink;
+    othercaps = gst_caps_copy (gst_pad_get_negotiated_caps (otherpad));
+
+    gst_caps_set_simple (othercaps, "rate", G_TYPE_INT, rate, NULL);
+
+    ret = gst_pad_try_set_caps (otherpad, othercaps);
+    if (GST_PAD_LINK_FAILED (ret)) return ret;
+
+    this->rate[1 - nr] = rate;
+  }
 
   this->caps_set[nr] = TRUE;
   this->rate[nr] = rate;
@@ -442,6 +450,7 @@ gst_audio_convert_change_state (GstElement *element)
 
 /*** ACTUAL WORK **************************************************************/
 
+#if 0
 static GstCaps *
 make_caps (gint endianness, gboolean sign, gint depth, gint width, gint rate, gint channels)
 {
@@ -523,6 +532,7 @@ gst_audio_convert_set_caps (GstPad *pad)
   g_assert (gst_audio_convert_link (pad, caps) == GST_PAD_LINK_OK);
   return TRUE;
 }
+#endif
 
 /* return a writable buffer of size which ideally is the same as before
    - You must unref the new buffer
@@ -693,16 +703,16 @@ static GstBuffer *
 gst_audio_convert_channels (GstAudioConvert *this, GstBuffer *buf)
 {
   GstBuffer *ret;
-  guint i, count;
+  gint i, count;
   guint32 *src, *dest;
 
   if (this->channels[0] == this->channels[1])
     return buf;
 
-  ret = gst_audio_convert_get_buffer (buf, buf->size / this->channels[0] * this->channels[1]);
-  count = ret->size / 4 / this->channels[1];
-  src = (guint32 *) buf->data;
-  dest = (guint32 *) ret->data;
+  count = GST_BUFFER_SIZE (buf) / 4 / this->channels[0];
+  ret = gst_audio_convert_get_buffer (buf, count * 4 * this->channels[1]);
+  src = (guint32 *) GST_BUFFER_DATA (buf);
+  dest = (guint32 *) GST_BUFFER_DATA (ret);
 
   if (this->channels[0] > this->channels[1]) {
     for (i = 0; i < count; i++) {
index 6ce077b..bfa0910 100644 (file)
@@ -161,27 +161,19 @@ static GstCaps *
 gst_audioscale_getcaps (GstPad *pad)
 {
   Audioscale *audioscale;
-  GstCaps *peercaps;
   GstCaps *caps;
+  GstPad *otherpad;
   int i;
-  int n;
 
   audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
 
-  if (pad == audioscale->srcpad){
-    peercaps = gst_pad_get_allowed_caps (audioscale->sinkpad);
-  }else{
-    peercaps = gst_pad_get_allowed_caps (audioscale->srcpad);
-  }
-
-  caps = gst_caps_intersect (peercaps, gst_static_caps_get (
-       &gst_audioscale_sink_template.static_caps));
-  if (gst_caps_is_empty(caps)) return caps;
+  otherpad = (pad == audioscale->srcpad) ? audioscale->sinkpad :
+    audioscale->srcpad;
+  caps = gst_pad_get_allowed_caps (otherpad);
 
   /* we do this hack, because the audioscale lib doesn't handle
    * rate conversions larger than a factor of 2 */
-  n = gst_caps_get_size (caps);
-  for (i=0;i<n;i++){
+  for (i=0;i<gst_caps_get_size(caps);i++){
     int rate_min, rate_max;
     GstStructure *structure = gst_caps_get_structure (caps, i);
     const GValue *value;
@@ -199,8 +191,15 @@ gst_audioscale_getcaps (GstPad *pad)
       return NULL;
     }
 
-    gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, rate_min/2,
-       rate_max*2, NULL);
+    rate_min /= 2;
+    if (rate_max < G_MAXINT/2){
+      rate_max *=2;
+    } else {
+      rate_max = G_MAXINT;
+    }
+
+    gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, rate_min,
+       rate_max, NULL);
   }
 
   return caps;
@@ -216,29 +215,48 @@ gst_audioscale_link (GstPad * pad, const GstCaps * caps)
   int channels;
   int ret;
   GstPadLinkReturn link_ret;
+  GstPad *otherpad;
 
   audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
   r = audioscale->resample;
 
-  link_ret = gst_pad_try_set_caps ((pad == audioscale->srcpad)
-      ? audioscale->sinkpad : audioscale->srcpad, caps);
-  if(link_ret == GST_PAD_LINK_OK){
+  otherpad = (pad == audioscale->srcpad) ? audioscale->sinkpad
+    : audioscale->srcpad;
+
+  structure = gst_caps_get_structure (caps, 0);
+
+  ret = gst_structure_get_int (structure, "rate", &rate);
+  ret &= gst_structure_get_int (structure, "channels", &channels);
+
+  link_ret = gst_pad_try_set_caps (otherpad, gst_caps_copy (caps));
+  if (GST_PAD_LINK_SUCCESSFUL (link_ret)){
     audioscale->passthru = TRUE;
+    r->channels = channels;
+    r->i_rate = rate;
+    r->o_rate = rate;
     return link_ret;
   }
-
   audioscale->passthru = FALSE;
 
-  structure = gst_caps_get_structure (caps, 0);
 
-  ret = gst_structure_get_int (structure, "rate", &rate);
-  ret &= gst_structure_get_int (structure, "channels", &channels);
+  if (gst_pad_is_negotiated (otherpad)) {
+    GstCaps *trycaps = gst_caps_copy (caps);
+
+    gst_caps_set_simple (trycaps,
+        "rate", G_TYPE_INT,
+        (int)((pad == audioscale->srcpad) ? r->i_rate : r->o_rate),
+        NULL);
+    link_ret = gst_pad_try_set_caps (otherpad, trycaps);
+    if (GST_PAD_LINK_FAILED (link_ret)){
+      return link_ret;
+    }
+  }
 
   r->channels = channels;
   if (pad == audioscale->srcpad) {
-    r->i_rate = rate;
-  } else {
     r->o_rate = rate;
+  } else {
+    r->i_rate = rate;
   }
   resample_reinit(r);
 
@@ -253,7 +271,7 @@ gst_audioscale_get_buffer (void *priv, unsigned int size)
   audioscale->outbuf = gst_buffer_new();
   GST_BUFFER_SIZE(audioscale->outbuf) = size;
   GST_BUFFER_DATA(audioscale->outbuf) = g_malloc(size);
-  GST_BUFFER_TIMESTAMP(audioscale->outbuf) = audioscale->offset * GST_SECOND / audioscale->targetfrequency;
+  GST_BUFFER_TIMESTAMP(audioscale->outbuf) = audioscale->offset * GST_SECOND / audioscale->resample->o_rate;
   audioscale->offset += size / sizeof(gint16) / audioscale->resample->channels;
 
   return GST_BUFFER_DATA(audioscale->outbuf);
@@ -317,10 +335,8 @@ gst_audioscale_chain (GstPad *pad, GstData *_data)
   data = GST_BUFFER_DATA(buf);
   size = GST_BUFFER_SIZE(buf);
 
-  GST_DEBUG (
-            "gst_audioscale_chain: got buffer of %ld bytes in '%s'\n",
-            size, gst_element_get_name (GST_ELEMENT (audioscale)));
-
+  GST_DEBUG ("gst_audioscale_chain: got buffer of %ld bytes in '%s'\n",
+      size, gst_element_get_name (GST_ELEMENT (audioscale)));
 
   resample_scale (audioscale->resample, data, size);
 
index 90cfd1d..70f0ad2 100644 (file)
@@ -27,9 +27,7 @@
 #include <gst/resample/resample.h>
 
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
 
 
 #define GST_TYPE_AUDIOSCALE \
@@ -59,10 +57,6 @@ struct _Audioscale {
 
   /* audio state */
   gboolean passthru;
-  gint format;
-  gint channels;
-  gint frequency;
-  gint targetfrequency;
   gint64 offset;
 
   resample_t *resample;
@@ -77,9 +71,7 @@ struct _AudioscaleClass {
 GType gst_audioscale_get_type(void);
 
 
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
 
 
 #endif /* __AUDIOSCALE_H__ */
index 0dbb3f7..e8d441d 100644 (file)
@@ -163,7 +163,7 @@ static GstCaps *
 gst_videoscale_getcaps (GstPad *pad)
 {
   GstVideoscale *videoscale;
-  GstCaps *peercaps;
+  GstCaps *othercaps;
   GstCaps *caps;
   GstPad *otherpad;
   int i;
@@ -171,29 +171,19 @@ gst_videoscale_getcaps (GstPad *pad)
   GST_DEBUG ("gst_videoscale_getcaps");
   videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad));
   
-  /* get list of peer's caps */
-  if(pad == videoscale->srcpad){
-    GST_DEBUG("getting caps of srcpad");
-    otherpad = videoscale->sinkpad;
-  }else{
-    GST_DEBUG("getting caps of sinkpad");
-    otherpad = videoscale->srcpad;
-  }
-  if (!GST_PAD_IS_LINKED (otherpad)){
-    GST_DEBUG ("otherpad not linked");
-    return GST_PAD_LINK_DELAYED;
-  }
-  peercaps = gst_pad_get_allowed_caps (GST_PAD_PEER(otherpad));
+  otherpad = (pad == videoscale->srcpad) ? videoscale->sinkpad :
+    videoscale->srcpad;
+  othercaps = gst_pad_get_allowed_caps (otherpad);
 
-  GST_DEBUG_CAPS("othercaps are", peercaps);
+  GST_DEBUG_CAPS("othercaps are", othercaps);
 
-  caps = gst_caps_copy (peercaps);
+  caps = gst_caps_copy (othercaps);
   for(i=0;i<gst_caps_get_size(caps);i++) {
     GstStructure *structure = gst_caps_get_structure (caps, i);
 
     gst_structure_set (structure,
-       "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
-       "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+       "width", GST_TYPE_INT_RANGE, 100, G_MAXINT,
+       "height", GST_TYPE_INT_RANGE, 100, G_MAXINT,
        NULL);
   }
 
@@ -208,42 +198,74 @@ gst_videoscale_link (GstPad *pad, const GstCaps *caps)
 {
   GstVideoscale *videoscale;
   GstPadLinkReturn ret;
-  const GstCaps *othercaps = NULL;
   GstPad *otherpad;
   GstStructure *structure;
+  struct videoscale_format_struct *format;
+  int height, width;
 
-  GST_DEBUG ("gst_videoscale_link");
+  GST_DEBUG ("gst_videoscale_link %s\n", gst_caps_to_string (caps));
   videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad));
 
-  if (pad == videoscale->srcpad) {
-    otherpad = videoscale->sinkpad;
-  } else {
-    otherpad = videoscale->srcpad;
-  }
+  otherpad = (pad == videoscale->srcpad) ? videoscale->sinkpad :
+    videoscale->srcpad;
+
+  structure = gst_caps_get_structure (caps, 0);
+  ret = gst_structure_get_int (structure, "width", &width);
+  ret &= gst_structure_get_int (structure, "height", &height);
+
+  format = videoscale_find_by_structure (structure);
+
+  if(!ret || format==NULL) return GST_PAD_LINK_REFUSED;
 
   ret = gst_pad_try_set_caps (otherpad, caps);
   if (ret == GST_PAD_LINK_OK) {
     /* cool, we can use passthru */
-    videoscale->passthru = TRUE;
+
+    videoscale->format = format;
+    videoscale->to_width = width;
+    videoscale->to_height = height;
+    videoscale->from_width = width;
+    videoscale->from_height = height;
+
+    gst_videoscale_setup (videoscale);
 
     return GST_PAD_LINK_OK;
   }
 
-  othercaps = GST_PAD_CAPS (otherpad);
+  if (gst_pad_is_negotiated (otherpad)) {
+    GstCaps *newcaps = gst_caps_copy (caps);
+
+    if (pad == videoscale->srcpad) {
+      gst_caps_set_simple (newcaps,
+          "width", G_TYPE_INT, videoscale->from_width,
+          "height", G_TYPE_INT, videoscale->from_height,
+          NULL);
+    } else {
+      gst_caps_set_simple (newcaps,
+          "width", G_TYPE_INT, videoscale->to_width,
+          "height", G_TYPE_INT, videoscale->to_height,
+          NULL);
+    }
+    ret = gst_pad_try_set_caps (otherpad, newcaps);
+    if (GST_PAD_LINK_FAILED (ret)) {
+      return GST_PAD_LINK_REFUSED;
+    }
+  }
+
+  videoscale->passthru = FALSE;
 
-  structure = gst_caps_get_structure (caps, 0);
   if (pad == videoscale->srcpad) {
-    ret = gst_structure_get_int (structure, "width", &videoscale->to_width);
-    ret &= gst_structure_get_int (structure, "height", &videoscale->to_height);
+    videoscale->to_width = width;
+    videoscale->to_height = height;
   } else {
-    ret = gst_structure_get_int (structure, "width", &videoscale->from_width);
-    ret &= gst_structure_get_int (structure, "height", &videoscale->from_height);
+    videoscale->from_width = width;
+    videoscale->from_height = height;
   }
+  videoscale->format = format;
 
-  if(!ret) return GST_PAD_LINK_REFUSED;
-
-  videoscale->format = videoscale_find_by_structure (structure);
-  gst_videoscale_setup(videoscale);
+  if (gst_pad_is_negotiated (otherpad)) {
+    gst_videoscale_setup (videoscale);
+  }
 
   return GST_PAD_LINK_OK;
 }
index 57005e9..1784af8 100644 (file)
@@ -109,10 +109,10 @@ videoscale_get_structure (struct videoscale_format_struct *format)
   if(format->scale==NULL)
     return NULL;
 
-  if(format->bpp){
+  if(format->depth){
     structure = gst_structure_new ("video/x-raw-rgb",
-       "depth", G_TYPE_INT, format->bpp,
-       "bpp", G_TYPE_INT, format->depth,
+       "depth", G_TYPE_INT, format->depth,
+       "bpp", G_TYPE_INT, format->bpp,
        "endianness", G_TYPE_INT, format->endianness,
        "red_mask", G_TYPE_INT, format->red_mask,
        "green_mask", G_TYPE_INT, format->green_mask,
@@ -124,8 +124,8 @@ videoscale_get_structure (struct videoscale_format_struct *format)
   }
 
   gst_structure_set(structure,
-      "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-      "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
+      "width", GST_TYPE_INT_RANGE, 100, G_MAXINT,
+      "height", GST_TYPE_INT_RANGE, 100, G_MAXINT,
       "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
       NULL);
 
@@ -139,7 +139,7 @@ videoscale_find_by_structure(GstStructure *structure)
   gboolean ret;
   struct videoscale_format_struct *format;
 
-  GST_DEBUG ("finding %p",structure);
+  GST_DEBUG ("finding %s",gst_structure_to_string(structure));
 
   g_return_val_if_fail(structure != NULL, NULL);
 
@@ -150,7 +150,7 @@ videoscale_find_by_structure(GstStructure *structure)
     if(!ret) return NULL;
     for (i = 0; i < videoscale_n_formats; i++){
       format = videoscale_formats + i;
-      if(format->bpp==0 && format->fourcc == fourcc){
+      if(format->depth==0 && format->fourcc == fourcc){
        return format;
       }
     }
@@ -195,6 +195,9 @@ gst_videoscale_setup (GstVideoscale *videoscale)
 
   if(videoscale->to_width==0 || videoscale->to_height==0 ||
        videoscale->from_width==0 || videoscale->from_height==0){
+    g_critical ("bad sizes %dx%d %dx%d",
+       videoscale->from_width, videoscale->from_height,
+        videoscale->to_width, videoscale->to_height);
     return;
   }
 
@@ -209,9 +212,9 @@ gst_videoscale_setup (GstVideoscale *videoscale)
   GST_DEBUG ("videoscale: scaling method POINT_SAMPLE");
 
   videoscale->from_buf_size = (videoscale->from_width * videoscale->from_height
-                 * videoscale->format->depth) / 8;
+                 * videoscale->format->bpp) / 8;
   videoscale->to_buf_size = (videoscale->to_width * videoscale->to_height
-                 * videoscale->format->depth) / 8;
+                 * videoscale->format->bpp) / 8;
 
   videoscale->passthru = FALSE;
   videoscale->inited = TRUE;
index c351c2b..dd7f5e1 100644 (file)
@@ -25,9 +25,9 @@
 
 struct videoscale_format_struct {
        unsigned int fourcc;
-       int depth;
-       void (*scale)(GstVideoscale *,unsigned char *dest, unsigned char *src);
        int bpp;
+       void (*scale)(GstVideoscale *,unsigned char *dest, unsigned char *src);
+       int depth;
        unsigned int endianness;
        unsigned int red_mask;
        unsigned int green_mask;
index 63a6490..b990c26 100644 (file)
@@ -310,15 +310,15 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
                      "red_mask",   G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
                      "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
                      "blue_mask",  G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
-                     "width",      G_TYPE_INT, e.xconfigure.width,
-                     "height",     G_TYPE_INT, e.xconfigure.height,
+                     "width",      G_TYPE_INT, e.xconfigure.width & ~3,
+                     "height",     G_TYPE_INT, e.xconfigure.height & ~3,
                      "framerate",  G_TYPE_DOUBLE, ximagesink->framerate,
                      NULL));
                 
                 if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
                   {
-                    GST_VIDEOSINK_WIDTH (ximagesink) = e.xconfigure.width;
-                    GST_VIDEOSINK_HEIGHT (ximagesink) = e.xconfigure.height;
+                    GST_VIDEOSINK_WIDTH (ximagesink) = e.xconfigure.width & ~3;
+                    GST_VIDEOSINK_HEIGHT (ximagesink) = e.xconfigure.height & ~3;
                 
                     if ( (ximagesink->ximage) &&
                          ( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
@@ -504,6 +504,32 @@ gst_ximagesink_xcontext_clear (GstXImageSink *ximagesink)
 /* Element stuff */
 
 static GstCaps *
+gst_ximagesink_fixate (GstPad *pad, const GstCaps *caps, gpointer ignore)
+{
+  GstStructure *structure;
+  GstCaps *newcaps;
+
+  if (gst_caps_get_size (caps) > 1) return NULL;
+
+  newcaps = gst_caps_copy (caps);
+  structure = gst_caps_get_structure (newcaps, 0);
+
+  if (gst_caps_structure_fixate_field_nearest_int (structure, "width", 320)) {
+    return newcaps;
+  }
+  if (gst_caps_structure_fixate_field_nearest_int (structure, "height", 240)) {
+    return newcaps;
+  }
+  if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate",
+        30.0)) {
+    return newcaps;
+  }
+
+  gst_caps_free (newcaps);
+  return NULL;
+}
+
+static GstCaps *
 gst_ximagesink_getcaps (GstPad *pad)
 {
   GstXImageSink *ximagesink;
@@ -948,6 +974,8 @@ gst_ximagesink_init (GstXImageSink *ximagesink)
                              gst_ximagesink_sinkconnect);
   gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (ximagesink),
                                 gst_ximagesink_getcaps);
+  gst_pad_set_fixate_function (GST_VIDEOSINK_PAD (ximagesink),
+                                gst_ximagesink_fixate);
 
   ximagesink->xcontext = NULL;
   ximagesink->xwindow = NULL;