void test_one_buffer() { GstElement *identity; GstBuffer *buffer; xmlfile = "identity_test_one_buffer"; std_log(LOG_FILENAME_LINE, "Test Started test_one_buffer"); identity = setup_identity (); fail_unless (gst_element_set_state (identity, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); buffer = gst_buffer_new_and_alloc (4); ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1); memcpy (GST_BUFFER_DATA (buffer), "data", 4); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK, "Failed pushing buffer to identity"); /* ... but it should end up being collected on the global buffer list */ fail_unless (g_list_length (buffers) == 1); fail_unless ((GstBuffer *) (g_list_first (buffers)->data) == buffer); ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1); /* cleanup */ cleanup_identity (identity); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* if no framerate is negotiated, we should not be able to push a buffer */ void test_no_framerate() { GstElement *videorate; GstBuffer *inbuffer; GstCaps *caps; videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); inbuffer = gst_buffer_new_and_alloc (4); memset (GST_BUFFER_DATA (inbuffer), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_NO_FRAMERATE_STRING); gst_buffer_set_caps (inbuffer, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); /* take a ref so we can later check refcount */ gst_buffer_ref (inbuffer); /* no framerate is negotiated so pushing should fail */ fail_if (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); gst_buffer_unref (inbuffer); fail_unless_equals_int (g_list_length (buffers), 0); /* cleanup */ cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_one() { GstElement *videorate; GstBuffer *inbuffer; GstCaps *caps; //gst_init(NULL,NULL); videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); inbuffer = gst_buffer_new_and_alloc (4); memset (GST_BUFFER_DATA (inbuffer), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (inbuffer, caps); GST_BUFFER_TIMESTAMP (inbuffer) = 0; gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); fail_unless_equals_int (g_list_length (buffers), 0); /* cleanup */ cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void check_filter_caps (const gchar * name, GstEvent * event, GstCaps * caps, gint size, gint num_buffers, const gchar * prop, va_list varargs) { GstElement *filter; GstBuffer *inbuffer, *outbuffer; gint i; GstSegment segment; filter = setup_filter (name, prop, varargs); fail_unless (gst_element_set_state (filter, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); gst_check_setup_events (mysrcpad, filter, caps, GST_FORMAT_TIME); /* ensure segment (format) properly setup */ gst_segment_init (&segment, GST_FORMAT_TIME); fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment))); if (event) fail_unless (gst_pad_push_event (mysrcpad, event)); for (i = 0; i < num_buffers; ++i) { inbuffer = gst_buffer_new_and_alloc (size); /* makes valgrind's memcheck happier */ gst_buffer_memset (inbuffer, 0, 0, size); GST_BUFFER_TIMESTAMP (inbuffer) = 0; ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); } fail_unless (g_list_length (buffers) == num_buffers); /* clean up buffers */ for (i = 0; i < num_buffers; ++i) { outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL); switch (i) { case 0: fail_unless (gst_buffer_get_size (outbuffer) == size); /* no check on filter operation itself */ break; default: break; } buffers = g_list_remove (buffers, outbuffer); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); gst_buffer_unref (outbuffer); outbuffer = NULL; } cleanup_filter (filter); g_list_free (buffers); buffers = NULL; }
/* from the given two data buffers, create two streamheader buffers and * some caps that match it, and store them in the given pointers * returns one ref to each of the buffers and the caps */ static void gst_multisocketsink_create_streamheader (const gchar * data1, const gchar * data2, GstBuffer ** hbuf1, GstBuffer ** hbuf2, GstCaps ** caps) { GstBuffer *buf; GValue array = { 0 }; GValue value = { 0 }; GstStructure *structure; guint size1 = strlen (data1); guint size2 = strlen (data2); fail_if (hbuf1 == NULL); fail_if (hbuf2 == NULL); fail_if (caps == NULL); /* create caps with streamheader, set the caps, and push the HEADER * buffers */ *hbuf1 = gst_buffer_new_and_alloc (size1); GST_BUFFER_FLAG_SET (*hbuf1, GST_BUFFER_FLAG_HEADER); gst_buffer_fill (*hbuf1, 0, data1, size1); *hbuf2 = gst_buffer_new_and_alloc (size2); GST_BUFFER_FLAG_SET (*hbuf2, GST_BUFFER_FLAG_HEADER); gst_buffer_fill (*hbuf2, 0, data2, size2); g_value_init (&array, GST_TYPE_ARRAY); g_value_init (&value, GST_TYPE_BUFFER); /* we take a copy, set it on the array (which refs it), then unref our copy */ buf = gst_buffer_copy (*hbuf1); gst_value_set_buffer (&value, buf); ASSERT_BUFFER_REFCOUNT (buf, "copied buffer", 2); gst_buffer_unref (buf); gst_value_array_append_value (&array, &value); g_value_unset (&value); g_value_init (&value, GST_TYPE_BUFFER); buf = gst_buffer_copy (*hbuf2); gst_value_set_buffer (&value, buf); ASSERT_BUFFER_REFCOUNT (buf, "copied buffer", 2); gst_buffer_unref (buf); gst_value_array_append_value (&array, &value); g_value_unset (&value); *caps = gst_caps_from_string ("application/x-gst-check"); structure = gst_caps_get_structure (*caps, 0); gst_structure_set_value (structure, "streamheader", &array); g_value_unset (&array); ASSERT_CAPS_REFCOUNT (*caps, "streamheader caps", 1); /* we want to keep them around for the tests */ gst_buffer_ref (*hbuf1); gst_buffer_ref (*hbuf2); GST_DEBUG ("created streamheader caps %p %" GST_PTR_FORMAT, *caps, *caps); }
static void fail_unless_perfect_stream (void) { guint64 timestamp = 0L, duration = 0L; guint64 offset = 0L, offset_end = 0L; GList *l; GstBuffer *buffer; for (l = buffers; l; l = l->next) { buffer = GST_BUFFER (l->data); ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1); GST_DEBUG ("buffer timestamp %" G_GUINT64_FORMAT ", duration %" G_GUINT64_FORMAT, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_DURATION (buffer)); fail_unless_equals_uint64 (timestamp, GST_BUFFER_TIMESTAMP (buffer)); fail_unless_equals_uint64 (offset, GST_BUFFER_OFFSET (buffer)); duration = GST_BUFFER_DURATION (buffer); offset_end = GST_BUFFER_OFFSET_END (buffer); timestamp += duration; offset = offset_end; gst_buffer_unref (buffer); } g_list_free (buffers); buffers = NULL; }
/* this tests that the output is a perfect stream if the input is */ static void test_perfect_stream_instance (int inrate, int outrate, int samples, int numbuffers) { GstElement *audioresample; GstBuffer *inbuffer, *outbuffer; GstCaps *caps; guint64 offset = 0; int i, j; GstMapInfo map; gint16 *p; audioresample = setup_audioresample (2, 0x3, inrate, outrate, GST_AUDIO_NE (S16)); caps = gst_pad_get_current_caps (mysrcpad); fail_unless (gst_caps_is_fixed (caps)); fail_unless (gst_element_set_state (audioresample, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); for (j = 1; j <= numbuffers; ++j) { inbuffer = gst_buffer_new_and_alloc (samples * 4); GST_BUFFER_DURATION (inbuffer) = GST_FRAMES_TO_CLOCK_TIME (samples, inrate); GST_BUFFER_TIMESTAMP (inbuffer) = GST_BUFFER_DURATION (inbuffer) * (j - 1); GST_BUFFER_OFFSET (inbuffer) = offset; offset += samples; GST_BUFFER_OFFSET_END (inbuffer) = offset; gst_buffer_map (inbuffer, &map, GST_MAP_WRITE); p = (gint16 *) map.data; /* create a 16 bit signed ramp */ for (i = 0; i < samples; ++i) { *p = -32767 + i * (65535 / samples); ++p; *p = -32767 + i * (65535 / samples); ++p; } gst_buffer_unmap (inbuffer, &map); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); /* ... but it ends up being collected on the global buffer list */ fail_unless_equals_int (g_list_length (buffers), j); } /* FIXME: we should make audioresample handle eos by flushing out the last * samples, which will give us one more, small, buffer */ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); fail_unless_perfect_stream (); /* cleanup */ gst_caps_unref (caps); cleanup_audioresample (audioresample); }
static void push_and_test (GstCaps * prop_caps, gboolean join, gboolean replace, GstCaps * in_caps, GstCaps * out_caps) { GstElement *capssetter; GstBuffer *buffer; GstCaps *current_out; capssetter = setup_capssetter (); fail_unless (gst_element_set_state (capssetter, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); g_object_set (capssetter, "join", join, NULL); g_object_set (capssetter, "replace", replace, NULL); g_object_set (capssetter, "caps", prop_caps, NULL); gst_caps_unref (prop_caps); buffer = gst_buffer_new_and_alloc (4); ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1); gst_buffer_fill (buffer, 0, "data", 4); gst_check_setup_events (mysrcpad, capssetter, in_caps, GST_FORMAT_TIME); gst_caps_unref (in_caps); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK, "Failed pushing buffer to capssetter"); fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()) == TRUE); /* ... but it should end up being collected on the global buffer list */ fail_unless (g_list_length (buffers) == 1); buffer = g_list_first (buffers)->data; ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1); current_out = gst_pad_get_current_caps (mysinkpad); fail_unless (gst_caps_is_equal (out_caps, current_out)); gst_caps_unref (current_out); gst_caps_unref (out_caps); /* cleanup */ cleanup_capssetter (capssetter); }
static void fail_unless_result_gain (GstElement * element, gdouble expected_gain) { GstBuffer *input_buf, *output_buf; gfloat input_sample, output_sample; gdouble gain, prop_gain; gboolean is_passthrough, expect_passthrough; gint i; fail_unless (g_list_length (buffers) == 0); input_sample = 1.0; input_buf = test_buffer_new (input_sample); /* We keep an extra reference to detect passthrough mode. */ gst_buffer_ref (input_buf); /* Pushing steals a reference. */ fail_unless (gst_pad_push (mysrcpad, input_buf) == GST_FLOW_OK); gst_buffer_unref (input_buf); /* The output buffer ends up on the global buffer list. */ fail_unless (g_list_length (buffers) == 1); output_buf = buffers->data; fail_if (output_buf == NULL); buffers = g_list_remove (buffers, output_buf); ASSERT_BUFFER_REFCOUNT (output_buf, "output_buf", 1); fail_unless_equals_int (GST_BUFFER_SIZE (output_buf), 8 * sizeof (gfloat)); output_sample = *((gfloat *) GST_BUFFER_DATA (output_buf)); fail_if (output_sample == 0.0, "First output sample is zero"); for (i = 1; i < 8; i++) { gfloat output = ((gfloat *) GST_BUFFER_DATA (output_buf))[i]; fail_unless (output_sample == output, "Output samples not uniform"); }; gain = 20. * log10 (output_sample / input_sample); fail_unless (MATCH_GAIN (gain, expected_gain), "Applied gain is %.2f dB, expected %.2f dB", gain, expected_gain); g_object_get (element, "result-gain", &prop_gain, NULL); fail_unless (MATCH_GAIN (prop_gain, expected_gain), "Result gain is %.2f dB, expected %.2f dB", prop_gain, expected_gain); is_passthrough = (output_buf == input_buf); expect_passthrough = MATCH_GAIN (expected_gain, +0.00); fail_unless (is_passthrough == expect_passthrough, expect_passthrough ? "Expected operation in passthrough mode" : "Incorrect passthrough behaviour"); gst_buffer_unref (output_buf); }
static void check_wrong_buffer (guint8 * data, guint length) { GstBuffer *buffer = gst_buffer_new_allocate (NULL, length, 0); GstElement *avisubtitle = setup_avisubtitle (); gst_buffer_fill (buffer, 0, data, length); fail_unless (gst_element_set_state (avisubtitle, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); gst_buffer_ref (buffer); ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 2); /* push the broken buffer */ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_ERROR, "accepted a broken buffer"); /* check if we have unreffed this buffer on failure */ ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 1); gst_buffer_unref (buffer); fail_unless (gst_element_set_state (avisubtitle, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); cleanup_avisubtitle (avisubtitle); }
static void check_correct_buffer (guint8 * src_data, guint src_size, guint8 * dst_data, guint dst_size) { GstBuffer *buffer = gst_buffer_new_allocate (NULL, src_size, 0); GstBuffer *newBuffer; GstElement *avisubtitle = setup_avisubtitle (); GstEvent *event; fail_unless (g_list_length (buffers) == 0, "Buffers list needs to be empty"); gst_buffer_fill (buffer, 0, src_data, src_size); fail_unless (gst_element_set_state (avisubtitle, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); ASSERT_BUFFER_REFCOUNT (buffer, "inbuffer", 1); event = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 2 * GST_SECOND, GST_SEEK_TYPE_SET, 5 * GST_SECOND); fail_unless (gst_element_send_event (avisubtitle, event) == FALSE, "Seeking is not possible when there is no buffer yet"); fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK, "not accepted a correct buffer"); /* we gave away our reference to the buffer, don't assume anything */ buffer = NULL; /* a new buffer is created in the list */ fail_unless (g_list_length (buffers) == 1, "No new buffer in the buffers list"); event = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 2 * GST_SECOND, GST_SEEK_TYPE_SET, 5 * GST_SECOND); fail_unless (gst_element_send_event (avisubtitle, event) == TRUE, "seeking should be working now"); fail_unless (g_list_length (buffers) == 2, "After seeking we need another buffer in the buffers"); newBuffer = GST_BUFFER (buffers->data); buffers = g_list_remove (buffers, newBuffer); fail_unless (g_list_length (buffers) == 1, "Buffers list needs to be empty"); fail_unless (gst_buffer_get_size (newBuffer) == dst_size, "size of the new buffer is wrong ( %d != %d)", gst_buffer_get_size (newBuffer), dst_size); fail_unless (gst_buffer_memcmp (newBuffer, 0, dst_data, dst_size) == 0, "data of the buffer is not correct"); gst_buffer_unref (newBuffer); /* free the buffer from seeking */ gst_buffer_unref (GST_BUFFER (buffers->data)); buffers = g_list_remove (buffers, buffers->data); fail_unless (gst_element_set_state (avisubtitle, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); cleanup_avisubtitle (avisubtitle); }
void test_non_ok_flow() { GstElement *videorate; GstClockTime ts; GstBuffer *buf; GstCaps *caps; videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); buf = gst_buffer_new_and_alloc (4); memset (GST_BUFFER_DATA (buf), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (buf, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (buf, "inbuffer", 1); /* push a few 'normal' buffers */ for (ts = 0; ts < 100 * GST_SECOND; ts += GST_SECOND / 33) { GstBuffer *inbuf; inbuf = gst_buffer_copy (buf); GST_BUFFER_TIMESTAMP (inbuf) = ts; fail_unless_equals_int (gst_pad_push (mysrcpad, inbuf), GST_FLOW_OK); } /* we should have buffers according to the output framerate of 25/1 */ fail_unless_equals_int (g_list_length (buffers), 100 * 25); /* now deactivate pad so we get a WRONG_STATE flow return */ gst_pad_set_active (mysinkpad, FALSE); /* push buffer on deactivated pad */ fail_unless (gst_buffer_is_metadata_writable (buf)); GST_BUFFER_TIMESTAMP (buf) = ts; /* pushing gives away our reference */ fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_WRONG_STATE); /* cleanup */ cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static GstBuffer * create_test_buffer (void) { GstBuffer *buf = gst_buffer_new_and_alloc (sizeof (test_input)); GstCaps *caps; gst_buffer_fill (buf, 0, test_input, sizeof (test_input)); caps = gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, "format", G_TYPE_STRING, GST_AUDIO_NE (F32), "layout", G_TYPE_STRING, "interleaved", NULL); gst_pad_set_caps (mysrcpad, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); return buf; }
static void check_buffers (guint expected) { GstBuffer *outbuffer; guint i, num_buffers; /* check buffers are the type we expect */ num_buffers = g_list_length (buffers); fail_unless (num_buffers >= expected); for (i = 0; i < num_buffers; ++i) { outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL); fail_if (gst_buffer_get_size (outbuffer) == 0); buffers = g_list_remove (buffers, outbuffer); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); gst_buffer_unref (outbuffer); outbuffer = NULL; } }
static GstBuffer * test_buffer_new (gfloat value) { GstBuffer *buf; GstCaps *caps; gfloat *data; gint i; buf = gst_buffer_new_and_alloc (8 * sizeof (gfloat)); data = (gfloat *) GST_BUFFER_DATA (buf); for (i = 0; i < 8; i++) data[i] = value; caps = gst_caps_from_string ("audio/x-raw-float, " "rate = 8000, channels = 1, endianness = BYTE_ORDER, width = 32"); gst_buffer_set_caps (buf, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); return buf; }
static void helper (gboolean flush) { GstElement *filter; GstBus *bus; GstPad *mysrcpad; GstPad *mysinkpad; /* init */ filter = gst_check_setup_element ("omx_dummy"); mysrcpad = gst_check_setup_src_pad (filter, &srctemplate, NULL); mysinkpad = gst_check_setup_sink_pad (filter, &sinktemplate, NULL); gst_pad_set_active (mysrcpad, TRUE); gst_pad_set_active (mysinkpad, TRUE); /* need to know when we are eos */ gst_pad_set_event_function (mysinkpad, test_sink_event); /* and notify the test run */ eos_mutex = g_mutex_new (); eos_cond = g_cond_new (); eos_arrived = FALSE; g_object_set (G_OBJECT (filter), "library-name", "libomxil-foo.so", NULL); /* start */ fail_unless_equals_int (gst_element_set_state (filter, GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS); bus = gst_bus_new (); gst_element_set_bus (filter, bus); /* send buffers in order*/ { guint i; for (i = 0; i < BUFFER_COUNT; i++) { GstBuffer *inbuffer; inbuffer = gst_buffer_new_and_alloc (BUFFER_SIZE); GST_BUFFER_DATA(inbuffer)[0] = i; ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); if (flush && i % FLUSH_AT == 0) { gst_pad_push_event (mysrcpad, gst_event_new_flush_start ()); gst_pad_push_event (mysrcpad, gst_event_new_flush_stop ()); i += FLUSH_AT; } } } { GstMessage *message; fail_if ((message = gst_bus_pop (bus)) != NULL); /* make sure there's no error on the bus */ message = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0); fail_if (message); } gst_pad_push_event (mysrcpad, gst_event_new_eos ()); /* need to wait a bit to make sure src pad task digested all and sent eos */ g_mutex_lock (eos_mutex); while (!eos_arrived) g_cond_wait (eos_cond, eos_mutex); g_mutex_unlock (eos_mutex); /* check the order of the buffers*/ if (!flush) { GList *cur; guint i; for (cur = buffers, i = 0; cur; cur = g_list_next (cur), i++) { GstBuffer *buffer; buffer = cur->data; fail_unless (GST_BUFFER_DATA(buffer)[0] == i); } fail_unless (i == BUFFER_COUNT); } /* cleanup */ gst_bus_set_flushing (bus, TRUE); gst_element_set_bus (filter, NULL); gst_object_unref (GST_OBJECT (bus)); gst_check_drop_buffers (); /* deinit */ gst_element_set_state (filter, GST_STATE_NULL); gst_pad_set_active (mysrcpad, FALSE); gst_pad_set_active (mysinkpad, FALSE); gst_check_teardown_src_pad (filter); gst_check_teardown_sink_pad (filter); gst_check_teardown_element (filter); g_mutex_free (eos_mutex); g_cond_free (eos_cond); }
void test_more() { GstElement *videorate; GstBuffer *first, *second, *third, *outbuffer; GList *l; GstCaps *caps; GRand *rand; videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); assert_videorate_stats (videorate, "creation", 0, 0, 0, 0); rand = g_rand_new (); /* first buffer */ first = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (first) = 0; /* it shouldn't matter what the offsets are, videorate produces perfect streams */ GST_BUFFER_OFFSET (first) = g_rand_int (rand); GST_BUFFER_OFFSET_END (first) = g_rand_int (rand); memset (GST_BUFFER_DATA (first), 1, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (first, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (first, "first", 1); gst_buffer_ref (first); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (first, "first", 2); fail_unless_equals_int (g_list_length (buffers), 0); assert_videorate_stats (videorate, "first buffer", 1, 0, 0, 0); /* second buffer; inbetween second and third output frame's timestamp */ second = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (second) = GST_SECOND * 3 / 50; GST_BUFFER_OFFSET (first) = g_rand_int (rand); GST_BUFFER_OFFSET_END (first) = g_rand_int (rand); memset (GST_BUFFER_DATA (second), 2, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (second, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (second, "second", 1); gst_buffer_ref (second); /* pushing gives away one of my references ... */ fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (second, "second", 2); /* ... and the first one is pushed out, with timestamp 0 */ fail_unless_equals_int (g_list_length (buffers), 1); assert_videorate_stats (videorate, "second buffer", 2, 1, 0, 0); ASSERT_BUFFER_REFCOUNT (first, "first", 2); outbuffer = buffers->data; fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), 0); /* third buffer */ third = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (third) = GST_SECOND * 12 / 50; GST_BUFFER_OFFSET (first) = g_rand_int (rand); GST_BUFFER_OFFSET_END (first) = g_rand_int (rand); memset (GST_BUFFER_DATA (third), 3, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (third, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (third, "third", 1); gst_buffer_ref (third); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (third, "third", 2); /* submitting the third buffer has triggered flushing of three more frames */ assert_videorate_stats (videorate, "third buffer", 3, 4, 0, 2); /* check timestamp and source correctness */ l = buffers; fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), 0); fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 1); fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 0); fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 1); l = g_list_next (l); fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), GST_SECOND / 25); fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2); fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 1); fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 2); l = g_list_next (l); fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), GST_SECOND * 2 / 25); fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2); fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 2); fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 3); l = g_list_next (l); fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), GST_SECOND * 3 / 25); fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2); fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 3); fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 4); fail_unless_equals_int (g_list_length (buffers), 4); /* one held by us, three held by each output frame taken from the second */ ASSERT_BUFFER_REFCOUNT (second, "second", 4); /* now send EOS */ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ())); /* submitting eos should flush out two more frames for tick 8 and 10 */ /* FIXME: right now it only flushes out one, so out is 5 instead of 6 ! */ assert_videorate_stats (videorate, "eos", 3, 5, 0, 2); fail_unless_equals_int (g_list_length (buffers), 5); /* cleanup */ g_rand_free (rand); gst_buffer_unref (first); gst_buffer_unref (second); gst_buffer_unref (third); cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void test_video_profile (const gchar * profile, gint profile_id, const gchar * input_format) { GstElement *x264enc; GstBuffer *inbuffer, *outbuffer; int i, num_buffers; x264enc = setup_x264enc (profile, "avc", input_format); fail_unless (gst_element_set_state (x264enc, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); /* corresponds to I420 buffer for the size mentioned in the caps */ if (!strcmp (input_format, "I420")) inbuffer = gst_buffer_new_and_alloc (384 * 288 * 3 / 2); else if (!strcmp (input_format, "Y42B")) inbuffer = gst_buffer_new_and_alloc (384 * 288 * 2); else if (!strcmp (input_format, "Y444")) inbuffer = gst_buffer_new_and_alloc (384 * 288 * 3); else g_assert_not_reached (); /* makes valgrind's memcheck happier */ gst_buffer_memset (inbuffer, 0, 0, -1); GST_BUFFER_TIMESTAMP (inbuffer) = 0; ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); /* send eos to have all flushed if needed */ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()) == TRUE); num_buffers = g_list_length (buffers); fail_unless (num_buffers == 1); /* check output caps */ { GstCaps *outcaps; outcaps = gst_pad_get_current_caps (mysinkpad); check_caps (outcaps, profile, profile_id); gst_caps_unref (outcaps); } /* clean up buffers */ for (i = 0; i < num_buffers; ++i) { outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL); switch (i) { case 0: { gint nsize, npos, j, type, next_type; GstMapInfo map; const guint8 *data; gsize size; gst_buffer_map (outbuffer, &map, GST_MAP_READ); data = map.data; size = map.size; npos = 0; j = 0; /* need SPS first */ next_type = 7; /* loop through NALs */ while (npos < size) { fail_unless (size - npos >= 4); nsize = GST_READ_UINT32_BE (data + npos); fail_unless (nsize > 0); fail_unless (npos + 4 + nsize <= size); type = data[npos + 4] & 0x1F; /* check the first NALs, disregard AU (9), SEI (6) */ if (type != 9 && type != 6) { fail_unless (type == next_type); switch (type) { case 7: /* SPS */ next_type = 8; break; case 8: /* PPS */ next_type = 5; break; default: break; } j++; } npos += nsize + 4; } gst_buffer_unmap (outbuffer, &map); /* should have reached the exact end */ fail_unless (npos == size); break; } default: break; } buffers = g_list_remove (buffers, outbuffer); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); gst_buffer_unref (outbuffer); outbuffer = NULL; } cleanup_x264enc (x264enc); g_list_free (buffers); buffers = NULL; }
/* 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); }
/* frames at 1, 0, 2 -> second one should be ignored */ void test_wrong_order_from_zero() { GstElement *videorate; GstBuffer *first, *second, *third, *outbuffer; GstCaps *caps; videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); assert_videorate_stats (videorate, "start", 0, 0, 0, 0); /* first buffer */ first = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (first) = GST_SECOND; memset (GST_BUFFER_DATA (first), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (first, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (first, "first", 1); gst_buffer_ref (first); GST_DEBUG ("pushing first buffer"); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (first, "first", 2); fail_unless_equals_int (g_list_length (buffers), 0); assert_videorate_stats (videorate, "first", 1, 0, 0, 0); /* second buffer */ second = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (second) = 0; memset (GST_BUFFER_DATA (second), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (second, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (second, "second", 1); gst_buffer_ref (second); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK); /* ... and it is now dropped because it is too old */ ASSERT_BUFFER_REFCOUNT (second, "second", 1); fail_unless_equals_int (g_list_length (buffers), 0); /* ... and the first one is still there */ assert_videorate_stats (videorate, "second", 2, 0, 1, 0); ASSERT_BUFFER_REFCOUNT (first, "first", 2); /* third buffer */ third = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND; memset (GST_BUFFER_DATA (third), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (third, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (third, "third", 1); gst_buffer_ref (third); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (third, "third", 2); /* and now the first one should be pushed once and dupped 24 + 13 times, to * reach the half point between 1 s (first) and 2 s (third) */ fail_unless_equals_int (g_list_length (buffers), 38); ASSERT_BUFFER_REFCOUNT (first, "first", 39); ASSERT_BUFFER_REFCOUNT (second, "second", 1); ASSERT_BUFFER_REFCOUNT (third, "third", 2); assert_videorate_stats (videorate, "third", 3, 38, 1, 37); /* verify last buffer */ outbuffer = g_list_last (buffers)->data; fail_unless (GST_IS_BUFFER (outbuffer)); fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), GST_SECOND * 37 / 25); /* cleanup */ gst_buffer_unref (first); gst_buffer_unref (second); gst_buffer_unref (third); cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* send frames with 0, 1, 2, 0 seconds */ void test_wrong_order() { GstElement *videorate; GstBuffer *first, *second, *third, *fourth, *outbuffer; GstCaps *caps; videorate = setup_videorate (); fail_unless (gst_element_set_state (videorate, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); assert_videorate_stats (videorate, "start", 0, 0, 0, 0); /* first buffer */ first = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (first) = 0; memset (GST_BUFFER_DATA (first), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (first, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (first, "first", 1); gst_buffer_ref (first); GST_DEBUG ("pushing first buffer"); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (first, "first", 2); fail_unless_equals_int (g_list_length (buffers), 0); assert_videorate_stats (videorate, "first", 1, 0, 0, 0); /* second buffer */ second = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (second) = GST_SECOND; memset (GST_BUFFER_DATA (second), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (second, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (second, "second", 1); gst_buffer_ref (second); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (second, "second", 2); /* and it created 13 output buffers as copies of the first frame */ fail_unless_equals_int (g_list_length (buffers), 13); assert_videorate_stats (videorate, "second", 2, 13, 0, 12); ASSERT_BUFFER_REFCOUNT (first, "first", 14); /* third buffer */ third = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND; memset (GST_BUFFER_DATA (third), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (third, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (third, "third", 1); gst_buffer_ref (third); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK); /* ... and it is now stuck inside videorate */ ASSERT_BUFFER_REFCOUNT (third, "third", 2); /* submitting a frame with 2 seconds triggers output of 25 more frames */ fail_unless_equals_int (g_list_length (buffers), 38); ASSERT_BUFFER_REFCOUNT (first, "first", 14); ASSERT_BUFFER_REFCOUNT (second, "second", 26); /* three frames submitted; two of them output as is, and 36 duplicated */ assert_videorate_stats (videorate, "third", 3, 38, 0, 36); /* fourth buffer */ fourth = gst_buffer_new_and_alloc (4); GST_BUFFER_TIMESTAMP (fourth) = 0; memset (GST_BUFFER_DATA (fourth), 0, 4); caps = gst_caps_from_string (VIDEO_CAPS_STRING); gst_buffer_set_caps (fourth, caps); gst_caps_unref (caps); ASSERT_BUFFER_REFCOUNT (fourth, "fourth", 1); gst_buffer_ref (fourth); /* pushing gives away my reference ... */ fail_unless (gst_pad_push (mysrcpad, fourth) == GST_FLOW_OK); /* ... and it is dropped */ ASSERT_BUFFER_REFCOUNT (fourth, "fourth", 1); fail_unless_equals_int (g_list_length (buffers), 38); ASSERT_BUFFER_REFCOUNT (first, "first", 14); ASSERT_BUFFER_REFCOUNT (second, "second", 26); assert_videorate_stats (videorate, "fourth", 4, 38, 1, 36); /* verify last buffer */ outbuffer = g_list_last (buffers)->data; fail_unless (GST_IS_BUFFER (outbuffer)); fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), GST_SECOND * 37 / 25); /* cleanup */ gst_buffer_unref (first); gst_buffer_unref (second); gst_buffer_unref (third); gst_buffer_unref (fourth); cleanup_videorate (videorate); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }