check/: Add extra tests for basetransform based components.
authorJan Schmidt <thaytan@mad.scientist.com>
Fri, 9 Sep 2005 17:53:47 +0000 (17:53 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Fri, 9 Sep 2005 17:53:47 +0000 (17:53 +0000)
Original commit message from CVS:
* check/Makefile.am:
* check/pipelines/simple_launch_lines.c: (setup_pipeline),
(run_pipeline), (GST_START_TEST), (simple_launch_lines_suite):
Add extra tests for basetransform based components.
Comment out the test_element_negotiation test until we decide
if it's testing correct behaviour.
* ext/libvisual/visual.c: (gst_visual_init), (get_buffer),
(gst_visual_chain), (gst_visual_change_state):
Slightly more correct but still bogus timestamping.
Fix state change function.
* gst/audioconvert/gstaudioconvert.c:
(gst_audio_convert_class_init):
* gst/audioresample/gstaudioresample.c:
* gst/ffmpegcolorspace/gstffmpegcolorspace.c:
(gst_ffmpegcsp_class_init):
* gst/videoscale/gstvideoscale.c: (gst_videoscale_class_init),
(gst_videoscale_prepare_size), (gst_videoscale_set_caps),
(gst_videoscale_prepare_image):
* gst/volume/gstvolume.c: (gst_volume_class_init),
(volume_transform_ip):
Basetransform updates. Enable passthrough modes.
* sys/ximage/ximagesink.c: (gst_ximage_buffer_init),
(gst_ximagesink_renegotiate_size), (gst_ximagesink_xcontext_get),
(gst_ximagesink_setcaps), (gst_ximagesink_buffer_alloc):
Negotiation fix that allows the window to return to the original
size and renegotiate passthrough upstream. Extra debug output.

12 files changed:
ChangeLog
check/Makefile.am
check/pipelines/simple_launch_lines.c
ext/libvisual/visual.c
gst/audioconvert/gstaudioconvert.c
gst/audioresample/gstaudioresample.c
gst/ffmpegcolorspace/gstffmpegcolorspace.c
gst/videoscale/gstvideoscale.c
gst/volume/gstvolume.c
sys/ximage/ximagesink.c
tests/check/Makefile.am
tests/check/pipelines/simple-launch-lines.c

index 27d5039..9dce39f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2005-09-09  Jan Schmidt  <thaytan@mad.scientist.com>
+
+       * check/Makefile.am:
+       * check/pipelines/simple_launch_lines.c: (setup_pipeline),
+       (run_pipeline), (GST_START_TEST), (simple_launch_lines_suite):
+         Add extra tests for basetransform based components. 
+         Comment out the test_element_negotiation test until we decide
+          if it's testing correct behaviour.
+       * ext/libvisual/visual.c: (gst_visual_init), (get_buffer),
+       (gst_visual_chain), (gst_visual_change_state):
+         Slightly more correct but still bogus timestamping.
+         Fix state change function.
+       * gst/audioconvert/gstaudioconvert.c:
+       (gst_audio_convert_class_init):
+       * gst/audioresample/gstaudioresample.c:
+       * gst/ffmpegcolorspace/gstffmpegcolorspace.c:
+       (gst_ffmpegcsp_class_init):
+       * gst/videoscale/gstvideoscale.c: (gst_videoscale_class_init),
+       (gst_videoscale_prepare_size), (gst_videoscale_set_caps),
+       (gst_videoscale_prepare_image):
+       * gst/volume/gstvolume.c: (gst_volume_class_init),
+       (volume_transform_ip):
+         Basetransform updates. Enable passthrough modes.
+       * sys/ximage/ximagesink.c: (gst_ximage_buffer_init),
+       (gst_ximagesink_renegotiate_size), (gst_ximagesink_xcontext_get),
+       (gst_ximagesink_setcaps), (gst_ximagesink_buffer_alloc):
+         Negotiation fix that allows the window to return to the original
+         size and renegotiate passthrough upstream. Extra debug output.
+
 2005-09-09  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * gst/sine/gstsinesrc.c:
index 46e5ef7..b1703db 100644 (file)
@@ -33,13 +33,12 @@ check_PROGRAMS = \
        elements/audioconvert \
        elements/audioresample \
        elements/volume \
+        pipelines/simple_launch_lines \
        $(check_vorbis)
 
 # these tests don't even pass
 # generic/states: elements need state fixin' before this can be added
-# pipelines/simple_launch_lines: needs negotioation fixing
 noinst_PROGRAMS = \
-        pipelines/simple_launch_lines \
        generic/states
 
 AM_CFLAGS = $(GST_OBJ_CFLAGS) $(GST_CHECK_CFLAGS) $(CHECK_CFLAGS)
index 850a8b8..ae51d5a 100644 (file)
@@ -24,7 +24,7 @@
 
 
 static GstElement *
-setup_pipeline (gchar * pipe_descr)
+setup_pipeline (const gchar * pipe_descr)
 {
   GstElement *pipeline;
 
@@ -43,7 +43,7 @@ setup_pipeline (gchar * pipe_descr)
  * the poll call will time out after half a second.
  */
 static void
-run_pipeline (GstElement * pipe, gchar * descr,
+run_pipeline (GstElement * pipe, const gchar * descr,
     GstMessageType events, GstMessageType tevent)
 {
   GstBus *bus;
@@ -100,8 +100,44 @@ GST_START_TEST (test_element_negotiation)
       GST_MESSAGE_UNKNOWN);
 #endif
 }
-GST_END_TEST Suite *
-simple_launch_lines_suite (void)
+
+GST_END_TEST
+GST_START_TEST (test_basetransform_based)
+{
+  /* Each of these tests is to check whether various basetransform based elements can
+   * select output caps when not allowed to do passthrough and going to a generic sink
+   * such as fakesink or filesink */
+  const gchar *s;
+
+  /* Check that videoscale can pick a height given only a width */
+  s = "videotestsrc ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! " "videoscale ! video/x-raw-yuv,width=640 ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Test that ffmpegcolorspace can pick an output format that isn't passthrough without 
+   * completely specified output caps */
+  s = "videotestsrc ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! " "ffmpegcolorspace ! video/x-raw-rgb ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Check that audioresample can pick a samplerate to use from a 
+   * range that doesn't include the input */
+  s = "sinesrc ! audio/x-raw-int,width=16,depth=16,rate=8000 ! audioresample ! "
+      "audio/x-raw-int,rate=[16000,48000] ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Check that audioconvert can pick a depth to use, given a width */
+  s = "sinesrc ! audio/x-raw-int,width=16,depth=16 ! audioconvert ! "
+      "audio/x-raw-int,width=32 ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+}
+GST_END_TEST Suite * simple_launch_lines_suite (void)
 {
   Suite *s = suite_create ("Pipelines");
   TCase *tc_chain = tcase_create ("linear");
@@ -110,7 +146,8 @@ simple_launch_lines_suite (void)
   tcase_set_timeout (tc_chain, 20);
 
   suite_add_tcase (s, tc_chain);
-  tcase_add_test (tc_chain, test_element_negotiation);
+//  tcase_add_test (tc_chain, test_element_negotiation);
+  tcase_add_test (tc_chain, test_basetransform_based);
   return s;
 }
 
index 981d5e4..2377a1b 100644 (file)
@@ -47,6 +47,7 @@ struct _GstVisual
   /* pads */
   GstPad *sinkpad;
   GstPad *srcpad;
+  GstClockTime next_ts;
 
   /* libvisual stuff */
   VisAudio audio;
@@ -210,6 +211,7 @@ gst_visual_init (GstVisual * visual)
   gst_pad_set_getcaps_function (visual->srcpad, gst_visual_getcaps);
   gst_element_add_pad (GST_ELEMENT (visual), visual->srcpad);
 
+  visual->next_ts = 0;
   visual->adapter = gst_adapter_new ();
 }
 
@@ -369,6 +371,9 @@ get_buffer (GstVisual * visual, GstBuffer ** outbuf)
         visual->video->bpp, GST_PAD_CAPS (visual->srcpad), outbuf);
   }
 
