mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
adder: use collectpads clipping function
Install a clipping function in the collectpads and use the audio clipping helper function to perform clipping to the segment boundaries. Fixes #590265
This commit is contained in:
parent
66ae01eced
commit
59ace1b9ee
3 changed files with 132 additions and 3 deletions
|
@ -1,10 +1,12 @@
|
||||||
plugin_LTLIBRARIES = libgstadder.la
|
plugin_LTLIBRARIES = libgstadder.la
|
||||||
|
|
||||||
libgstadder_la_SOURCES = gstadder.c
|
libgstadder_la_SOURCES = gstadder.c
|
||||||
libgstadder_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
libgstadder_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||||
#$(LIBOIL_CFLAGS)
|
#$(LIBOIL_CFLAGS)
|
||||||
libgstadder_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstadder_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstadder_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
libgstadder_la_LIBADD = \
|
||||||
|
$(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \
|
||||||
|
$(GST_BASE_LIBS) $(GST_LIBS)
|
||||||
#$(LIBOIL_LIBS)
|
#$(LIBOIL_LIBS)
|
||||||
libgstadder_la_LIBTOOLFLAGS = --tag=disable-static
|
libgstadder_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,8 @@ static void gst_adder_release_pad (GstElement * element, GstPad * pad);
|
||||||
static GstStateChangeReturn gst_adder_change_state (GstElement * element,
|
static GstStateChangeReturn gst_adder_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
|
||||||
|
static GstBuffer *gst_adder_do_clip (GstCollectPads * pads,
|
||||||
|
GstCollectData * data, GstBuffer * buffer, gpointer user_data);
|
||||||
static GstFlowReturn gst_adder_collected (GstCollectPads * pads,
|
static GstFlowReturn gst_adder_collected (GstCollectPads * pads,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
@ -780,7 +782,7 @@ gst_adder_sink_event (GstPad * pad, GstEvent * event)
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
/* we received a flush-stop. The collect_event function will push the
|
/* we received a flush-stop. The collect_event function will push the
|
||||||
* event past our element. We simply forward all flush-stop events, even
|
* event past our element. We simply forward all flush-stop events, even
|
||||||
* when no flush-stop was pendingk, this is required because collectpads
|
* when no flush-stop was pending, this is required because collectpads
|
||||||
* does not provide an API to handle-but-not-forward the flush-stop.
|
* does not provide an API to handle-but-not-forward the flush-stop.
|
||||||
* We unset the pending flush-stop flag so that we don't send anymore
|
* We unset the pending flush-stop flag so that we don't send anymore
|
||||||
* flush-stop from the collect function later.
|
* flush-stop from the collect function later.
|
||||||
|
@ -882,6 +884,8 @@ gst_adder_init (GstAdder * adder)
|
||||||
adder->collect = gst_collect_pads_new ();
|
adder->collect = gst_collect_pads_new ();
|
||||||
gst_collect_pads_set_function (adder->collect,
|
gst_collect_pads_set_function (adder->collect,
|
||||||
GST_DEBUG_FUNCPTR (gst_adder_collected), adder);
|
GST_DEBUG_FUNCPTR (gst_adder_collected), adder);
|
||||||
|
gst_collect_pads_set_clip_function (adder->collect,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_adder_do_clip), adder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1023,6 +1027,18 @@ gst_adder_release_pad (GstElement * element, GstPad * pad)
|
||||||
gst_element_remove_pad (element, pad);
|
gst_element_remove_pad (element, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstBuffer *
|
||||||
|
gst_adder_do_clip (GstCollectPads * pads, GstCollectData * data,
|
||||||
|
GstBuffer * buffer, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstAdder *adder = GST_ADDER (user_data);
|
||||||
|
|
||||||
|
buffer = gst_audio_buffer_clip (buffer, &data->segment, adder->rate,
|
||||||
|
adder->bps);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -732,6 +732,116 @@ GST_START_TEST (test_remove_pad)
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
|
static GstBuffer *handoff_buffer = NULL;
|
||||||
|
static void
|
||||||
|
handoff_buffer_cb (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GST_DEBUG ("got buffer %p", buffer);
|
||||||
|
gst_buffer_replace (&handoff_buffer, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if clipping works as expected */
|
||||||
|
GST_START_TEST (test_clip)
|
||||||
|
{
|
||||||
|
GstElement *bin, *adder, *sink;
|
||||||
|
GstBus *bus;
|
||||||
|
GstPad *sinkpad;
|
||||||
|
gboolean res;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GstEvent *event;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
GST_INFO ("preparing test");
|
||||||
|
|
||||||
|
/* build pipeline */
|
||||||
|
bin = gst_pipeline_new ("pipeline");
|
||||||
|
bus = gst_element_get_bus (bin);
|
||||||
|
gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
|
||||||
|
|
||||||
|
g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
|
||||||
|
g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
|
||||||
|
g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
|
||||||
|
|
||||||
|
/* just an adder and a fakesink */
|
||||||
|
adder = gst_element_factory_make ("adder", "adder");
|
||||||
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
|
g_object_set (sink, "signal-handoffs", TRUE, NULL);
|
||||||
|
g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_cb, NULL);
|
||||||
|
gst_bin_add_many (GST_BIN (bin), adder, sink, NULL);
|
||||||
|
|
||||||
|
res = gst_element_link (adder, sink);
|
||||||
|
fail_unless (res == TRUE, NULL);
|
||||||
|
|
||||||
|
/* set to playing */
|
||||||
|
res = gst_element_set_state (bin, GST_STATE_PLAYING);
|
||||||
|
fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
|
||||||
|
|
||||||
|
/* create an unconnected sinkpad in adder, should also automatically activate
|
||||||
|
* the pad */
|
||||||
|
sinkpad = gst_element_get_request_pad (adder, "sink%d");
|
||||||
|
fail_if (sinkpad == NULL, NULL);
|
||||||
|
|
||||||
|
/* send segment to adder */
|
||||||
|
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
|
||||||
|
GST_SECOND, 2 * GST_SECOND, 0);
|
||||||
|
gst_pad_send_event (sinkpad, event);
|
||||||
|
|
||||||
|
caps = gst_caps_new_simple ("audio/x-raw-int",
|
||||||
|
"rate", G_TYPE_INT, 44100,
|
||||||
|
"channels", G_TYPE_INT, 2,
|
||||||
|
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||||
|
"width", G_TYPE_INT, 16,
|
||||||
|
"depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||||
|
|
||||||
|
/* should be clipped and ok */
|
||||||
|
buffer = gst_buffer_new_and_alloc (44100);
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) = 0;
|
||||||
|
GST_BUFFER_DURATION (buffer) = 250 * GST_MSECOND;
|
||||||
|
gst_buffer_set_caps (buffer, caps);
|
||||||
|
GST_DEBUG ("pushing buffer %p", buffer);
|
||||||
|
ret = gst_pad_chain (sinkpad, buffer);
|
||||||
|
fail_unless (ret == GST_FLOW_OK);
|
||||||
|
fail_unless (handoff_buffer == NULL);
|
||||||
|
|
||||||
|
/* should be partially clipped */
|
||||||
|
buffer = gst_buffer_new_and_alloc (44100);
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) = 900 * GST_MSECOND;
|
||||||
|
GST_BUFFER_DURATION (buffer) = 250 * GST_MSECOND;
|
||||||
|
gst_buffer_set_caps (buffer, caps);
|
||||||
|
GST_DEBUG ("pushing buffer %p", buffer);
|
||||||
|
ret = gst_pad_chain (sinkpad, buffer);
|
||||||
|
fail_unless (ret == GST_FLOW_OK);
|
||||||
|
fail_unless (handoff_buffer != NULL);
|
||||||
|
gst_buffer_replace (&handoff_buffer, NULL);
|
||||||
|
|
||||||
|
/* should not be clipped */
|
||||||
|
buffer = gst_buffer_new_and_alloc (44100);
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
|
||||||
|
GST_BUFFER_DURATION (buffer) = 250 * GST_MSECOND;
|
||||||
|
gst_buffer_set_caps (buffer, caps);
|
||||||
|
GST_DEBUG ("pushing buffer %p", buffer);
|
||||||
|
ret = gst_pad_chain (sinkpad, buffer);
|
||||||
|
fail_unless (ret == GST_FLOW_OK);
|
||||||
|
fail_unless (handoff_buffer != NULL);
|
||||||
|
gst_buffer_replace (&handoff_buffer, NULL);
|
||||||
|
|
||||||
|
/* should be clipped and ok */
|
||||||
|
buffer = gst_buffer_new_and_alloc (44100);
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) = 2 * GST_SECOND;
|
||||||
|
GST_BUFFER_DURATION (buffer) = 250 * GST_MSECOND;
|
||||||
|
gst_buffer_set_caps (buffer, caps);
|
||||||
|
GST_DEBUG ("pushing buffer %p", buffer);
|
||||||
|
ret = gst_pad_chain (sinkpad, buffer);
|
||||||
|
fail_unless (ret == GST_FLOW_OK);
|
||||||
|
fail_unless (handoff_buffer == NULL);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
adder_suite (void)
|
adder_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -745,6 +855,7 @@ adder_suite (void)
|
||||||
tcase_add_test (tc_chain, test_live_seeking);
|
tcase_add_test (tc_chain, test_live_seeking);
|
||||||
tcase_add_test (tc_chain, test_add_pad);
|
tcase_add_test (tc_chain, test_add_pad);
|
||||||
tcase_add_test (tc_chain, test_remove_pad);
|
tcase_add_test (tc_chain, test_remove_pad);
|
||||||
|
tcase_add_test (tc_chain, test_clip);
|
||||||
|
|
||||||
/* Use a longer timeout */
|
/* Use a longer timeout */
|
||||||
#ifdef HAVE_VALGRIND
|
#ifdef HAVE_VALGRIND
|
||||||
|
|
Loading…
Reference in a new issue