From 5301cc3132c30e0923022b759d7ddc258c09e0a7 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 7 Sep 2006 19:00:33 +0000 Subject: [PATCH] Fix implementation of sync-method 'next-keyframe' Original commit message from CVS: patch by: Michael Smith * 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' --- ChangeLog | 11 ++++++ gst/tcp/gstmultifdsink.c | 25 ++++++------- tests/check/elements/multifdsink.c | 60 ++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4ea3aa6c7..a5336dbfdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-09-07 Thomas Vander Stichele + + patch by: Michael Smith + + * 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 patch by: Wim Taymans diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index c5bcca3567..0d8879c326 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -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: diff --git a/tests/check/elements/multifdsink.c b/tests/check/elements/multifdsink.c index 024b27687d..36b4b58b15 100644 --- a/tests/check/elements/multifdsink.c +++ b/tests/check/elements/multifdsink.c @@ -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; }