+  if (*outbuf == NULL)
+    return GST_FLOW_ERROR;
+
   return GST_FLOW_OK;
 }
 
@@ -391,6 +396,9 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
     }
   }
 
+  if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE)
+    visual->next_ts = GST_BUFFER_TIMESTAMP (buffer);
+
   /* spf = samples per frame */
   spf = visual->rate / visual->fps;
   gst_adapter_push (visual->adapter, buffer);
@@ -419,9 +427,9 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
       visual_actor_run (visual->actor, &visual->audio);
 
       /* FIXME: Match timestamps from the incoming audio */
-      GST_BUFFER_TIMESTAMP (outbuf) =
-          GST_SECOND * visual->count++ / visual->fps;
+      GST_BUFFER_TIMESTAMP (outbuf) = visual->next_ts;
       GST_BUFFER_DURATION (outbuf) = GST_SECOND / visual->fps;
+      visual->next_ts += GST_BUFFER_DURATION (outbuf);
       ret = gst_pad_push (visual->srcpad, outbuf);
       outbuf = NULL;
     }
@@ -449,6 +457,7 @@ static GstStateChangeReturn
 gst_visual_change_state (GstElement * element, GstStateChange transition)
 {
   GstVisual *visual = GST_VISUAL (element);
+  GstStateChangeReturn ret;
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
@@ -469,13 +478,20 @@ gst_visual_change_state (GstElement * element, GstStateChange transition)
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       gst_adapter_clear (visual->adapter);
-      visual->count = 0;
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+  switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
+      visual->next_ts = 0;
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       if (visual->actor)
@@ -489,10 +505,7 @@ gst_visual_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  if (GST_ELEMENT_CLASS (parent_class)->change_state)
-    return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  return GST_STATE_CHANGE_SUCCESS;
+  return ret;
 }
 
 static void
