gst_plugins_base/tests/check/elements/gdpdepay.c
changeset 0 0e761a78d257
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 #include "config.h"
       
    22 #include <string.h>
       
    23 #include <unistd.h>
       
    24 
       
    25 #include <gst/check/gstcheck.h>
       
    26 #include <gst/dataprotocol/dataprotocol.h>
       
    27 
       
    28 /* For ease of programming we use globals to keep refs for our floating
       
    29  * src and sink pads we create; otherwise we always have to do get_pad,
       
    30  * get_peer, and then remove references in every test function */
       
    31 static GstPad *mysrcpad, *mysinkpad, *myshsinkpad;
       
    32 
       
    33 #define AUDIO_CAPS_TEMPLATE_STRING \
       
    34   "audio/x-raw-int, " \
       
    35     "rate = (int) [ 1, MAX ], " \
       
    36     "channels = (int) [ 1, 8 ], " \
       
    37     "endianness = (int) BYTE_ORDER, " \
       
    38     "width = (int) {8, 16}, " \
       
    39     "depth = (int) {8, 16}, " \
       
    40     "signed = (boolean) true"
       
    41 
       
    42 #define AUDIO_CAPS_STRING \
       
    43   "audio/x-raw-int, " \
       
    44     "rate = (int) 1000, " \
       
    45     "channels = (int) 2, " \
       
    46     "endianness = (int) BYTE_ORDER, " \
       
    47     "width = (int) 16, " \
       
    48     "depth = (int) 16, " \
       
    49     "signed = (boolean) true"
       
    50 
       
    51 
       
    52 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
       
    53     GST_PAD_SINK,
       
    54     GST_PAD_ALWAYS,
       
    55     GST_STATIC_CAPS (AUDIO_CAPS_TEMPLATE_STRING)
       
    56     );
       
    57 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
       
    58     GST_PAD_SRC,
       
    59     GST_PAD_ALWAYS,
       
    60     GST_STATIC_CAPS ("application/x-gdp")
       
    61     );
       
    62 
       
    63 /* takes over reference for outcaps */
       
    64 static GstElement *
       
    65 setup_gdpdepay (void)
       
    66 {
       
    67   GstElement *gdpdepay;
       
    68 
       
    69   GST_DEBUG ("setup_gdpdepay");
       
    70   gdpdepay = gst_check_setup_element ("gdpdepay");
       
    71   mysrcpad = gst_check_setup_src_pad (gdpdepay, &srctemplate, NULL);
       
    72   mysinkpad = gst_check_setup_sink_pad (gdpdepay, &sinktemplate, NULL);
       
    73   gst_pad_set_active (mysrcpad, TRUE);
       
    74   gst_pad_set_active (mysinkpad, TRUE);
       
    75 
       
    76   return gdpdepay;
       
    77 }
       
    78 
       
    79 static void
       
    80 cleanup_gdpdepay (GstElement * gdpdepay)
       
    81 {
       
    82   GST_DEBUG ("cleanup_gdpdepay");
       
    83 
       
    84   gst_pad_set_active (mysrcpad, FALSE);
       
    85   if (mysinkpad)
       
    86     gst_pad_set_active (mysinkpad, FALSE);
       
    87   if (myshsinkpad)
       
    88     gst_pad_set_active (myshsinkpad, FALSE);
       
    89   gst_check_teardown_src_pad (gdpdepay);
       
    90   gst_check_teardown_sink_pad (gdpdepay);
       
    91   gst_check_teardown_element (gdpdepay);
       
    92   mysinkpad = NULL;
       
    93   myshsinkpad = NULL;
       
    94 }
       
    95 
       
    96 static void
       
    97 gdpdepay_push_per_byte (gchar * reason, guint8 * bytes, guint length)
       
    98 {
       
    99   int i;
       
   100   GstBuffer *inbuffer;
       
   101 
       
   102   for (i = 0; i < length; ++i) {
       
   103     inbuffer = gst_buffer_new_and_alloc (1);
       
   104     GST_BUFFER_DATA (inbuffer)[0] = bytes[i];
       
   105     fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK,
       
   106         "%s: failed pushing byte buffer", reason);
       
   107   }
       
   108 }
       
   109 
       
   110 GST_START_TEST (test_audio_per_byte)
       
   111 {
       
   112   GstCaps *caps;
       
   113   GstPad *srcpad;
       
   114   GstElement *gdpdepay;
       
   115   GstBuffer *buffer, *outbuffer;
       
   116   guint8 *header, *payload;
       
   117   guint len;
       
   118   GstDPPacketizer *pk;
       
   119 
       
   120   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
       
   121 
       
   122   gdpdepay = setup_gdpdepay ();
       
   123   srcpad = gst_element_get_pad (gdpdepay, "src");
       
   124 
       
   125   fail_unless (gst_element_set_state (gdpdepay,
       
   126           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
       
   127       "could not set to playing");
       
   128 
       
   129   caps = gst_pad_get_caps (srcpad);
       
   130   fail_unless (gst_caps_is_any (caps));
       
   131   gst_caps_unref (caps);
       
   132   fail_if (gst_pad_get_negotiated_caps (srcpad));
       
   133 
       
   134   /* create caps and buffer packets and push them */
       
   135   caps = gst_caps_from_string (AUDIO_CAPS_STRING);
       
   136   fail_unless (pk->packet_from_caps (caps, 0, &len, &header, &payload));
       
   137   gst_caps_unref (caps);
       
   138   gdpdepay_push_per_byte ("caps header", header, len);
       
   139   fail_unless_equals_int (g_list_length (buffers), 0);
       
   140   gdpdepay_push_per_byte ("caps payload", payload,
       
   141       gst_dp_header_payload_length (header));
       
   142   fail_unless_equals_int (g_list_length (buffers), 0);
       
   143   caps = gst_pad_get_caps (srcpad);
       
   144   fail_if (gst_caps_is_any (caps));
       
   145   gst_caps_unref (caps);
       
   146 
       
   147   g_free (header);
       
   148   g_free (payload);
       
   149 
       
   150   buffer = gst_buffer_new_and_alloc (4);
       
   151   memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
       
   152   GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND;
       
   153   GST_BUFFER_DURATION (buffer) = GST_SECOND / 10;
       
   154   fail_unless (pk->header_from_buffer (buffer, 0, &len, &header));
       
   155   gdpdepay_push_per_byte ("buffer header", header, len);
       
   156   fail_unless_equals_int (g_list_length (buffers), 0);
       
   157   gdpdepay_push_per_byte ("buffer payload", GST_BUFFER_DATA (buffer),
       
   158       gst_dp_header_payload_length (header));
       
   159   g_free (header);
       
   160   gst_buffer_unref (buffer);
       
   161 
       
   162   fail_unless_equals_int (g_list_length (buffers), 1);
       
   163   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
       
   164   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), GST_SECOND);
       
   165   fail_unless_equals_uint64 (GST_BUFFER_DURATION (outbuffer), GST_SECOND / 10);
       
   166 
       
   167   buffers = g_list_remove (buffers, outbuffer);
       
   168   gst_buffer_unref (outbuffer);
       
   169 
       
   170   fail_unless (gst_element_set_state (gdpdepay,
       
   171           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
       
   172 
       
   173   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
       
   174   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
       
   175   g_list_free (buffers);
       
   176   buffers = NULL;
       
   177   gst_object_unref (srcpad);
       
   178   cleanup_gdpdepay (gdpdepay);
       
   179 
       
   180   gst_dp_packetizer_free (pk);
       
   181 }
       
   182 
       
   183 GST_END_TEST;
       
   184 
       
   185 GST_START_TEST (test_audio_in_one_buffer)
       
   186 {
       
   187   GstCaps *caps;
       
   188   GstPad *srcpad;
       
   189   GstElement *gdpdepay;
       
   190   GstBuffer *buffer, *inbuffer;
       
   191   guint8 *caps_header, *caps_payload, *buf_header;
       
   192   guint header_len, payload_len;
       
   193   guint i;
       
   194   GstDPPacketizer *pk;
       
   195 
       
   196   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
       
   197 
       
   198   gdpdepay = setup_gdpdepay ();
       
   199   srcpad = gst_element_get_pad (gdpdepay, "src");
       
   200 
       
   201   fail_unless (gst_element_set_state (gdpdepay,
       
   202           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
       
   203       "could not set to playing");
       
   204 
       
   205   /* make sure no caps are set yet */
       
   206   caps = gst_pad_get_caps (srcpad);
       
   207   fail_unless (gst_caps_is_any (caps));
       
   208   gst_caps_unref (caps);
       
   209   fail_if (gst_pad_get_negotiated_caps (srcpad));
       
   210 
       
   211   /* create caps and buffer packets and push them as one buffer */
       
   212   caps = gst_caps_from_string (AUDIO_CAPS_STRING);
       
   213   fail_unless (pk->packet_from_caps (caps, 0, &header_len, &caps_header,
       
   214           &caps_payload));
       
   215 
       
   216   buffer = gst_buffer_new_and_alloc (4);
       
   217   memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
       
   218   fail_unless (pk->header_from_buffer (buffer, 0, &header_len, &buf_header));
       
   219 
       
   220   payload_len = gst_dp_header_payload_length (caps_header);
       
   221 
       
   222   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
       
   223       payload_len + GST_BUFFER_SIZE (buffer));
       
   224   memcpy (GST_BUFFER_DATA (inbuffer), caps_header, GST_DP_HEADER_LENGTH);
       
   225   i = GST_DP_HEADER_LENGTH;
       
   226   memcpy (GST_BUFFER_DATA (inbuffer) + i, caps_payload, payload_len);
       
   227   i += payload_len;
       
   228   memcpy (GST_BUFFER_DATA (inbuffer) + i, buf_header, GST_DP_HEADER_LENGTH);
       
   229   i += GST_DP_HEADER_LENGTH;
       
   230   memcpy (GST_BUFFER_DATA (inbuffer) + i, GST_BUFFER_DATA (buffer),
       
   231       GST_BUFFER_SIZE (buffer));
       
   232 
       
   233   gst_caps_unref (caps);
       
   234   gst_buffer_unref (buffer);
       
   235 
       
   236   g_free (caps_header);
       
   237   g_free (caps_payload);
       
   238   g_free (buf_header);
       
   239 
       
   240   /* now push it */
       
   241   gst_pad_push (mysrcpad, inbuffer);
       
   242 
       
   243   /* the buffer is still queued */
       
   244   fail_unless_equals_int (g_list_length (buffers), 1);
       
   245 
       
   246   fail_unless (gst_element_set_state (gdpdepay,
       
   247           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
       
   248 
       
   249   gst_object_unref (srcpad);
       
   250   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
       
   251   g_list_free (buffers);
       
   252   buffers = NULL;
       
   253   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
       
   254   cleanup_gdpdepay (gdpdepay);
       
   255 
       
   256   gst_dp_packetizer_free (pk);
       
   257 }
       
   258 
       
   259 GST_END_TEST;
       
   260 
       
   261 static GstStaticPadTemplate shsinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
       
   262     GST_PAD_SINK,
       
   263     GST_PAD_ALWAYS,
       
   264     GST_STATIC_CAPS ("application/x-gst-test-streamheader")
       
   265     );
       
   266 
       
   267 static GstElement *
       
   268 setup_gdpdepay_streamheader (void)
       
   269 {
       
   270   GstElement *gdpdepay;
       
   271 
       
   272   GST_DEBUG ("setup_gdpdepay");
       
   273   gdpdepay = gst_check_setup_element ("gdpdepay");
       
   274   mysrcpad = gst_check_setup_src_pad (gdpdepay, &srctemplate, NULL);
       
   275   myshsinkpad = gst_check_setup_sink_pad (gdpdepay, &shsinktemplate, NULL);
       
   276   gst_pad_set_active (mysrcpad, TRUE);
       
   277   gst_pad_set_active (myshsinkpad, TRUE);
       
   278 
       
   279   return gdpdepay;
       
   280 }
       
   281 
       
   282 #ifndef HAVE_CPU_PPC64          /* Test known to fail on PPC64. See #348114 */
       
   283 
       
   284 /* this tests deserialization of a GDP stream where the serialized caps
       
   285  * have a streamheader set */
       
   286 GST_START_TEST (test_streamheader)
       
   287 {
       
   288   GstCaps *caps, *padcaps;
       
   289   GstPad *srcpad;
       
   290   GstElement *gdpdepay;
       
   291   GstBuffer *buffer, *inbuffer, *outbuffer, *shbuffer;
       
   292   guint8 *caps_header, *caps_payload, *buf_header;
       
   293   guint header_len, payload_len;
       
   294   guint i;
       
   295   GstStructure *structure;
       
   296   GValue array = { 0 };
       
   297   GValue value = { 0 };
       
   298   GstDPPacketizer *pk;
       
   299 
       
   300   pk = gst_dp_packetizer_new (GST_DP_VERSION_1_0);
       
   301 
       
   302   gdpdepay = setup_gdpdepay_streamheader ();
       
   303   srcpad = gst_element_get_pad (gdpdepay, "src");
       
   304   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
       
   305 
       
   306   fail_unless (gst_element_set_state (gdpdepay,
       
   307           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
       
   308       "could not set to playing");
       
   309 
       
   310   /* make sure no caps are set yet */
       
   311   caps = gst_pad_get_caps (srcpad);
       
   312   fail_unless (gst_caps_is_any (caps));
       
   313   gst_caps_unref (caps);
       
   314   fail_if (gst_pad_get_negotiated_caps (srcpad));
       
   315 
       
   316   /* create a streamheader buffer and the caps containing it */
       
   317   caps = gst_caps_from_string ("application/x-gst-test-streamheader");
       
   318   structure = gst_caps_get_structure (caps, 0);
       
   319   buffer = gst_buffer_new_and_alloc (4);
       
   320   memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
       
   321   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
       
   322   g_value_init (&array, GST_TYPE_ARRAY);
       
   323   g_value_init (&value, GST_TYPE_BUFFER);
       
   324   shbuffer = gst_buffer_copy (buffer);
       
   325   gst_value_set_buffer (&value, shbuffer);
       
   326   gst_buffer_unref (shbuffer);
       
   327   gst_value_array_append_value (&array, &value);
       
   328   g_value_unset (&value);
       
   329   gst_structure_set_value (structure, "streamheader", &array);
       
   330   g_value_unset (&array);
       
   331 
       
   332   gst_buffer_set_caps (buffer, caps);
       
   333 
       
   334   /* create GDP packets for the caps and the buffer, and put them in one
       
   335    * GDP buffer */
       
   336   fail_unless (pk->packet_from_caps (caps, 0, &header_len, &caps_header,
       
   337           &caps_payload));
       
   338 
       
   339   fail_unless (pk->header_from_buffer (buffer, 0, &header_len, &buf_header));
       
   340 
       
   341   payload_len = gst_dp_header_payload_length (caps_header);
       
   342 
       
   343   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
       
   344       payload_len + GST_BUFFER_SIZE (buffer));
       
   345   memcpy (GST_BUFFER_DATA (inbuffer), caps_header, GST_DP_HEADER_LENGTH);
       
   346   i = GST_DP_HEADER_LENGTH;
       
   347   memcpy (GST_BUFFER_DATA (inbuffer) + i, caps_payload, payload_len);
       
   348   i += payload_len;
       
   349   memcpy (GST_BUFFER_DATA (inbuffer) + i, buf_header, GST_DP_HEADER_LENGTH);
       
   350   i += GST_DP_HEADER_LENGTH;
       
   351   memcpy (GST_BUFFER_DATA (inbuffer) + i, GST_BUFFER_DATA (buffer),
       
   352       GST_BUFFER_SIZE (buffer));
       
   353 
       
   354   gst_caps_unref (caps);
       
   355   gst_buffer_unref (buffer);
       
   356 
       
   357   g_free (caps_header);
       
   358   g_free (caps_payload);
       
   359   g_free (buf_header);
       
   360 
       
   361   /* now push it */
       
   362   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
       
   363   gst_pad_push (mysrcpad, inbuffer);
       
   364 
       
   365   /* our only output buffer is the streamheader buffer */
       
   366   fail_unless_equals_int (g_list_length (buffers), 1);
       
   367   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
       
   368   buffers = g_list_remove (buffers, outbuffer);
       
   369   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
       
   370   fail_unless (GST_BUFFER_FLAG_IS_SET (outbuffer, GST_BUFFER_FLAG_IN_CAPS));
       
   371 
       
   372   padcaps = gst_pad_get_negotiated_caps (myshsinkpad);
       
   373   caps = gst_buffer_get_caps (outbuffer);
       
   374   fail_if (caps == NULL);
       
   375   fail_if (padcaps == NULL);
       
   376   GST_DEBUG ("caps: %" GST_PTR_FORMAT ", padcaps: %" GST_PTR_FORMAT, caps,
       
   377       padcaps);
       
   378   fail_unless (gst_caps_is_equal (padcaps, caps));
       
   379 
       
   380   /* FIXME: get streamheader, compare data with buffer */
       
   381   gst_buffer_unref (outbuffer);
       
   382   gst_caps_unref (padcaps);
       
   383   gst_caps_unref (caps);
       
   384 
       
   385   /* clean up */
       
   386   fail_unless (gst_element_set_state (gdpdepay,
       
   387           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
       
   388 
       
   389   gst_object_unref (srcpad);
       
   390   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
       
   391   g_list_free (buffers);
       
   392   buffers = NULL;
       
   393   ASSERT_OBJECT_REFCOUNT (gdpdepay, "gdpdepay", 1);
       
   394   cleanup_gdpdepay (gdpdepay);
       
   395 
       
   396   gst_dp_packetizer_free (pk);
       
   397 }
       
   398 
       
   399 GST_END_TEST;
       
   400 
       
   401 #endif /* ifndef HAVE_CPU_PPC64 */
       
   402 
       
   403 static Suite *
       
   404 gdpdepay_suite (void)
       
   405 {
       
   406   Suite *s = suite_create ("gdpdepay");
       
   407   TCase *tc_chain = tcase_create ("general");
       
   408 
       
   409   suite_add_tcase (s, tc_chain);
       
   410   tcase_add_test (tc_chain, test_audio_per_byte);
       
   411   tcase_add_test (tc_chain, test_audio_in_one_buffer);
       
   412 #ifndef HAVE_CPU_PPC64          /* Test known to fail on PPC64. See #348114 */
       
   413   tcase_add_test (tc_chain, test_streamheader);
       
   414 #endif
       
   415   return s;
       
   416 }
       
   417 
       
   418 int
       
   419 main (int argc, char **argv)
       
   420 {
       
   421   int nf;
       
   422 
       
   423   Suite *s = gdpdepay_suite ();
       
   424   SRunner *sr = srunner_create (s);
       
   425 
       
   426   gst_check_init (&argc, &argv);
       
   427 
       
   428   srunner_run_all (sr, CK_NORMAL);
       
   429   nf = srunner_ntests_failed (sr);
       
   430   srunner_free (sr);
       
   431 
       
   432   return nf;
       
   433 }