Fix implementation of sync-method 'next-keyframe'

Original commit message from CVS:

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'
This commit is contained in:
Michael Smith 2006-09-07 19:00:33 +00:00 committed by Thomas Vander Stichele
parent a66ee4d6da
commit 5301cc3132
3 changed files with 83 additions and 13 deletions

View file

@ -1,3 +1,14 @@
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>

View file

@ -1090,6 +1090,7 @@ is_sync_frame (GstMultiFdSink * sink, GstBuffer * buffer)
} else if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_IN_CAPS)) {
return TRUE;
}
return FALSE;
}
@ -1105,7 +1106,6 @@ gst_multi_fd_sink_client_queue_buffer (GstMultiFdSink * sink,
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 */
@ -1448,27 +1448,26 @@ gst_multi_fd_sink_new_client (GstMultiFdSink * sink, GstTCPClient * client)
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:

View file

@ -794,6 +794,65 @@ GST_START_TEST (test_burst_client_bytes_with_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
@ -815,6 +874,7 @@ multifdsink_suite (void)
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;
}