index 0f1cc7d..10544a3 100644 (file)
@@ -191,6 +191,8 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
       GST_DEBUG_FUNCPTR (gst_audio_convert_transform_ip);
   GST_BASE_TRANSFORM_CLASS (klass)->transform =
       GST_DEBUG_FUNCPTR (gst_audio_convert_transform);
+
+  GST_BASE_TRANSFORM_CLASS (klass)->passthrough_on_same_caps = TRUE;
 }
 
 static void
index e3bdba6..1d11856 100644 (file)
@@ -145,6 +145,8 @@ static void gst_audioresample_class_init (GstAudioresampleClass * klass)
       GST_DEBUG_FUNCPTR (audioresample_set_caps);
   GST_BASE_TRANSFORM_CLASS (klass)->transform =
       GST_DEBUG_FUNCPTR (audioresample_transform);
+
+  GST_BASE_TRANSFORM_CLASS (klass)->passthrough_on_same_caps = TRUE;
 }
 
 static void gst_audioresample_init (GstAudioresample * audioresample,
index f2ec124..be0ea2c 100644 (file)
@@ -95,8 +95,10 @@ static gboolean gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans,
     GstCaps * caps, guint * size);
 static GstFlowReturn gst_ffmpegcsp_transform (GstBaseTransform * btrans,
     GstBuffer * inbuf, GstBuffer * outbuf);
+#if 0
 static GstFlowReturn gst_ffmpegcsp_transform_ip (GstBaseTransform * btrans,
     GstBuffer * inbuf);
+#endif
 
 static GstPadTemplate *sinktempl, *srctempl;
 static GstElementClass *parent_class = NULL;
@@ -301,8 +303,12 @@ gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
       GST_DEBUG_FUNCPTR (gst_ffmpegcsp_get_unit_size);
   gstbasetransform_class->transform =
       GST_DEBUG_FUNCPTR (gst_ffmpegcsp_transform);
