1 /* GStreamer
2  *
3  * unit test for faad
4  *
5  * Copyright (C) <2009> Mark Nauwelaerts <mnauw@users.sf.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include <unistd.h>
24 
25 #include <gst/check/gstcheck.h>
26 #include <gst/audio/audio.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;
32 
33 #define AUDIO_CAPS_STRING "audio/x-raw, " \
34                            "format = (string) " GST_AUDIO_NE (S16) ", " \
35                            "rate = (int) 48000, " \
36                            "channels = (int) 2, " \
37                            "channel-mask = (bitmask) 3"
38 
39 #define AAC_CAPS_STRING "audio/mpeg, " \
40                           "mpegversion = (int) 4, " \
41                           "rate = (int) 48000, " \
42                           "channels = (int) 2, " \
43                           "framed = (boolean) true "
44 
45 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
46     GST_PAD_SINK,
47     GST_PAD_ALWAYS,
48     GST_STATIC_CAPS (AUDIO_CAPS_STRING));
49 
50 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
51     GST_PAD_SRC,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS (AAC_CAPS_STRING));
54 
55 
56 static GstElement *
setup_faad(void)57 setup_faad (void)
58 {
59   GstElement *faad;
60 
61   GST_DEBUG ("setup_faad");
62   faad = gst_check_setup_element ("faad");
63   mysrcpad = gst_check_setup_src_pad (faad, &srctemplate);
64   mysinkpad = gst_check_setup_sink_pad (faad, &sinktemplate);
65   gst_pad_set_active (mysrcpad, TRUE);
66   gst_pad_set_active (mysinkpad, TRUE);
67 
68   return faad;
69 }
70 
71 static void
cleanup_faad(GstElement * faad)72 cleanup_faad (GstElement * faad)
73 {
74   GST_DEBUG ("cleanup_faad");
75   gst_element_set_state (faad, GST_STATE_NULL);
76 
77   gst_pad_set_active (mysrcpad, FALSE);
78   gst_pad_set_active (mysinkpad, FALSE);
79   gst_check_teardown_src_pad (faad);
80   gst_check_teardown_sink_pad (faad);
81   gst_check_teardown_element (faad);
82 }
83 
84 static void
do_test(GstBuffer * inbuffer,GstCaps * caps)85 do_test (GstBuffer * inbuffer, GstCaps * caps)
86 {
87   GstElement *faad;
88   GstBuffer *outbuffer;
89   gint i, num_buffers;
90   const gint nbuffers = 2;
91 
92   faad = setup_faad ();
93   fail_unless (gst_element_set_state (faad,
94           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
95       "could not set to playing");
96 
97   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
98   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
99 
100   gst_check_setup_events (mysrcpad, faad, caps, GST_FORMAT_TIME);
101 
102   /* need to push twice to get faad output */
103   gst_buffer_ref (inbuffer);
104   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
105   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
106 
107   /* send eos to have all flushed if needed */
108   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()) == TRUE);
109 
110   num_buffers = g_list_length (buffers);
111   fail_unless (num_buffers >= nbuffers - 1);
112 
113   /* clean up buffers */
114   for (i = 0; i < num_buffers; ++i) {
115     gint size;
116 
117     outbuffer = GST_BUFFER (buffers->data);
118     fail_if (outbuffer == NULL);
119 
120     size = gst_buffer_get_size (outbuffer);
121 
122     /* 2 16-bit channels */
123     fail_unless (size == 1024 * 2 * 2);
124 
125     buffers = g_list_remove (buffers, outbuffer);
126 
127     ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
128     gst_buffer_unref (outbuffer);
129     outbuffer = NULL;
130   }
131 
132   cleanup_faad (faad);
133   g_list_free (buffers);
134   buffers = NULL;
135 }
136 
137 static guint8 raw_data_block[] = {
138   0x21, 0x1b, 0x80, 0x00, 0x7d, 0xe0, 0x00, 0x3e, 0xf1, 0xe7
139 };
140 
141 static guint8 adts_header[] = {
142   0xff, 0xf8, 0x4c, 0x80, 0x02, 0x7f, 0xfc, 0x04, 0x40
143 };
144 
145 static guint8 codec_data[] = {
146   0x11, 0x90
147 };
148 
GST_START_TEST(test_adts)149 GST_START_TEST (test_adts)
150 {
151   gint size;
152   GstBuffer *buf, *header_buf;
153   GstCaps *caps;
154 
155   size = sizeof (adts_header);
156   header_buf = gst_buffer_new_and_alloc (size);
157   gst_buffer_fill (header_buf, 0, adts_header, size);
158 
159   size = sizeof (raw_data_block);
160   buf = gst_buffer_new_and_alloc (size);
161   gst_buffer_fill (buf, 0, raw_data_block, size);
162 
163   buf = gst_buffer_append (header_buf, buf);
164   caps = gst_caps_from_string (AAC_CAPS_STRING);
165   gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "adts", NULL);
166   do_test (buf, caps);
167   gst_caps_unref (caps);
168 }
169 
170 GST_END_TEST;
171 
GST_START_TEST(test_raw)172 GST_START_TEST (test_raw)
173 {
174   gint size;
175   GstBuffer *buf, *codec_buf;
176   GstCaps *caps;
177 
178   size = sizeof (codec_data);
179   codec_buf = gst_buffer_new_and_alloc (size);
180   gst_buffer_fill (codec_buf, 0, codec_data, size);
181 
182   size = sizeof (raw_data_block);
183   buf = gst_buffer_new_and_alloc (size);
184   gst_buffer_fill (buf, 0, raw_data_block, size);
185   caps = gst_caps_from_string (AAC_CAPS_STRING);
186   gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "raw",
187       "codec_data", GST_TYPE_BUFFER, codec_buf, NULL);
188   gst_buffer_unref (codec_buf);
189 
190   do_test (buf, caps);
191   gst_caps_unref (caps);
192 }
193 
194 GST_END_TEST;
195 
196 static Suite *
faad_suite(void)197 faad_suite (void)
198 {
199   Suite *s = suite_create ("faad");
200   TCase *tc_chain = tcase_create ("general");
201 
202   suite_add_tcase (s, tc_chain);
203   tcase_add_test (tc_chain, test_adts);
204   tcase_add_test (tc_chain, test_raw);
205 
206   return s;
207 }
208 
209 GST_CHECK_MAIN (faad);
210