Fix implementation of sync-method 'next-keyframe'
authorMichael Smith <msmith@fluendo.com>
Thu, 7 Sep 2006 19:00:33 +0000 (19:00 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Thu, 7 Sep 2006 19:00:33 +0000 (19:00 +0000)
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'

ChangeLog
gst/tcp/gstmultifdsink.c
tests/check/elements/multifdsink.c

index c4ea3aa..a5336db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 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):
index c5bcca3..0d8879c 100644 (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:
index 024b276..36b4b58 100644 (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;
 }