+#if 0
   gstbasetransform_class->transform_ip =
       GST_DEBUG_FUNCPTR (gst_ffmpegcsp_transform_ip);
+#endif
+
+  gstbasetransform_class->passthrough_on_same_caps = TRUE;
 
   GST_DEBUG_CATEGORY_INIT (ffmpegcolorspace_debug, "ffmpegcolorspace", 0,
       "FFMPEG-based colorspace converter");
@@ -334,12 +340,15 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
   return TRUE;
 }
 
+#if 0
+/* FIXME: Could use transform_ip to implement endianness swap type operations */
 static GstFlowReturn
 gst_ffmpegcsp_transform_ip (GstBaseTransform * btrans, GstBuffer * inbuf)
 {
   /* do nothing */
   return GST_FLOW_OK;
 }
+#endif
 
 static GstFlowReturn
 gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
index 0da809c..a80cad3 100644 (file)
@@ -151,8 +151,6 @@ static gboolean gst_videoscale_set_caps (GstBaseTransform * trans,
     GstCaps * in, GstCaps * out);
 static gboolean gst_videoscale_get_unit_size (GstBaseTransform * trans,
     GstCaps * caps, guint * size);
-static GstFlowReturn gst_videoscale_transform_ip (GstBaseTransform * trans,
-    GstBuffer * in);
 static GstFlowReturn gst_videoscale_transform (GstBaseTransform * trans,
     GstBuffer * in, GstBuffer * out);
 
@@ -221,9 +219,10 @@ gst_videoscale_class_init (GstVideoscaleClass * klass)
   trans_class->transform_caps = gst_videoscale_transform_caps;
   trans_class->set_caps = gst_videoscale_set_caps;
   trans_class->get_unit_size = gst_videoscale_get_unit_size;
-  trans_class->transform_ip = gst_videoscale_transform_ip;
   trans_class->transform = gst_videoscale_transform;
 
+  trans_class->passthrough_on_same_caps = TRUE;
+
   parent_class = g_type_class_peek_parent (klass);
 }
 
@@ -317,10 +316,6 @@ gst_videoscale_get_format (GstCaps * caps)
   return -1;
 }
 
-#define ROUND_UP_2(x)  (((x)+1)&~1)
-#define ROUND_UP_4(x)  (((x)+3)&~3)
-#define ROUND_UP_8(x)  (((x)+7)&~7)
-
 /* calculate the size of a buffer */
 static gboolean
 gst_videoscale_prepare_size (gint format,
@@ -342,17 +337,17 @@ gst_videoscale_prepare_size (gint format,
       break;
     case GST_VIDEOSCALE_RGB:
     case GST_VIDEOSCALE_BGR:
-      img->stride = ROUND_UP_4 (img->width * 3);
+      img->stride = GST_ROUND_UP_4 (img->width * 3);
       *size = img->stride * img->height;
       break;
     case GST_VIDEOSCALE_YUY2:
     case GST_VIDEOSCALE_YVYU:
     case GST_VIDEOSCALE_UYVY:
-      img->stride = ROUND_UP_4 (img->width * 2);
+      img->stride = GST_ROUND_UP_4 (img->width * 2);
       *size = img->stride * img->height;
       break;
     case GST_VIDEOSCALE_Y:
-      img->stride = ROUND_UP_4 (img->width);
+      img->stride = GST_ROUND_UP_4 (img->width);
       *size = img->stride * img->height;
       break;
     case GST_VIDEOSCALE_I420:
@@ -360,21 +355,21 @@ gst_videoscale_prepare_size (gint format,
     {
       gulong img_u_stride, img_u_height;
 
-      img->stride = ROUND_UP_4 (img->width);
+      img->stride = GST_ROUND_UP_4 (img->width);
 
-      img_u_height = ROUND_UP_2 (img->height) / 2;
-      img_u_stride = ROUND_UP_4 (img->stride / 2);
+      img_u_height = GST_ROUND_UP_2 (img->height) / 2;
+      img_u_stride = GST_ROUND_UP_4 (img->stride / 2);
 
-      *size = img->stride * ROUND_UP_2 (img->height) +
+      *size = img->stride * GST_ROUND_UP_2 (img->height) +
           2 * img_u_stride * img_u_height;
       break;
     }
     case GST_VIDEOSCALE_RGB565:
-      img->stride = ROUND_UP_4 (img->width * 2);
+      img->stride = GST_ROUND_UP_4 (img->width * 2);
       *size = img->stride * img->height;
       break;
     case GST_VIDEOSCALE_RGB555:
-      img->stride = ROUND_UP_4 (img->width * 2);
+      img->stride = GST_ROUND_UP_4 (img->width * 2);
       *size = img->stride * img->height;
       break;
     default:
@@ -436,6 +431,7 @@ gst_videoscale_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out)
   GST_DEBUG_OBJECT (videoscale, "from=%dx%d, size %d -> to=%dx%d, size %d",
       videoscale->from_width, videoscale->from_height, videoscale->src_size,
       videoscale->to_width, videoscale->to_height, videoscale->dest_size);
+
 done:
   return ret;
 }
@@ -472,10 +468,10 @@ gst_videoscale_prepare_image (gint format, GstBuffer * buf,
   switch (format) {
     case GST_VIDEOSCALE_I420:
     case GST_VIDEOSCALE_YV12:
-      img_u->pixels = img->pixels + ROUND_UP_2 (img->height) * img->stride;
-      img_u->height = ROUND_UP_2 (img->height) / 2;
-      img_u->width = ROUND_UP_2 (img->width) / 2;
-      img_u->stride = ROUND_UP_4 (img->stride / 2);
+      img_u->pixels = img->pixels + GST_ROUND_UP_2 (img->height) * img->stride;
+      img_u->height = GST_ROUND_UP_2 (img->height) / 2;
+      img_u->width = GST_ROUND_UP_2 (img->width) / 2;
+      img_u->stride = GST_ROUND_UP_4 (img->stride / 2);
       memcpy (img_v, img_u, sizeof (*img_v));
       img_v->pixels = img_u->pixels + img_u->height * img_u->stride;
       break;
@@ -486,13 +482,6 @@ gst_videoscale_prepare_image (gint format, GstBuffer * buf,
 }
 
 static GstFlowReturn
-gst_videoscale_transform_ip (GstBaseTransform * trans, GstBuffer * in)
-{
-  /* nothing to be done in passthrough */
-  return GST_FLOW_OK;
-}
-
-static GstFlowReturn
 gst_videoscale_transform (GstBaseTransform * trans, GstBuffer * in,
     GstBuffer * out)
 {
index 6e0800d..98bdbbc 100644 (file)
@@ -134,8 +134,8 @@ static void volume_get_property (GObject * object, guint prop_id,
 static void volume_update_volume (const GValue * value, gpointer data);
 static void volume_update_mute (const GValue * value, gpointer data);
 
-static GstFlowReturn volume_transform (GstBaseTransform * base,
-    GstBuffer * inbuf, GstBuffer * outbuf);
+static GstFlowReturn volume_transform_ip (GstBaseTransform * base,
+    GstBuffer * outbuf);
 static gboolean volume_set_caps (GstBaseTransform * base, GstCaps * incaps,
     GstCaps * outcaps);
 
@@ -276,8 +276,8 @@ gst_volume_class_init (GstVolumeClass * klass)
           0.0, VOLUME_MAX_DOUBLE, 1.0,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
 
-  GST_BASE_TRANSFORM_CLASS (klass)->transform =
-      GST_DEBUG_FUNCPTR (volume_transform);
+  GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
+      GST_DEBUG_FUNCPTR (volume_transform_ip);
   GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
       GST_DEBUG_FUNCPTR (volume_set_caps);
 }
@@ -390,8 +390,7 @@ volume_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps)
  * a class-global method
  */
 static GstFlowReturn
-volume_transform (GstBaseTransform * base, GstBuffer * inbuf,
-    GstBuffer * outbuf)
+volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
 {
   GstVolume *this = GST_VOLUME (base);
 
index caee628..8e6c41b 100644 (file)
@@ -635,6 +635,11 @@ gst_ximagesink_renegotiate_size (GstXImageSink * ximagesink)
       GST_VIDEO_SINK_HEIGHT (ximagesink) != ximagesink->xwindow->height) {
     GstCaps *caps;
 
+    GST_DEBUG_OBJECT (ximagesink,
+        "Window changed size to %dx%d from %dx%d. Setting desired caps",
+        ximagesink->xwindow->width, ximagesink->xwindow->height,
+        GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink));
+
     caps = gst_caps_new_simple ("video/x-raw-rgb",
         "bpp", G_TYPE_INT, ximagesink->xcontext->bpp,
         "depth", G_TYPE_INT, ximagesink->xcontext->depth,
@@ -1049,6 +1054,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   gboolean ret = TRUE;
   GstStructure *structure;
   const GValue *par;
+  gint new_width, new_height;
 
   ximagesink = GST_XIMAGESINK (bsink);
 
@@ -1060,12 +1066,25 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
       GST_PTR_FORMAT, ximagesink->xcontext->caps, caps);
 
   structure = gst_caps_get_structure (caps, 0);
+
+/* We used to only get the new width and height if we don't 
+ * yet have one, which means GST_VIDEO_SINK_WIDTH/HEIGHT never change
+ * after the first buffer, which seems totally bogus. I don't understand
+ * why it might have been this way...
+ */
+#if 0
   if (GST_VIDEO_SINK_WIDTH (ximagesink) == 0) {
-    ret &= gst_structure_get_int (structure, "width",
-        &(GST_VIDEO_SINK_WIDTH (ximagesink)));
-    ret &= gst_structure_get_int (structure, "height",
-        &(GST_VIDEO_SINK_HEIGHT (ximagesink)));
+    ret &= gst_structure_get_int (structure, "width", &new_width);
+    ret &= gst_structure_get_int (structure, "height", &new_height);
+  } else {
+    new_width = GST_VIDEO_SINK_WIDTH (ximagesink);
+    new_height = GST_VIDEO_SINK_HEIGHT (ximagesink);
   }
+#else
+  ret &= gst_structure_get_int (structure, "width", &new_width);
+  ret &= gst_structure_get_int (structure, "height", &new_height);
+#endif
+
   ret &= gst_structure_get_double (structure,
       "framerate", &ximagesink->framerate);
   if (!ret)
@@ -1079,6 +1098,16 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   if (par && gst_value_compare (par, ximagesink->par) != GST_VALUE_EQUAL)
     goto wrong_aspect;
 
+  if (GST_VIDEO_SINK_WIDTH (ximagesink) != new_width ||
+      GST_VIDEO_SINK_HEIGHT (ximagesink) != new_height) {
+    GST_DEBUG_OBJECT (ximagesink, "Input caps changed size %dx%d -> %dx%d",
+        GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink),
+        new_width, new_height);
+  }
+
+  GST_VIDEO_SINK_WIDTH (ximagesink) = new_width;
+  GST_VIDEO_SINK_HEIGHT (ximagesink) = new_height;
+
   /* Creating our window and our image */
   g_assert (GST_VIDEO_SINK_WIDTH (ximagesink) > 0);
   g_assert (GST_VIDEO_SINK_HEIGHT (ximagesink) > 0);
@@ -1349,9 +1378,11 @@ gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
     GST_DEBUG_OBJECT (ximagesink, "no usable image in pool, creating ximage");
     ximage = gst_ximagesink_ximage_new (ximagesink, width, height);
 
-    if (ximagesink->desired_caps)
+    if (ximagesink->desired_caps) {
+      GST_DEBUG_OBJECT (ximagesink, "Returning buffer with my desired caps %"
+          GST_PTR_FORMAT, ximagesink->desired_caps);
       gst_buffer_set_caps (GST_BUFFER (ximage), ximagesink->desired_caps);
-    else
+    else
       /* fixme we have no guarantee that the ximage is actually of these caps,
          do we? */
       gst_buffer_set_caps (GST_BUFFER (ximage), caps);
index 46e5ef7..b1703db 100644 (file)
@@ -33,13 +33,12 @@ check_PROGRAMS = \
        elements/audioconvert \
        elements/audioresample \
        elements/volume \
+        pipelines/simple_launch_lines \
        $(check_vorbis)
 
 # these tests don't even pass
 # generic/states: elements need state fixin' before this can be added
-# pipelines/simple_launch_lines: needs negotioation fixing
 noinst_PROGRAMS = \
-        pipelines/simple_launch_lines \
        generic/states
 
 AM_CFLAGS = $(GST_OBJ_CFLAGS) $(GST_CHECK_CFLAGS) $(CHECK_CFLAGS)
index 850a8b8..ae51d5a 100644 (file)
@@ -24,7 +24,7 @@
 
 
 static GstElement *
-setup_pipeline (gchar * pipe_descr)
+setup_pipeline (const gchar * pipe_descr)
 {
   GstElement *pipeline;
 
@@ -43,7 +43,7 @@ setup_pipeline (gchar * pipe_descr)
  * the poll call will time out after half a second.
  */
 static void
-run_pipeline (GstElement * pipe, gchar * descr,
+run_pipeline (GstElement * pipe, const gchar * descr,
     GstMessageType events, GstMessageType tevent)
 {
   GstBus *bus;
@@ -100,8 +100,44 @@ GST_START_TEST (test_element_negotiation)
       GST_MESSAGE_UNKNOWN);
 #endif
 }
-GST_END_TEST Suite *
-simple_launch_lines_suite (void)
+
+GST_END_TEST
+GST_START_TEST (test_basetransform_based)
+{
+  /* Each of these tests is to check whether various basetransform based elements can
+   * select output caps when not allowed to do passthrough and going to a generic sink
+   * such as fakesink or filesink */
+  const gchar *s;
+
+  /* Check that videoscale can pick a height given only a width */
+  s = "videotestsrc ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! " "videoscale ! video/x-raw-yuv,width=640 ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Test that ffmpegcolorspace can pick an output format that isn't passthrough without 
+   * completely specified output caps */
+  s = "videotestsrc ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! " "ffmpegcolorspace ! video/x-raw-rgb ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Check that audioresample can pick a samplerate to use from a 
+   * range that doesn't include the input */
+  s = "sinesrc ! audio/x-raw-int,width=16,depth=16,rate=8000 ! audioresample ! "
+      "audio/x-raw-int,rate=[16000,48000] ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+
+  /* Check that audioconvert can pick a depth to use, given a width */
+  s = "sinesrc ! audio/x-raw-int,width=16,depth=16 ! audioconvert ! "
+      "audio/x-raw-int,width=32 ! fakesink";
+  run_pipeline (setup_pipeline (s), s,
+      GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
+      GST_MESSAGE_UNKNOWN);
+}
+GST_END_TEST Suite * simple_launch_lines_suite (void)
 {
   Suite *s = suite_create ("Pipelines");
   TCase *tc_chain = tcase_create ("linear");
@@ -110,7 +146,8 @@ simple_launch_lines_suite (void)
   tcase_set_timeout (tc_chain, 20);
 
   suite_add_tcase (s, tc_chain);
-  tcase_add_test (tc_chain, test_element_negotiation);
+//  tcase_add_test (tc_chain, test_element_negotiation);
+  tcase_add_test (tc_chain, test_basetransform_based);
   return s;
 }