2006-09-07 Thomas Vander Stichele <thomas at apestaart dot org>
+ patch by: Michael Smith <msmith at fluendo dot com>
+
+ * gst/tcp/gstmultifdsink.c: (is_sync_frame),
+ (gst_multi_fd_sink_client_queue_buffer),
+ (gst_multi_fd_sink_new_client):
+ * tests/check/elements/multifdsink.c: (GST_START_TEST),
+ (multifdsink_suite):
+ Fix implementation of sync-method 'next-keyframe'
+
+2006-09-07 Thomas Vander Stichele <thomas at apestaart dot org>
+
patch by: Wim Taymans <wim at fluendo dot com>
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_start):
} else if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_IN_CAPS)) {
return TRUE;
}
+
return FALSE;
}
gboolean send_streamheader = FALSE;
GstStructure *s;
-
/* before we queue the buffer, we check if we need to queue streamheader
* buffers (because it's a new client, or because they changed) */
caps = gst_buffer_get_caps (buffer); /* cleaned up after streamheader */
break;
case GST_SYNC_METHOD_NEXT_KEYFRAME:
{
- GstBuffer *buf;
-
- /* if the buffer at the head of the queue is a sync point we can proceed,
- * else we need to skip the buffer and wait for a new one */
+ /* if one of the new buffers (between client->bufpos and 0) in the queue
+ * is a sync point, we can proceed, otherwise we need to keep waiting */
GST_LOG_OBJECT (sink,
"[fd %5d] new client, bufpos %d, waiting for keyframe", client->fd.fd,
client->bufpos);
- /* get the buffer for the client */
- buf = g_array_index (sink->bufqueue, GstBuffer *, 0);
- if (is_sync_frame (sink, buf)) {
- GST_LOG_OBJECT (sink, "[fd %5d] new client, found sync", client->fd.fd);
- result = 0;
+ result = find_prev_syncframe (sink, client->bufpos);
+ if (result != -1) {
+ GST_DEBUG_OBJECT (sink,
+ "[fd %5d] SYNC_METHOD_NEXT_KEYFRAME: result %d",
+ client->fd.fd, result);
break;
}
- /* client is not on a syncbuffer, need to skip this buffer and
+
+ /* client is not on a syncbuffer, need to skip these buffers and
* wait some more */
- GST_LOG_OBJECT (sink, "[fd %5d] new client, skipping buffer",
+ GST_LOG_OBJECT (sink,
+ "[fd %5d] new client, skipping buffer(s), no syncpoint found",
client->fd.fd);
client->bufpos = -1;
- result = -1;
break;
}
case GST_SYNC_METHOD_LATEST_KEYFRAME:
GST_END_TEST;
+/* Check that we can get data when multifdsink is configured in next-keyframe
+ * mode */
+GST_START_TEST (test_client_next_keyframe)
+{
+ GstElement *sink;
+ GstBuffer *buffer;
+ GstCaps *caps;
+ int pfd1[2];
+ gchar data[16];
+ guint64 bytes_served;
+ gint i;
+ guint buffers_queued;
+
+ 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);
+}
+
+GST_END_TEST;
+
/* FIXME: add test simulating chained oggs where:
* sync-method is burst-on-connect
* (when multifdsink actually does burst-on-connect based on byte size, not
tcase_add_test (tc_chain, test_burst_client_bytes);
tcase_add_test (tc_chain, test_burst_client_bytes_keyframe);
tcase_add_test (tc_chain, test_burst_client_bytes_with_keyframe);
+ tcase_add_test (tc_chain, test_client_next_keyframe);
return s;
}