From 0f4fa24d8e3b39b4111c5af88e7302c608c5707e Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 9 Sep 2005 17:53:47 +0000 Subject: [PATCH] check/: Add extra tests for basetransform based components. 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. --- ChangeLog | 29 +++++++++++++ check/Makefile.am | 3 +- check/pipelines/simple_launch_lines.c | 47 ++++++++++++++++++--- ext/libvisual/visual.c | 27 +++++++++--- gst/audioconvert/gstaudioconvert.c | 2 + gst/audioresample/gstaudioresample.c | 2 + gst/ffmpegcolorspace/gstffmpegcolorspace.c | 9 ++++ gst/videoscale/gstvideoscale.c | 43 +++++++------------ gst/volume/gstvolume.c | 11 +++-- sys/ximage/ximagesink.c | 43 ++++++++++++++++--- tests/check/Makefile.am | 3 +- tests/check/pipelines/simple-launch-lines.c | 47 ++++++++++++++++++--- 12 files changed, 206 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27d5039899..9dce39f2eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2005-09-09 Jan Schmidt + + * 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 * gst/sine/gstsinesrc.c: diff --git a/check/Makefile.am b/check/Makefile.am index 46e5ef74b5..b1703db3e8 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -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) diff --git a/check/pipelines/simple_launch_lines.c b/check/pipelines/simple_launch_lines.c index 850a8b8130..ae51d5aa38 100644 --- a/check/pipelines/simple_launch_lines.c +++ b/check/pipelines/simple_launch_lines.c @@ -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; } diff --git a/ext/libvisual/visual.c b/ext/libvisual/visual.c index 981d5e4978..2377a1b37c 100644 --- a/ext/libvisual/visual.c +++ b/ext/libvisual/visual.c @@ -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 diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index 0f1cc7d365..10544a38e6 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -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 diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index e3bdba6752..1d11856e33 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -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, diff --git a/gst/ffmpegcolorspace/gstffmpegcolorspace.c b/gst/ffmpegcolorspace/gstffmpegcolorspace.c index f2ec124749..be0ea2cfcc 100644 --- a/gst/ffmpegcolorspace/gstffmpegcolorspace.c +++ b/gst/ffmpegcolorspace/gstffmpegcolorspace.c @@ -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, diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c index 0da809c657..a80cad3a3d 100644 --- a/gst/videoscale/gstvideoscale.c +++ b/gst/videoscale/gstvideoscale.c @@ -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; @@ -485,13 +481,6 @@ gst_videoscale_prepare_image (gint format, GstBuffer * buf, return res; } -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) diff --git a/gst/volume/gstvolume.c b/gst/volume/gstvolume.c index 6e0800df70..98bdbbc82e 100644 --- a/gst/volume/gstvolume.c +++ b/gst/volume/gstvolume.c @@ -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); diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index caee628f95..8e6c41b588 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -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); diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 46e5ef74b5..b1703db3e8 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -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) diff --git a/tests/check/pipelines/simple-launch-lines.c b/tests/check/pipelines/simple-launch-lines.c index 850a8b8130..ae51d5aa38 100644 --- a/tests/check/pipelines/simple-launch-lines.c +++ b/tests/check/pipelines/simple-launch-lines.c @@ -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; }