gst_plugins_base/tsrc/check/elements/multifdsink/src/multifdsink.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  *
       
     3  * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Library General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Library General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Library General Public
       
    16  * License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 
       
    22 #include <gst/gst_global.h>
       
    23 #include <unistd.h>
       
    24 #include <sys/ioctl.h>
       
    25 #ifdef HAVE_FIONREAD_IN_SYS_FILIO
       
    26 #include <sys/filio.h>
       
    27 #endif
       
    28 
       
    29 #include <glib/gtypes.h>
       
    30 
       
    31 #define LOG_FILE "c:\\logs\\multifdsink_logs.txt" 
       
    32 #include "std_log_result.h" 
       
    33 #define LOG_FILENAME_LINE __FILE__, __LINE__
       
    34 
       
    35 void create_xml(int result)
       
    36 {
       
    37     if(result)
       
    38         assert_failed = 1;
       
    39     
       
    40     testResultXml(xmlfile);
       
    41     close_log_file();
       
    42 }
       
    43 
       
    44 #include <gst/check/gstcheck.h>
       
    45 
       
    46 static GstPad *mysrcpad;
       
    47 
       
    48 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
       
    49     GST_PAD_SRC,
       
    50     GST_PAD_ALWAYS,
       
    51     GST_STATIC_CAPS ("application/x-gst-check")
       
    52     );
       
    53 
       
    54 static GstElement *
       
    55 setup_multifdsink (void)
       
    56 {
       
    57   GstElement *multifdsink;
       
    58 
       
    59   GST_DEBUG ("setup_multifdsink");
       
    60   multifdsink = gst_check_setup_element ("multifdsink");
       
    61   mysrcpad = gst_check_setup_src_pad (multifdsink, &srctemplate, NULL);
       
    62 
       
    63   return multifdsink;
       
    64 }
       
    65 
       
    66 static void
       
    67 cleanup_multifdsink (GstElement * multifdsink)
       
    68 {
       
    69   GST_DEBUG ("cleanup_multifdsink");
       
    70 
       
    71   gst_check_teardown_src_pad (multifdsink);
       
    72   gst_check_teardown_element (multifdsink);
       
    73 }
       
    74 
       
    75 static void
       
    76 wait_bytes_served (GstElement * sink, guint64 bytes)
       
    77 {
       
    78   guint64 bytes_served = 0;
       
    79 
       
    80   while (bytes_served != bytes) {
       
    81     g_object_get (sink, "bytes-served", &bytes_served, NULL);
       
    82   }
       
    83 }
       
    84 
       
    85 /* FIXME: possibly racy, since if it would write, we may not get it
       
    86  * immediately ? */
       
    87 #define fail_if_can_read(msg,fd) \
       
    88 G_STMT_START { \
       
    89   long avail; \
       
    90 \
       
    91   fail_if (ioctl (fd, FIONREAD, &avail) < 0, "%s: could not ioctl", msg); \
       
    92   fail_if (avail > 0, "%s: has bytes available to read"); \
       
    93 } G_STMT_END;
       
    94 
       
    95 
       
    96 void test_no_clients()
       
    97 {
       
    98   GstElement *sink;
       
    99   GstBuffer *buffer;
       
   100   GstCaps *caps;
       
   101   
       
   102   std_log(LOG_FILENAME_LINE, "Test Started test_no_clients");
       
   103 
       
   104   sink = setup_multifdsink ();
       
   105 
       
   106   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   107 
       
   108   caps = gst_caps_from_string ("application/x-gst-check");
       
   109   buffer = gst_buffer_new_and_alloc (4);
       
   110   gst_buffer_set_caps (buffer, caps);
       
   111   gst_caps_unref (caps);
       
   112   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   113 
       
   114   GST_DEBUG ("cleaning up multifdsink");
       
   115 
       
   116   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);  //commented bz..select() blocks indefinitly
       
   117   cleanup_multifdsink (sink);
       
   118   
       
   119   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   120       create_xml(0);
       
   121 }
       
   122 
       
   123 
       
   124 
       
   125 void test_add_client()
       
   126 {
       
   127   GstElement *sink;
       
   128   GstBuffer *buffer;
       
   129   GstCaps *caps;
       
   130   int pfd[2];
       
   131   gchar data[4];
       
   132   
       
   133   std_log(LOG_FILENAME_LINE, "Test Started test_add_client");
       
   134 
       
   135   sink = setup_multifdsink ();
       
   136 
       
   137   fail_if (pipe (pfd) == -1);
       
   138 
       
   139   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   140 
       
   141   /* add the client */
       
   142   g_signal_emit_by_name (sink, "add", pfd[1]);
       
   143 
       
   144   caps = gst_caps_from_string ("application/x-gst-check");
       
   145   GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps);
       
   146   buffer = gst_buffer_new_and_alloc (4);
       
   147   gst_buffer_set_caps (buffer, caps);
       
   148   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
       
   149   memcpy (GST_BUFFER_DATA (buffer), "dead", 4);
       
   150   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   151 
       
   152   GST_DEBUG ("reading");
       
   153   fail_if (read (pfd[0], data, 4) < 4);
       
   154   fail_unless (strncmp (data, "dead", 4) == 0);
       
   155   wait_bytes_served (sink, 4);
       
   156 
       
   157   GST_DEBUG ("cleaning up multifdsink");
       
   158   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   159   cleanup_multifdsink (sink);
       
   160 
       
   161   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   162   gst_caps_unref (caps);
       
   163   
       
   164   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   165       create_xml(0);
       
   166 }
       
   167 
       
   168 
       
   169 
       
   170 #define fail_unless_read(msg,fd,size,ref) \
       
   171 G_STMT_START { \
       
   172   char data[size + 1]; \
       
   173   int nbytes; \
       
   174 \
       
   175   GST_DEBUG ("%s: reading %d bytes", msg, size); \
       
   176   nbytes = read (fd, data, size); \
       
   177   data[size] = 0; \
       
   178   GST_DEBUG ("%s: read %d bytes", msg, nbytes); \
       
   179   fail_if (nbytes < size); \
       
   180   fail_unless (memcmp (data, ref, size) == 0, \
       
   181       "data read '%s' differs from '%s'", data, ref); \
       
   182 } G_STMT_END;
       
   183 
       
   184 /* from the given two data buffers, create two streamheader buffers and
       
   185  * some caps that match it, and store them in the given pointers
       
   186  * returns  one ref to each of the buffers and the caps */
       
   187 static void
       
   188 gst_multifdsink_create_streamheader (const gchar * data1,
       
   189     const gchar * data2, GstBuffer ** hbuf1, GstBuffer ** hbuf2,
       
   190     GstCaps ** caps)
       
   191 {
       
   192   GstBuffer *buf;
       
   193   GValue array = { 0 };
       
   194   GValue value = { 0 };
       
   195   GstStructure *structure;
       
   196   guint size1 = strlen (data1);
       
   197   guint size2 = strlen (data2);
       
   198 
       
   199   fail_if (hbuf1 == NULL);
       
   200   fail_if (hbuf2 == NULL);
       
   201   fail_if (caps == NULL);
       
   202 
       
   203   /* create caps with streamheader, set the caps, and push the IN_CAPS
       
   204    * buffers */
       
   205   *hbuf1 = gst_buffer_new_and_alloc (size1);
       
   206   GST_BUFFER_FLAG_SET (*hbuf1, GST_BUFFER_FLAG_IN_CAPS);
       
   207   memcpy (GST_BUFFER_DATA (*hbuf1), data1, size1);
       
   208   *hbuf2 = gst_buffer_new_and_alloc (size2);
       
   209   GST_BUFFER_FLAG_SET (*hbuf2, GST_BUFFER_FLAG_IN_CAPS);
       
   210   memcpy (GST_BUFFER_DATA (*hbuf2), data2, size2);
       
   211   /* we want to keep them around for the tests */
       
   212   gst_buffer_ref (*hbuf1);
       
   213   gst_buffer_ref (*hbuf2);
       
   214 
       
   215   g_value_init (&array, GST_TYPE_ARRAY);
       
   216 
       
   217   g_value_init (&value, GST_TYPE_BUFFER);
       
   218   /* we take a copy, set it on the array (which refs it), then unref our copy */
       
   219   buf = gst_buffer_copy (*hbuf1);
       
   220   gst_value_set_buffer (&value, buf);
       
   221   ASSERT_BUFFER_REFCOUNT (buf, "copied buffer", 2);
       
   222   gst_buffer_unref (buf);
       
   223   gst_value_array_append_value (&array, &value);
       
   224   g_value_unset (&value);
       
   225 
       
   226   g_value_init (&value, GST_TYPE_BUFFER);
       
   227   buf = gst_buffer_copy (*hbuf2);
       
   228   gst_value_set_buffer (&value, buf);
       
   229   ASSERT_BUFFER_REFCOUNT (buf, "copied buffer", 2);
       
   230   gst_buffer_unref (buf);
       
   231   gst_value_array_append_value (&array, &value);
       
   232   g_value_unset (&value);
       
   233 
       
   234   *caps = gst_caps_from_string ("application/x-gst-check");
       
   235   structure = gst_caps_get_structure (*caps, 0);
       
   236 
       
   237   gst_structure_set_value (structure, "streamheader", &array);
       
   238   g_value_unset (&array);
       
   239   ASSERT_CAPS_REFCOUNT (*caps, "streamheader caps", 1);
       
   240 
       
   241   /* set our streamheadery caps on the buffers */
       
   242   gst_buffer_set_caps (*hbuf1, *caps);
       
   243   gst_buffer_set_caps (*hbuf2, *caps);
       
   244   ASSERT_CAPS_REFCOUNT (*caps, "streamheader caps", 3);
       
   245 
       
   246   GST_DEBUG ("created streamheader caps %p %" GST_PTR_FORMAT, *caps, *caps);
       
   247 }
       
   248 
       
   249 
       
   250 /* this test:
       
   251  * - adds a first client
       
   252  * - sets streamheader caps on the pad
       
   253  * - pushes the IN_CAPS buffers
       
   254  * - pushes a buffer
       
   255  * - verifies that the client received all the data correctly, and did not
       
   256  *   get multiple copies of the streamheader
       
   257  * - adds a second client
       
   258  * - verifies that this second client receives the streamheader caps too, plus
       
   259  * - the new buffer
       
   260  */
       
   261 void test_streamheader()
       
   262 {
       
   263   GstElement *sink;
       
   264   GstBuffer *hbuf1, *hbuf2, *buf;
       
   265   GstCaps *caps;
       
   266   int pfd1[2], pfd2[2];
       
   267   
       
   268   std_log(LOG_FILENAME_LINE, "Test Started test_streamheader");
       
   269 
       
   270   sink = setup_multifdsink ();
       
   271 
       
   272   fail_if (pipe (pfd1) == -1);
       
   273   fail_if (pipe (pfd2) == -1);
       
   274 
       
   275   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   276 
       
   277   /* add the first client */
       
   278   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   279 
       
   280   /* create caps with streamheader, set the caps, and push the IN_CAPS
       
   281    * buffers */
       
   282   gst_multifdsink_create_streamheader ("babe", "deadbeef", &hbuf1, &hbuf2,
       
   283       &caps);
       
   284   fail_unless (gst_pad_set_caps (mysrcpad, caps));
       
   285   /* one is ours, two on the buffers, and one now on the pad */
       
   286   ASSERT_CAPS_REFCOUNT (caps, "caps", 4);
       
   287 
       
   288   fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK);
       
   289   fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK);
       
   290 
       
   291   //FIXME:
       
   292   //fail_if_can_read ("first client", pfd1[0]);
       
   293 
       
   294   /* push a non-IN_CAPS buffer, this should trigger the client receiving the
       
   295    * first three buffers */
       
   296   buf = gst_buffer_new_and_alloc (4);
       
   297   memcpy (GST_BUFFER_DATA (buf), "f00d", 4);
       
   298   gst_pad_push (mysrcpad, buf);
       
   299 
       
   300   fail_unless_read ("first client", pfd1[0], 4, "babe");
       
   301   fail_unless_read ("first client", pfd1[0], 8, "deadbeef");
       
   302   fail_unless_read ("first client", pfd1[0], 4, "f00d");
       
   303   wait_bytes_served (sink, 16);
       
   304 
       
   305   /* now add the second client */
       
   306   g_signal_emit_by_name (sink, "add", pfd2[1]);
       
   307   //FIXME:
       
   308   //fail_if_can_read ("second client", pfd2[0]);
       
   309 
       
   310   /* now push another buffer, which will trigger streamheader for second
       
   311    * client */
       
   312   buf = gst_buffer_new_and_alloc (4);
       
   313   memcpy (GST_BUFFER_DATA (buf), "deaf", 4);
       
   314   gst_pad_push (mysrcpad, buf);
       
   315 
       
   316   fail_unless_read ("first client", pfd1[0], 4, "deaf");
       
   317 
       
   318   fail_unless_read ("second client", pfd2[0], 4, "babe");
       
   319   fail_unless_read ("second client", pfd2[0], 8, "deadbeef");
       
   320   /* we missed the f00d buffer */
       
   321   fail_unless_read ("second client", pfd2[0], 4, "deaf");
       
   322   wait_bytes_served (sink, 36);
       
   323 
       
   324   GST_DEBUG ("cleaning up multifdsink");
       
   325 
       
   326   g_signal_emit_by_name (sink, "remove", pfd1[1]);
       
   327   g_signal_emit_by_name (sink, "remove", pfd2[1]);
       
   328 
       
   329   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   330   cleanup_multifdsink (sink);
       
   331 
       
   332   ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 1);
       
   333   ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 1);
       
   334   gst_buffer_unref (hbuf1);
       
   335   gst_buffer_unref (hbuf2);
       
   336 
       
   337   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   338   gst_caps_unref (caps);
       
   339   
       
   340   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   341       create_xml(0);
       
   342 }
       
   343 
       
   344 
       
   345 
       
   346 /* this tests changing of streamheaders
       
   347  * - set streamheader caps on the pad
       
   348  * - pushes the IN_CAPS buffers
       
   349  * - pushes a buffer
       
   350  * - add a first client
       
   351  * - verifies that this first client receives the first streamheader caps,
       
   352  *   plus a new buffer
       
   353  * - change streamheader caps
       
   354  * - verify that the first client receives the new streamheader buffers as well
       
   355  */
       
   356 void test_change_streamheader()
       
   357 {
       
   358   GstElement *sink;
       
   359   GstBuffer *hbuf1, *hbuf2, *buf;
       
   360   GstCaps *caps;
       
   361   int pfd1[2], pfd2[2];
       
   362   
       
   363   std_log(LOG_FILENAME_LINE, "Test Started test_change_streamheader");
       
   364 
       
   365   sink = setup_multifdsink ();
       
   366 
       
   367   fail_if (pipe (pfd1) == -1);
       
   368   fail_if (pipe (pfd2) == -1);
       
   369 
       
   370   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   371 
       
   372   /* create caps with streamheader, set the caps, and push the IN_CAPS
       
   373    * buffers */
       
   374   gst_multifdsink_create_streamheader ("first", "header", &hbuf1, &hbuf2,
       
   375       &caps);
       
   376   fail_unless (gst_pad_set_caps (mysrcpad, caps));
       
   377   /* one is ours, two on the buffers, and one now on the pad */
       
   378   ASSERT_CAPS_REFCOUNT (caps, "caps", 4);
       
   379 
       
   380   /* one to hold for the test and one to give away */
       
   381   ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2);
       
   382   ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2);
       
   383 
       
   384   fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK);
       
   385   fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK);
       
   386 
       
   387   /* add the first client */
       
   388   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   389 
       
   390   /* verify this hasn't triggered a write yet */
       
   391   /* FIXME: possibly racy, since if it would write, we may not get it
       
   392    * immediately ? */
       
   393   //fail_if_can_read ("first client, no buffer", pfd1[0]);
       
   394 
       
   395   /* now push a buffer and read */
       
   396   buf = gst_buffer_new_and_alloc (4);
       
   397   memcpy (GST_BUFFER_DATA (buf), "f00d", 4);
       
   398   gst_pad_push (mysrcpad, buf);
       
   399 
       
   400   fail_unless_read ("change: first client", pfd1[0], 5, "first");
       
   401   fail_unless_read ("change: first client", pfd1[0], 6, "header");
       
   402   fail_unless_read ("change: first client", pfd1[0], 4, "f00d");
       
   403   //wait_bytes_served (sink, 16);
       
   404 
       
   405   /* now add the second client */
       
   406   g_signal_emit_by_name (sink, "add", pfd2[1]);
       
   407   //fail_if_can_read ("second client, no buffer", pfd2[0]);
       
   408 
       
   409   /* change the streamheader */
       
   410 
       
   411   /* before we change, multifdsink still has a list of the old streamheaders */
       
   412   ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2);
       
   413   ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2);
       
   414   gst_buffer_unref (hbuf1);
       
   415   gst_buffer_unref (hbuf2);
       
   416 
       
   417   /* drop our ref to the previous caps */
       
   418   gst_caps_unref (caps);
       
   419 
       
   420   gst_multifdsink_create_streamheader ("second", "header", &hbuf1, &hbuf2,
       
   421       &caps);
       
   422   fail_unless (gst_pad_set_caps (mysrcpad, caps));
       
   423   /* one to hold for the test and one to give away */
       
   424   ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 2);
       
   425   ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 2);
       
   426 
       
   427   fail_unless (gst_pad_push (mysrcpad, hbuf1) == GST_FLOW_OK);
       
   428   fail_unless (gst_pad_push (mysrcpad, hbuf2) == GST_FLOW_OK);
       
   429 
       
   430   /* verify neither client has new data available to read */
       
   431   //fail_if_can_read ("first client, changed streamheader", pfd1[0]);
       
   432   //fail_if_can_read ("second client, changed streamheader", pfd2[0]);
       
   433 
       
   434   /* now push another buffer, which will trigger streamheader for second
       
   435    * client, but should also send new streamheaders to first client */
       
   436   buf = gst_buffer_new_and_alloc (8);
       
   437   memcpy (GST_BUFFER_DATA (buf), "deadbabe", 8);
       
   438   gst_pad_push (mysrcpad, buf);
       
   439 
       
   440   fail_unless_read ("first client", pfd1[0], 6, "second");
       
   441   fail_unless_read ("first client", pfd1[0], 6, "header");
       
   442   fail_unless_read ("first client", pfd1[0], 8, "deadbabe");
       
   443 
       
   444   /* new streamheader data */
       
   445   fail_unless_read ("second client", pfd2[0], 6, "second");
       
   446   fail_unless_read ("second client", pfd2[0], 6, "header");
       
   447   /* we missed the f00d buffer */
       
   448   fail_unless_read ("second client", pfd2[0], 8, "deadbabe");
       
   449   //wait_bytes_served (sink, 36);
       
   450 
       
   451   GST_DEBUG ("cleaning up multifdsink");
       
   452   g_signal_emit_by_name (sink, "remove", pfd1[1]);
       
   453   g_signal_emit_by_name (sink, "remove", pfd2[1]);
       
   454   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   455 
       
   456   /* setting to NULL should have cleared the streamheader */
       
   457   ASSERT_BUFFER_REFCOUNT (hbuf1, "hbuf1", 1);
       
   458   ASSERT_BUFFER_REFCOUNT (hbuf2, "hbuf2", 1);
       
   459   gst_buffer_unref (hbuf1);
       
   460   gst_buffer_unref (hbuf2);
       
   461   cleanup_multifdsink (sink);
       
   462 
       
   463   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   464   gst_caps_unref (caps);
       
   465   
       
   466   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   467       create_xml(0);
       
   468 }
       
   469 
       
   470 
       
   471 
       
   472 /* keep 100 bytes and burst 80 bytes to clients */
       
   473 void test_burst_client_bytes()
       
   474 {
       
   475   GstElement *sink;
       
   476   GstBuffer *buffer;
       
   477   GstCaps *caps;
       
   478   int pfd1[2];
       
   479   int pfd2[2];
       
   480   int pfd3[2];
       
   481   gchar data[16];
       
   482   gint i;
       
   483   guint buffers_queued;
       
   484   
       
   485   std_log(LOG_FILENAME_LINE, "Test Started test_burst_client_bytes");
       
   486 
       
   487   sink = setup_multifdsink ();
       
   488   /* make sure we keep at least 100 bytes at all times */
       
   489   g_object_set (sink, "bytes-min", 100, NULL);
       
   490   g_object_set (sink, "sync-method", 3, NULL);  /* 3 = burst */
       
   491   g_object_set (sink, "burst-unit", 3, NULL);   /* 3 = bytes */
       
   492   g_object_set (sink, "burst-value", (guint64) 80, NULL);
       
   493 
       
   494   fail_if (pipe (pfd1) == -1);
       
   495   fail_if (pipe (pfd2) == -1);
       
   496   fail_if (pipe (pfd3) == -1);
       
   497 
       
   498   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   499 
       
   500   caps = gst_caps_from_string ("application/x-gst-check");
       
   501   GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps);
       
   502 
       
   503   /* push buffers in, 9 * 16 bytes = 144 bytes */
       
   504   for (i = 0; i < 9; i++) {
       
   505     gchar *data;
       
   506 
       
   507     buffer = gst_buffer_new_and_alloc (16);
       
   508     gst_buffer_set_caps (buffer, caps);
       
   509 
       
   510     /* copy some id */
       
   511     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   512     g_snprintf (data, 16, "deadbee%08x", i);
       
   513 
       
   514     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   515   }
       
   516 
       
   517   /* check that at least 7 buffers (112 bytes) are in the queue */
       
   518   g_object_get (sink, "buffers-queued", &buffers_queued, NULL);
       
   519   fail_if (buffers_queued != 7);
       
   520 
       
   521   /* now add the clients */
       
   522   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   523   g_signal_emit_by_name (sink, "add_full", pfd2[1], 3,
       
   524       3, (guint64) 50, 3, (guint64) 200);
       
   525   g_signal_emit_by_name (sink, "add_full", pfd3[1], 3,
       
   526       3, (guint64) 50, 3, (guint64) 50);
       
   527 
       
   528   /* push last buffer to make client fds ready for reading */
       
   529   for (i = 9; i < 10; i++) {
       
   530     gchar *data;
       
   531 
       
   532     buffer = gst_buffer_new_and_alloc (16);
       
   533     gst_buffer_set_caps (buffer, caps);
       
   534 
       
   535     /* copy some id */
       
   536     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   537     g_snprintf (data, 16, "deadbee%08x", i);
       
   538 
       
   539     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   540   }
       
   541 
       
   542   /* now we should only read the last 5 buffers (5 * 16 = 80 bytes) */
       
   543   GST_DEBUG ("Reading from client 1");
       
   544   fail_if (read (pfd1[0], data, 16) < 16);
       
   545   fail_unless (strncmp (data, "deadbee00000005", 16) == 0);
       
   546   fail_if (read (pfd1[0], data, 16) < 16);
       
   547   fail_unless (strncmp (data, "deadbee00000006", 16) == 0);
       
   548   fail_if (read (pfd1[0], data, 16) < 16);
       
   549   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   550   fail_if (read (pfd1[0], data, 16) < 16);
       
   551   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   552   fail_if (read (pfd1[0], data, 16) < 16);
       
   553   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   554 
       
   555   /* second client only bursts 50 bytes = 4 buffers (we get 4 buffers since
       
   556    * the max alows it) */
       
   557   GST_DEBUG ("Reading from client 2");
       
   558   fail_if (read (pfd2[0], data, 16) < 16);
       
   559   fail_unless (strncmp (data, "deadbee00000006", 16) == 0);
       
   560   fail_if (read (pfd2[0], data, 16) < 16);
       
   561   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   562   fail_if (read (pfd2[0], data, 16) < 16);
       
   563   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   564   fail_if (read (pfd2[0], data, 16) < 16);
       
   565   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   566 
       
   567   /* third client only bursts 50 bytes = 4 buffers, we can't send
       
   568    * more than 50 bytes so we only get 3 buffers (48 bytes). */
       
   569   GST_DEBUG ("Reading from client 3");
       
   570   fail_if (read (pfd3[0], data, 16) < 16);
       
   571   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   572   fail_if (read (pfd3[0], data, 16) < 16);
       
   573   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   574   fail_if (read (pfd3[0], data, 16) < 16);
       
   575   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   576 
       
   577   GST_DEBUG ("cleaning up multifdsink");
       
   578   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   579   cleanup_multifdsink (sink);
       
   580 
       
   581   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   582   gst_caps_unref (caps);
       
   583   
       
   584   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   585       create_xml(0);
       
   586 }
       
   587 
       
   588 
       
   589 
       
   590 /* keep 100 bytes and burst 80 bytes to clients */
       
   591 void test_burst_client_bytes_keyframe()
       
   592 {
       
   593   GstElement *sink;
       
   594   GstBuffer *buffer;
       
   595   GstCaps *caps;
       
   596   int pfd1[2];
       
   597   int pfd2[2];
       
   598   int pfd3[2];
       
   599   gchar data[16];
       
   600   gint i;
       
   601   guint buffers_queued;
       
   602   
       
   603   std_log(LOG_FILENAME_LINE, "Test Started test_burst_client_bytes_keyframe");
       
   604 
       
   605   sink = setup_multifdsink ();
       
   606   /* make sure we keep at least 100 bytes at all times */
       
   607   g_object_set (sink, "bytes-min", 100, NULL);
       
   608   g_object_set (sink, "sync-method", 4, NULL);  /* 3 = burst_keyframe */
       
   609   g_object_set (sink, "burst-unit", 3, NULL);   /* 3 = bytes */
       
   610   g_object_set (sink, "burst-value", (guint64) 80, NULL);
       
   611 
       
   612   fail_if (pipe (pfd1) == -1);
       
   613   fail_if (pipe (pfd2) == -1);
       
   614   fail_if (pipe (pfd3) == -1);
       
   615 
       
   616   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   617 
       
   618   caps = gst_caps_from_string ("application/x-gst-check");
       
   619   GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps);
       
   620 
       
   621   /* push buffers in, 9 * 16 bytes = 144 bytes */
       
   622   for (i = 0; i < 9; i++) {
       
   623     gchar *data;
       
   624 
       
   625     buffer = gst_buffer_new_and_alloc (16);
       
   626     gst_buffer_set_caps (buffer, caps);
       
   627 
       
   628     /* mark most buffers as delta */
       
   629     if (i != 0 && i != 4 && i != 8)
       
   630       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
       
   631 
       
   632     /* copy some id */
       
   633     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   634     g_snprintf (data, 16, "deadbee%08x", i);
       
   635 
       
   636     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   637   }
       
   638 
       
   639   /* check that at least 7 buffers (112 bytes) are in the queue */
       
   640   g_object_get (sink, "buffers-queued", &buffers_queued, NULL);
       
   641   fail_if (buffers_queued != 7);
       
   642 
       
   643   /* now add the clients */
       
   644   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   645   g_signal_emit_by_name (sink, "add_full", pfd2[1], 4,
       
   646       3, (guint64) 50, 3, (guint64) 90);
       
   647   g_signal_emit_by_name (sink, "add_full", pfd3[1], 4,
       
   648       3, (guint64) 50, 3, (guint64) 50);
       
   649 
       
   650   /* push last buffer to make client fds ready for reading */
       
   651   for (i = 9; i < 10; i++) {
       
   652     gchar *data;
       
   653 
       
   654     buffer = gst_buffer_new_and_alloc (16);
       
   655     gst_buffer_set_caps (buffer, caps);
       
   656     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
       
   657 
       
   658     /* copy some id */
       
   659     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   660     g_snprintf (data, 16, "deadbee%08x", i);
       
   661 
       
   662     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   663   }
       
   664 
       
   665   /* now we should only read the last 6 buffers (min 5 * 16 = 80 bytes),
       
   666    * keyframe at buffer 4 */
       
   667   GST_DEBUG ("Reading from client 1");
       
   668   fail_if (read (pfd1[0], data, 16) < 16);
       
   669   fail_unless (strncmp (data, "deadbee00000004", 16) == 0);
       
   670   fail_if (read (pfd1[0], data, 16) < 16);
       
   671   fail_unless (strncmp (data, "deadbee00000005", 16) == 0);
       
   672   fail_if (read (pfd1[0], data, 16) < 16);
       
   673   fail_unless (strncmp (data, "deadbee00000006", 16) == 0);
       
   674   fail_if (read (pfd1[0], data, 16) < 16);
       
   675   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   676   fail_if (read (pfd1[0], data, 16) < 16);
       
   677   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   678   fail_if (read (pfd1[0], data, 16) < 16);
       
   679   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   680 
       
   681   /* second client only bursts 50 bytes = 4 buffers, there is
       
   682    * no keyframe above min and below max, so get one below min */
       
   683   GST_DEBUG ("Reading from client 2");
       
   684   fail_if (read (pfd2[0], data, 16) < 16);
       
   685   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   686   fail_if (read (pfd2[0], data, 16) < 16);
       
   687   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   688 
       
   689   /* third client only bursts 50 bytes = 4 buffers, we can't send
       
   690    * more than 50 bytes so we only get 2 buffers (32 bytes). */
       
   691   GST_DEBUG ("Reading from client 3");
       
   692   fail_if (read (pfd3[0], data, 16) < 16);
       
   693   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   694   fail_if (read (pfd3[0], data, 16) < 16);
       
   695   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   696 
       
   697   GST_DEBUG ("cleaning up multifdsink");
       
   698   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   699   cleanup_multifdsink (sink);
       
   700 
       
   701   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   702   gst_caps_unref (caps);
       
   703   
       
   704   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   705       create_xml(0);
       
   706 }
       
   707 
       
   708 
       
   709 
       
   710 /* keep 100 bytes and burst 80 bytes to clients */
       
   711 void test_burst_client_bytes_with_keyframe()
       
   712 {
       
   713   GstElement *sink;
       
   714   GstBuffer *buffer;
       
   715   GstCaps *caps;
       
   716   int pfd1[2];
       
   717   int pfd2[2];
       
   718   int pfd3[2];
       
   719   gchar data[16];
       
   720   gint i;
       
   721   guint buffers_queued;
       
   722   
       
   723   std_log(LOG_FILENAME_LINE, "Test Started test_burst_client_bytes_with_keyframe");
       
   724 
       
   725   sink = setup_multifdsink ();
       
   726   /* make sure we keep at least 100 bytes at all times */
       
   727   g_object_set (sink, "bytes-min", 100, NULL);
       
   728   g_object_set (sink, "sync-method", 5, NULL);  /* 3 = burst_with_keyframe */
       
   729   g_object_set (sink, "burst-unit", 3, NULL);   /* 3 = bytes */
       
   730   g_object_set (sink, "burst-value", (guint64) 80, NULL);
       
   731 
       
   732   fail_if (pipe (pfd1) == -1);
       
   733   fail_if (pipe (pfd2) == -1);
       
   734   fail_if (pipe (pfd3) == -1);
       
   735 
       
   736   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   737 
       
   738   caps = gst_caps_from_string ("application/x-gst-check");
       
   739   GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps);
       
   740 
       
   741   /* push buffers in, 9 * 16 bytes = 144 bytes */
       
   742   for (i = 0; i < 9; i++) {
       
   743     gchar *data;
       
   744 
       
   745     buffer = gst_buffer_new_and_alloc (16);
       
   746     gst_buffer_set_caps (buffer, caps);
       
   747 
       
   748     /* mark most buffers as delta */
       
   749     if (i != 0 && i != 4 && i != 8)
       
   750       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
       
   751 
       
   752     /* copy some id */
       
   753     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   754     g_snprintf (data, 16, "deadbee%08x", i);
       
   755 
       
   756     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   757   }
       
   758 
       
   759   /* check that at least 7 buffers (112 bytes) are in the queue */
       
   760   g_object_get (sink, "buffers-queued", &buffers_queued, NULL);
       
   761   fail_if (buffers_queued != 7);
       
   762 
       
   763   /* now add the clients */
       
   764   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   765   g_signal_emit_by_name (sink, "add_full", pfd2[1], 5,
       
   766       3, (guint64) 50, 3, (guint64) 90);
       
   767   g_signal_emit_by_name (sink, "add_full", pfd3[1], 5,
       
   768       3, (guint64) 50, 3, (guint64) 50);
       
   769 
       
   770   /* push last buffer to make client fds ready for reading */
       
   771   for (i = 9; i < 10; i++) {
       
   772     gchar *data;
       
   773 
       
   774     buffer = gst_buffer_new_and_alloc (16);
       
   775     gst_buffer_set_caps (buffer, caps);
       
   776     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
       
   777 
       
   778     /* copy some id */
       
   779     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   780     g_snprintf (data, 16, "deadbee%08x", i);
       
   781 
       
   782     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   783   }
       
   784 
       
   785   /* now we should only read the last 6 buffers (min 5 * 16 = 80 bytes),
       
   786    * keyframe at buffer 4 */
       
   787   GST_DEBUG ("Reading from client 1");
       
   788   fail_if (read (pfd1[0], data, 16) < 16);
       
   789   fail_unless (strncmp (data, "deadbee00000004", 16) == 0);
       
   790   fail_if (read (pfd1[0], data, 16) < 16);
       
   791   fail_unless (strncmp (data, "deadbee00000005", 16) == 0);
       
   792   fail_if (read (pfd1[0], data, 16) < 16);
       
   793   fail_unless (strncmp (data, "deadbee00000006", 16) == 0);
       
   794   fail_if (read (pfd1[0], data, 16) < 16);
       
   795   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   796   fail_if (read (pfd1[0], data, 16) < 16);
       
   797   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   798   fail_if (read (pfd1[0], data, 16) < 16);
       
   799   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   800 
       
   801   /* second client only bursts 50 bytes = 4 buffers, there is
       
   802    * no keyframe above min and below max, so send min */
       
   803   GST_DEBUG ("Reading from client 2");
       
   804   fail_if (read (pfd2[0], data, 16) < 16);
       
   805   fail_unless (strncmp (data, "deadbee00000006", 16) == 0);
       
   806   fail_if (read (pfd2[0], data, 16) < 16);
       
   807   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   808   fail_if (read (pfd2[0], data, 16) < 16);
       
   809   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   810   fail_if (read (pfd2[0], data, 16) < 16);
       
   811   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   812 
       
   813   /* third client only bursts 50 bytes = 4 buffers, we can't send
       
   814    * more than 50 bytes so we only get 3 buffers (48 bytes). */
       
   815   GST_DEBUG ("Reading from client 3");
       
   816   fail_if (read (pfd3[0], data, 16) < 16);
       
   817   fail_unless (strncmp (data, "deadbee00000007", 16) == 0);
       
   818   fail_if (read (pfd3[0], data, 16) < 16);
       
   819   fail_unless (strncmp (data, "deadbee00000008", 16) == 0);
       
   820   fail_if (read (pfd3[0], data, 16) < 16);
       
   821   fail_unless (strncmp (data, "deadbee00000009", 16) == 0);
       
   822 
       
   823   GST_DEBUG ("cleaning up multifdsink");
       
   824   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   825   cleanup_multifdsink (sink);
       
   826 
       
   827   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   828   gst_caps_unref (caps);
       
   829   
       
   830   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   831       create_xml(0);
       
   832 }
       
   833 
       
   834 
       
   835 /* Check that we can get data when multifdsink is configured in next-keyframe
       
   836  * mode */
       
   837 void test_client_next_keyframe()
       
   838 {
       
   839   GstElement *sink;
       
   840   GstBuffer *buffer;
       
   841   GstCaps *caps;
       
   842   int pfd1[2];
       
   843   gchar data[16];
       
   844   gint i;
       
   845   
       
   846     
       
   847   std_log(LOG_FILENAME_LINE, "Test Started test_client_next_keyframe");
       
   848   
       
   849   sink = setup_multifdsink ();
       
   850   g_object_set (sink, "sync-method", 1, NULL);  /* 1 = next-keyframe */
       
   851 
       
   852   fail_if (pipe (pfd1) == -1);
       
   853 
       
   854   ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
       
   855 
       
   856   caps = gst_caps_from_string ("application/x-gst-check");
       
   857   GST_DEBUG ("Created test caps %p %" GST_PTR_FORMAT, caps, caps);
       
   858 
       
   859   /* now add our client */
       
   860   g_signal_emit_by_name (sink, "add", pfd1[1]);
       
   861 
       
   862   /* push buffers in: keyframe, then non-keyframe */
       
   863   for (i = 0; i < 2; i++) {
       
   864     gchar *data;
       
   865 
       
   866     buffer = gst_buffer_new_and_alloc (16);
       
   867     gst_buffer_set_caps (buffer, caps);
       
   868 
       
   869     /* copy some id */
       
   870     data = (gchar *) GST_BUFFER_DATA (buffer);
       
   871     g_snprintf (data, 16, "deadbee%08x", i);
       
   872     if (i > 0)
       
   873       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
       
   874 
       
   875     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
       
   876   }
       
   877 
       
   878   /* now we should be able to read some data */
       
   879   GST_DEBUG ("Reading from client 1");
       
   880   fail_if (read (pfd1[0], data, 16) < 16);
       
   881   fail_unless (strncmp (data, "deadbee00000000", 16) == 0);
       
   882   fail_if (read (pfd1[0], data, 16) < 16);
       
   883   fail_unless (strncmp (data, "deadbee00000001", 16) == 0);
       
   884 
       
   885   GST_DEBUG ("cleaning up multifdsink");
       
   886   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
       
   887   cleanup_multifdsink (sink);
       
   888 
       
   889   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
       
   890   gst_caps_unref (caps);
       
   891   
       
   892   std_log(LOG_FILENAME_LINE, "Test Successful");
       
   893       create_xml(0);
       
   894 }
       
   895 
       
   896 
       
   897 
       
   898 /* FIXME: add test simulating chained oggs where:
       
   899  * sync-method is burst-on-connect
       
   900  * (when multifdsink actually does burst-on-connect based on byte size, not
       
   901    "last keyframe" which any frame for audio :))
       
   902  * an old client still needs to read from before the new streamheaders
       
   903  * a new client gets the new streamheaders
       
   904  */
       
   905 
       
   906 
       
   907 void (*fn[]) (void) = {
       
   908 test_no_clients,
       
   909 test_add_client,
       
   910 test_streamheader,
       
   911 test_change_streamheader,
       
   912 test_burst_client_bytes,
       
   913 test_burst_client_bytes_keyframe,
       
   914 test_burst_client_bytes_with_keyframe,
       
   915 test_client_next_keyframe
       
   916 };
       
   917 
       
   918 char *args[] = {
       
   919 "test_no_clients",
       
   920 "test_add_client",
       
   921 "test_streamheader",
       
   922 "test_change_streamheader",
       
   923 "test_burst_client_bytes",
       
   924 "test_burst_client_bytes_keyframe",
       
   925 "test_burst_client_bytes_with_keyframe",
       
   926 "test_client_next_keyframe"
       
   927 };
       
   928 
       
   929 GST_CHECK_MAIN(multifdsink)
       
   930