• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2009 Thomas Vander Stichele <thomas at apestaart dot org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include <gst/check/gstcheck.h>
21 #include <gst/audio/audio.h>
22 #include <glib/gstdio.h>
23 
24 static guint16
_get_first_sample(GstSample * sample)25 _get_first_sample (GstSample * sample)
26 {
27   GstAudioInfo info;
28   GstCaps *caps;
29   GstBuffer *buf;
30   GstMapInfo map;
31   guint16 res;
32 
33   fail_unless (sample != NULL, "NULL sample");
34 
35   caps = gst_sample_get_caps (sample);
36   fail_unless (caps != NULL, "sample without caps");
37 
38   buf = gst_sample_get_buffer (sample);
39   GST_DEBUG ("buffer with size=%" G_GSIZE_FORMAT ", caps=%" GST_PTR_FORMAT,
40       gst_buffer_get_size (buf), caps);
41 
42   gst_buffer_map (buf, &map, GST_MAP_READ);
43   /* log buffer details */
44   GST_MEMDUMP ("buffer data from decoder", map.data, map.size);
45 
46   /* make sure it's the format we expect */
47   fail_unless (gst_audio_info_from_caps (&info, caps));
48 
49   fail_unless_equals_int (GST_AUDIO_INFO_WIDTH (&info), 16);
50   fail_unless_equals_int (GST_AUDIO_INFO_DEPTH (&info), 16);
51   fail_unless_equals_int (GST_AUDIO_INFO_RATE (&info), 44100);
52   fail_unless_equals_int (GST_AUDIO_INFO_CHANNELS (&info), 1);
53 
54   if (GST_AUDIO_INFO_IS_LITTLE_ENDIAN (&info))
55     res = GST_READ_UINT16_LE (map.data);
56   else
57     res = GST_READ_UINT16_BE (map.data);
58 
59   gst_buffer_unmap (buf, &map);
60 
61   return res;
62 }
63 
GST_START_TEST(test_decode)64 GST_START_TEST (test_decode)
65 {
66   GstElement *pipeline;
67   GstElement *appsink;
68   GstSample *sample = NULL;
69   guint16 first_sample = 0;
70   guint size = 0;
71   gchar *path =
72       g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL);
73   gchar *pipe_desc =
74       g_strdup_printf
75       ("filesrc location=\"%s\" ! flacparse ! flacdec ! appsink name=sink",
76       path);
77 
78   pipeline = gst_parse_launch (pipe_desc, NULL);
79   fail_unless (pipeline != NULL);
80 
81   g_free (path);
82   g_free (pipe_desc);
83 
84   appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
85   fail_unless (appsink != NULL);
86 
87   gst_element_set_state (pipeline, GST_STATE_PLAYING);
88 
89   do {
90     g_signal_emit_by_name (appsink, "pull-sample", &sample);
91     if (sample == NULL)
92       break;
93     if (first_sample == 0)
94       first_sample = _get_first_sample (sample);
95 
96     size += gst_buffer_get_size (gst_sample_get_buffer (sample));
97 
98     gst_sample_unref (sample);
99     sample = NULL;
100   }
101   while (TRUE);
102 
103   /* audiotestsrc with samplesperbuffer 1024 and 10 num-buffers */
104   fail_unless_equals_int (size, 20480);
105   fail_unless_equals_int (first_sample, 0x066a);
106 
107   gst_element_set_state (pipeline, GST_STATE_NULL);
108   g_object_unref (pipeline);
109   g_object_unref (appsink);
110 }
111 
112 GST_END_TEST;
113 
GST_START_TEST(test_decode_seek_full)114 GST_START_TEST (test_decode_seek_full)
115 {
116   GstElement *pipeline;
117   GstElement *appsink;
118   GstEvent *event;
119   GstSample *sample = NULL;
120   guint16 first_sample = 0;
121   guint size = 0;
122   gchar *path =
123       g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL);
124   gchar *pipe_desc =
125       g_strdup_printf
126       ("filesrc location=\"%s\" ! flacparse ! flacdec ! appsink name=sink",
127       path);
128 
129   pipeline = gst_parse_launch (pipe_desc, NULL);
130   fail_unless (pipeline != NULL);
131 
132   g_free (pipe_desc);
133   g_free (path);
134 
135   appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
136   fail_unless (appsink != NULL);
137 
138   gst_element_set_state (pipeline, GST_STATE_PAUSED);
139   gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
140 
141   /* do a seek that should give us the complete output */
142   event = gst_event_new_seek (1.0, GST_FORMAT_DEFAULT, GST_SEEK_FLAG_FLUSH,
143       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 20480);
144   fail_unless (gst_element_send_event (appsink, event));
145 
146   gst_element_set_state (pipeline, GST_STATE_PLAYING);
147 
148   do {
149     g_signal_emit_by_name (appsink, "pull-sample", &sample);
150     if (sample == NULL)
151       break;
152     if (first_sample == 0)
153       first_sample = _get_first_sample (sample);
154     size += gst_buffer_get_size (gst_sample_get_buffer (sample));
155 
156     gst_sample_unref (sample);
157     sample = NULL;
158   }
159   while (TRUE);
160 
161   /* file was generated with audiotestsrc
162    * with 1024 samplesperbuffer and 10 num-buffers in 16 bit audio */
163   fail_unless_equals_int (size, 20480);
164   fail_unless_equals_int (first_sample, 0x066a);
165 
166   gst_element_set_state (pipeline, GST_STATE_NULL);
167 
168   g_object_unref (pipeline);
169   g_object_unref (appsink);
170 }
171 
172 GST_END_TEST;
173 
GST_START_TEST(test_decode_seek_partial)174 GST_START_TEST (test_decode_seek_partial)
175 {
176   GstElement *pipeline;
177   GstElement *appsink;
178   GstEvent *event;
179   GstSample *sample = NULL;
180   guint size = 0;
181   guint16 first_sample = 0;
182   gchar *path =
183       g_build_filename (GST_TEST_FILES_PATH, "audiotestsrc.flac", NULL);
184   gchar *pipe_desc =
185       g_strdup_printf
186       ("filesrc location=\"%s\" ! flacparse ! flacdec ! appsink name=sink",
187       path);
188 
189   pipeline = gst_parse_launch (pipe_desc, NULL);
190   fail_unless (pipeline != NULL);
191 
192   g_free (path);
193   g_free (pipe_desc);
194 
195   appsink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
196   fail_unless (appsink != NULL);
197 
198   gst_element_set_state (pipeline, GST_STATE_PAUSED);
199   gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
200 
201   /* do a partial seek to get the first 1024 samples or 2048 bytes */
202   event = gst_event_new_seek (1.0, GST_FORMAT_DEFAULT, GST_SEEK_FLAG_FLUSH,
203       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 1024);
204   GST_DEBUG ("seeking");
205   fail_unless (gst_element_send_event (appsink, event));
206   GST_DEBUG ("seeked");
207 
208   gst_element_set_state (pipeline, GST_STATE_PLAYING);
209 
210   do {
211     GST_DEBUG ("pulling sample");
212     g_signal_emit_by_name (appsink, "pull-sample", &sample);
213     GST_DEBUG ("pulled sample %p", sample);
214     if (sample == NULL)
215       break;
216     if (first_sample == 0) {
217       first_sample = _get_first_sample (sample);
218     }
219     size += gst_buffer_get_size (gst_sample_get_buffer (sample));
220 
221     gst_sample_unref (sample);
222     sample = NULL;
223   }
224   while (TRUE);
225 
226   /* allow for sample round-up clipping effect */
227   fail_unless (size == 2048 || size == 2050);
228   fail_unless_equals_int (first_sample, 0x066a);
229 
230   gst_element_set_state (pipeline, GST_STATE_NULL);
231 
232   g_object_unref (pipeline);
233   g_object_unref (appsink);
234 }
235 
236 GST_END_TEST;
237 
238 static Suite *
flacdec_suite(void)239 flacdec_suite (void)
240 {
241   Suite *s = suite_create ("flacdec");
242 
243   TCase *tc_chain = tcase_create ("linear");
244 
245   /* time out after 60s, not the default 3 */
246   tcase_set_timeout (tc_chain, 60);
247 
248   suite_add_tcase (s, tc_chain);
249   tcase_add_test (tc_chain, test_decode);
250   tcase_add_test (tc_chain, test_decode_seek_full);
251   tcase_add_test (tc_chain, test_decode_seek_partial);
252 
253   return s;
254 }
255 
256 GST_CHECK_MAIN (flacdec);
257