/* GStreamer * Copyright (C) 2010 Thiago Santos * * capsfilter-renegotiation.c: Unit test for capsfilter caps renegotiation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* Ideally this would be in core, but using videotestsrc makes it easier */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #define FIRST_CAPS "video/x-raw,width=(int)480,height=(int)320" #define SECOND_CAPS "video/x-raw,width=(int)120,height=(int)100" #define THIRD_CAPS "video/x-raw,width=(int)[10,50],height=(int)[100,200]" #define FOURTH_CAPS "video/x-raw,width=(int)300,height=(int)[25,75];" \ "video/x-raw,width=(int)[30,40]," \ "height=(int)[100,200],format=(string)YUY2" int buffer_count = 0; GstCaps *current_caps = NULL; int caps_change = 0; static GstPadProbeReturn buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data) { GstCaps *pad_caps; GstElement *capsfilter = GST_ELEMENT (data); GstCaps *caps = NULL; /* increment the buffer count and check if it is time to change the caps */ buffer_count++; if (buffer_count == 50) { /* change the caps to another one */ caps = gst_caps_from_string (SECOND_CAPS); } else if (buffer_count == 100) { /* change the caps to another one, this time unfixed */ caps = gst_caps_from_string (THIRD_CAPS); } else if (buffer_count == 150) { /* change the caps to another one, * this time unfixed with multiple entries */ caps = gst_caps_from_string (FOURTH_CAPS); } /* set the caps */ if (caps) { g_object_set (capsfilter, "caps", caps, NULL); gst_caps_unref (caps); } /* now check if the pad caps has changed since last check */ pad_caps = gst_pad_get_current_caps (pad); if (current_caps == NULL && pad_caps != NULL) { /* probably the first caps, this is a change */ current_caps = gst_caps_copy (pad_caps); caps_change++; } else if (current_caps != NULL) { if (pad_caps == NULL) { /* caps was set to NULL, we consider this a change */ gst_caps_unref (current_caps); current_caps = NULL; caps_change++; } else { if (!gst_caps_is_equal (current_caps, pad_caps)) { /* a caps change */ gst_caps_unref (current_caps); current_caps = gst_caps_copy (pad_caps); caps_change++; } } } gst_caps_unref (pad_caps); return TRUE; } /* launch line is a pipeline that must have a capsfilter named 'cf' that * will be used to trigger the renegotiation */ static void run_capsfilter_renegotiation (const gchar * launch_line) { GstElement *capsfilter; GstElement *sink; GstElement *pipeline; GstBus *bus; GstMessage *msg; GstPad *pad; caps_change = 0; buffer_count = 0; if (current_caps) gst_caps_unref (current_caps); current_caps = NULL; pipeline = gst_parse_launch (launch_line, NULL); fail_unless (pipeline != NULL); capsfilter = gst_bin_get_by_name (GST_BIN (pipeline), "cf"); fail_unless (capsfilter != NULL); sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); fail_unless (sink != NULL); pad = gst_element_get_static_pad (sink, "sink"); gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe, capsfilter, NULL); gst_object_unref (pad); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE); msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS | GST_MESSAGE_ERROR); fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS); fail_unless_equals_int (caps_change, 4); gst_element_set_state (pipeline, GST_STATE_NULL); if (current_caps) gst_caps_unref (current_caps); current_caps = NULL; gst_message_unref (msg); g_object_unref (bus); gst_object_unref (sink); gst_object_unref (capsfilter); g_object_unref (G_OBJECT (pipeline)); } GST_START_TEST (test_capsfilter_renegotiation) { run_capsfilter_renegotiation ("videotestsrc num-buffers=200 " " ! capsfilter caps=\"" FIRST_CAPS "\" name=cf ! fakesink name=sink"); run_capsfilter_renegotiation ("videotestsrc num-buffers=200 " " ! capsfilter caps=\"" FIRST_CAPS "\" name=cf ! fakesink name=sink"); run_capsfilter_renegotiation ("videotestsrc num-buffers=200 " " ! capsfilter caps=\"video/x-raw, format=(string)I420, width=(int)100, height=(int)100\" " " ! videoconvert ! videoscale ! capsfilter caps=\"" FIRST_CAPS "\" name=cf " " ! fakesink name=sink"); } GST_END_TEST; static Suite * capsfilter_renegotiation_suite (void) { Suite *s = suite_create ("CapsfilterRenegotiation"); TCase *tc_chain = tcase_create ("linear"); /* time out after 60s, not the default 3 */ tcase_set_timeout (tc_chain, 60); suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_capsfilter_renegotiation); return s; } GST_CHECK_MAIN (capsfilter_renegotiation);