void test_no_clients() { GstElement *sink; GstBuffer *buffer; GstCaps *caps; std_log(LOG_FILENAME_LINE, "Test Started test_no_clients"); sink = setup_multifdsink (); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); buffer = gst_buffer_new_and_alloc (4); gst_buffer_set_caps (buffer, caps); gst_caps_unref (caps); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); GST_DEBUG ("cleaning up multifdsink"); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); //commented bz..select() blocks indefinitly cleanup_multifdsink (sink); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void do_one_buffer_test_apply (gboolean clean_point) { GstBuffer *buffer_in, *buffer_out; g_object_set (element, "ntp-offset", NTP_OFFSET, "cseq", 0x12345678, "set-e-bit", FALSE, NULL); ASSERT_SET_STATE (element, GST_STATE_PLAYING, GST_STATE_CHANGE_SUCCESS); buffer_in = create_rtp_buffer (TIMESTAMP, clean_point); buffer_out = create_extension_buffer (buffer_in, clean_point, FALSE, FALSE, NTP_OFFSET, CSEQ); /* push initial events */ gst_check_setup_events (mysrcpad, element, NULL, GST_FORMAT_TIME); /* Push buffer */ fail_unless_equals_int (gst_pad_push (mysrcpad, buffer_in), GST_FLOW_OK); check_buffer_equal ((GstBuffer *) buffers->data, buffer_out); gst_buffer_unref (buffer_out); ASSERT_SET_STATE (element, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); }
/* Check that we can get data when multifdsink is configured in next-keyframe * mode */ void test_client_next_keyframe() { GstElement *sink; GstBuffer *buffer; GstCaps *caps; int pfd1[2]; gchar data[16]; gint i; std_log(LOG_FILENAME_LINE, "Test Started test_client_next_keyframe"); sink = setup_multifdsink (); g_object_set (sink, "sync-method", 1, NULL); /* 1 = next-keyframe */ fail_if (pipe (pfd1) == -1); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps); /* now add our client */ g_signal_emit_by_name (sink, "add", pfd1[1]); /* push buffers in: keyframe, then non-keyframe */ for (i = 0; i < 2; i++) { gchar *data; buffer = gst_buffer_new_and_alloc (16); gst_buffer_set_caps (buffer, caps); /* copy some id */ data = (gchar *) GST_BUFFER_DATA (buffer); g_snprintf (data, 16, "deadbee%08x", i); if (i > 0) GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); } /* now we should be able to read some data */ GST_DEBUG ("Reading from client 1"); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000000", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000001", 16) == 0); GST_DEBUG ("cleaning up multifdsink"); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); cleanup_multifdsink (sink); ASSERT_CAPS_REFCOUNT (caps, "caps", 1); gst_caps_unref (caps); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void do_two_buffers_test_apply (gboolean end_contiguous) { GstBuffer *buffer_in, *buffer_out; GList *node; g_object_set (element, "ntp-offset", NTP_OFFSET, "cseq", 0x12345678, "set-e-bit", TRUE, NULL); ASSERT_SET_STATE (element, GST_STATE_PLAYING, GST_STATE_CHANGE_SUCCESS); buffer_in = create_rtp_buffer (TIMESTAMP, FALSE); buffer_out = create_extension_buffer (buffer_in, FALSE, end_contiguous, FALSE, NTP_OFFSET, CSEQ); /* push initial events */ gst_check_setup_events (mysrcpad, element, NULL, GST_FORMAT_TIME); /* Push buffer */ fail_unless_equals_int (gst_pad_push (mysrcpad, buffer_in), GST_FLOW_OK); /* The buffer hasn't been pushed it as the element is waiting for the next * buffer. */ fail_unless_equals_int (g_list_length (buffers), 0); /* push an ntp-offset event to trigger a discontinuty */ fail_unless (gst_pad_push_event (mysrcpad, create_ntp_offset_event (NTP_OFFSET, end_contiguous))); /* A second buffer is pushed */ buffer_in = create_rtp_buffer (TIMESTAMP + 1, FALSE); fail_unless_equals_int (gst_pad_push (mysrcpad, buffer_in), GST_FLOW_OK); /* The first buffer has now been pushed out */ fail_unless_equals_int (g_list_length (buffers), 1); node = g_list_last (buffers); check_buffer_equal ((GstBuffer *) node->data, buffer_out); gst_buffer_unref (buffer_out); /* Push EOS */ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ())); /* The second buffer has been pushed out */ fail_unless_equals_int (g_list_length (buffers), 2); /* Last buffer always has the 'E' flag */ buffer_out = create_extension_buffer (buffer_in, FALSE, TRUE, end_contiguous, NTP_OFFSET, CSEQ); node = g_list_last (buffers); check_buffer_equal ((GstBuffer *) node->data, buffer_out); gst_buffer_unref (buffer_out); ASSERT_SET_STATE (element, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); }
static gboolean on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: g_main_loop_quit (data->loop); break; case GST_MESSAGE_ERROR: ASSERT_SET_STATE (data->sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); ASSERT_SET_STATE (data->source, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); g_main_loop_quit (data->loop); break; default: break; } return TRUE; }
void test_add_client() { GstElement *sink; GstBuffer *buffer; GstCaps *caps; int pfd[2]; gchar data[4]; std_log(LOG_FILENAME_LINE, "Test Started test_add_client"); sink = setup_multifdsink (); fail_if (pipe (pfd) == -1); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); /* add the client */ g_signal_emit_by_name (sink, "add", pfd[1]); caps = gst_caps_from_string ("application/x-gst-check"); GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps); buffer = gst_buffer_new_and_alloc (4); gst_buffer_set_caps (buffer, caps); ASSERT_CAPS_REFCOUNT (caps, "caps", 2); memcpy (GST_BUFFER_DATA (buffer), "dead", 4); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); GST_DEBUG ("reading"); fail_if (read (pfd[0], data, 4) < 4); fail_unless (strncmp (data, "dead", 4) == 0); wait_bytes_served (sink, 4); GST_DEBUG ("cleaning up multifdsink"); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); cleanup_multifdsink (sink); ASSERT_CAPS_REFCOUNT (caps, "caps", 1); gst_caps_unref (caps); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* keep 100 bytes and burst 80 bytes to clients */ void test_burst_client_bytes_with_keyframe() { GstElement *sink; GstBuffer *buffer; GstCaps *caps; int pfd1[2]; int pfd2[2]; int pfd3[2]; gchar data[16]; gint i; guint buffers_queued; std_log(LOG_FILENAME_LINE, "Test Started test_burst_client_bytes_with_keyframe"); sink = setup_multifdsink (); /* make sure we keep at least 100 bytes at all times */ g_object_set (sink, "bytes-min", 100, NULL); g_object_set (sink, "sync-method", 5, NULL); /* 3 = burst_with_keyframe */ g_object_set (sink, "burst-unit", 3, NULL); /* 3 = bytes */ g_object_set (sink, "burst-value", (guint64) 80, NULL); fail_if (pipe (pfd1) == -1); fail_if (pipe (pfd2) == -1); fail_if (pipe (pfd3) == -1); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps); /* push buffers in, 9 * 16 bytes = 144 bytes */ for (i = 0; i < 9; i++) { gchar *data; buffer = gst_buffer_new_and_alloc (16); gst_buffer_set_caps (buffer, caps); /* mark most buffers as delta */ if (i != 0 && i != 4 && i != 8) GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); /* copy some id */ data = (gchar *) GST_BUFFER_DATA (buffer); g_snprintf (data, 16, "deadbee%08x", i); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); } /* check that at least 7 buffers (112 bytes) are in the queue */ g_object_get (sink, "buffers-queued", &buffers_queued, NULL); fail_if (buffers_queued != 7); /* now add the clients */ g_signal_emit_by_name (sink, "add", pfd1[1]); g_signal_emit_by_name (sink, "add_full", pfd2[1], 5, 3, (guint64) 50, 3, (guint64) 90); g_signal_emit_by_name (sink, "add_full", pfd3[1], 5, 3, (guint64) 50, 3, (guint64) 50); /* push last buffer to make client fds ready for reading */ for (i = 9; i < 10; i++) { gchar *data; buffer = gst_buffer_new_and_alloc (16); gst_buffer_set_caps (buffer, caps); GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); /* copy some id */ data = (gchar *) GST_BUFFER_DATA (buffer); g_snprintf (data, 16, "deadbee%08x", i); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); } /* now we should only read the last 6 buffers (min 5 * 16 = 80 bytes), * keyframe at buffer 4 */ GST_DEBUG ("Reading from client 1"); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000004", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000005", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000006", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000007", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000008", 16) == 0); fail_if (read (pfd1[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000009", 16) == 0); /* second client only bursts 50 bytes = 4 buffers, there is * no keyframe above min and below max, so send min */ GST_DEBUG ("Reading from client 2"); fail_if (read (pfd2[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000006", 16) == 0); fail_if (read (pfd2[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000007", 16) == 0); fail_if (read (pfd2[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000008", 16) == 0); fail_if (read (pfd2[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000009", 16) == 0); /* third client only bursts 50 bytes = 4 buffers, we can't send * more than 50 bytes so we only get 3 buffers (48 bytes). */ GST_DEBUG ("Reading from client 3"); fail_if (read (pfd3[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000007", 16) == 0); fail_if (read (pfd3[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000008", 16) == 0); fail_if (read (pfd3[0], data, 16) < 16); fail_unless (strncmp (data, "deadbee00000009", 16) == 0); GST_DEBUG ("cleaning up multifdsink"); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); cleanup_multifdsink (sink); ASSERT_CAPS_REFCOUNT (caps, "caps", 1); gst_caps_unref (caps); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* this tests changing of streamheaders * - set streamheader caps on the pad * - pushes the IN_CAPS buffers * - pushes a buffer * - add a first client * - verifies that this first client receives the first streamheader caps, * plus a new buffer * - change streamheader caps * - verify that the first client receives the new streamheader buffers as well */ void test_change_streamheader() { GstElement *sink; GstBuffer *hbuf1, *hbuf2, *buf; GstCaps *caps; int pfd1[2], pfd2[2]; std_log(LOG_FILENAME_LINE, "Test Started test_change_streamheader"); sink = setup_multifdsink (); fail_if (pipe (pfd1) == -1); fail_if (pipe (pfd2) == -1); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); /* create caps with streamheader, set the caps, and push the IN_CAPS * buffers */ gst_multifdsink_create_streamheader ("first", "header", &hbuf1, &hbuf2, &caps); fail_unless (gst_pad_set_caps (mysrcpad, caps)); /* one is ours, two on the buffers, and one now on the pad */ ASSERT_CAPS_REFCOUNT (caps, "caps", 4); /* one to hold for the test and one to give away */ ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2); ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2); fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK); fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK); /* add the first client */ g_signal_emit_by_name (sink, "add", pfd1[1]); /* verify this hasn't triggered a write yet */ /* FIXME: possibly racy, since if it would write, we may not get it * immediately ? */ //fail_if_can_read ("first client, no buffer", pfd1[0]); /* now push a buffer and read */ buf = gst_buffer_new_and_alloc (4); memcpy (GST_BUFFER_DATA (buf), "f00d", 4); gst_pad_push (mysrcpad, buf); fail_unless_read ("change: first client", pfd1[0], 5, "first"); fail_unless_read ("change: first client", pfd1[0], 6, "header"); fail_unless_read ("change: first client", pfd1[0], 4, "f00d"); //wait_bytes_served (sink, 16); /* now add the second client */ g_signal_emit_by_name (sink, "add", pfd2[1]); //fail_if_can_read ("second client, no buffer", pfd2[0]); /* change the streamheader */ /* before we change, multifdsink still has a list of the old streamheaders */ ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2); ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2); gst_buffer_unref (hbuf1); gst_buffer_unref (hbuf2); /* drop our ref to the previous caps */ gst_caps_unref (caps); gst_multifdsink_create_streamheader ("second", "header", &hbuf1, &hbuf2, &caps); fail_unless (gst_pad_set_caps (mysrcpad, caps)); /* one to hold for the test and one to give away */ ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2); ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2); fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK); fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK); /* verify neither client has new data available to read */ //fail_if_can_read ("first client, changed streamheader", pfd1[0]); //fail_if_can_read ("second client, changed streamheader", pfd2[0]); /* now push another buffer, which will trigger streamheader for second * client, but should also send new streamheaders to first client */ buf = gst_buffer_new_and_alloc (8); memcpy (GST_BUFFER_DATA (buf), "deadbabe", 8); gst_pad_push (mysrcpad, buf); fail_unless_read ("first client", pfd1[0], 6, "second"); fail_unless_read ("first client", pfd1[0], 6, "header"); fail_unless_read ("first client", pfd1[0], 8, "deadbabe"); /* new streamheader data */ fail_unless_read ("second client", pfd2[0], 6, "second"); fail_unless_read ("second client", pfd2[0], 6, "header"); /* we missed the f00d buffer */ fail_unless_read ("second client", pfd2[0], 8, "deadbabe"); //wait_bytes_served (sink, 36); GST_DEBUG ("cleaning up multifdsink"); g_signal_emit_by_name (sink, "remove", pfd1[1]); g_signal_emit_by_name (sink, "remove", pfd2[1]); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); /* setting to NULL should have cleared the streamheader */ ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 1); ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 1); gst_buffer_unref (hbuf1); gst_buffer_unref (hbuf2); cleanup_multifdsink (sink); ASSERT_CAPS_REFCOUNT (caps, "caps", 1); gst_caps_unref (caps); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* this test: * - adds a first client * - sets streamheader caps on the pad * - pushes the IN_CAPS buffers * - pushes a buffer * - verifies that the client received all the data correctly, and did not * get multiple copies of the streamheader * - adds a second client * - verifies that this second client receives the streamheader caps too, plus * - the new buffer */ void test_streamheader() { GstElement *sink; GstBuffer *hbuf1, *hbuf2, *buf; GstCaps *caps; int pfd1[2], pfd2[2]; std_log(LOG_FILENAME_LINE, "Test Started test_streamheader"); sink = setup_multifdsink (); fail_if (pipe (pfd1) == -1); fail_if (pipe (pfd2) == -1); ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); /* add the first client */ g_signal_emit_by_name (sink, "add", pfd1[1]); /* create caps with streamheader, set the caps, and push the IN_CAPS * buffers */ gst_multifdsink_create_streamheader ("babe", "deadbeef", &hbuf1, &hbuf2, &caps); fail_unless (gst_pad_set_caps (mysrcpad, caps)); /* one is ours, two on the buffers, and one now on the pad */ ASSERT_CAPS_REFCOUNT (caps, "caps", 4); fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK); fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK); //FIXME: //fail_if_can_read ("first client", pfd1[0]); /* push a non-IN_CAPS buffer, this should trigger the client receiving the * first three buffers */ buf = gst_buffer_new_and_alloc (4); memcpy (GST_BUFFER_DATA (buf), "f00d", 4); gst_pad_push (mysrcpad, buf); fail_unless_read ("first client", pfd1[0], 4, "babe"); fail_unless_read ("first client", pfd1[0], 8, "deadbeef"); fail_unless_read ("first client", pfd1[0], 4, "f00d"); wait_bytes_served (sink, 16); /* now add the second client */ g_signal_emit_by_name (sink, "add", pfd2[1]); //FIXME: //fail_if_can_read ("second client", pfd2[0]); /* now push another buffer, which will trigger streamheader for second * client */ buf = gst_buffer_new_and_alloc (4); memcpy (GST_BUFFER_DATA (buf), "deaf", 4); gst_pad_push (mysrcpad, buf); fail_unless_read ("first client", pfd1[0], 4, "deaf"); fail_unless_read ("second client", pfd2[0], 4, "babe"); fail_unless_read ("second client", pfd2[0], 8, "deadbeef"); /* we missed the f00d buffer */ fail_unless_read ("second client", pfd2[0], 4, "deaf"); wait_bytes_served (sink, 36); GST_DEBUG ("cleaning up multifdsink"); g_signal_emit_by_name (sink, "remove", pfd1[1]); g_signal_emit_by_name (sink, "remove", pfd2[1]); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); cleanup_multifdsink (sink); ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 1); ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 1); gst_buffer_unref (hbuf1); gst_buffer_unref (hbuf2); ASSERT_CAPS_REFCOUNT (caps, "caps", 1); gst_caps_unref (caps); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }