|
1 /* GStreamer |
|
2 * |
|
3 * unit test for cddabasesrc |
|
4 * |
|
5 * Copyright (C) <2005> Tim-Philipp Müller <tim centricular 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., 59 Temple Place - Suite 330, |
|
20 * Boston, MA 02111-1307, USA. |
|
21 */ |
|
22 |
|
23 /* TODO: |
|
24 * - test different modes (when seeking to tracks in track mode, buffer |
|
25 * timestamps should start from 0, when seeking to tracks in disc mode, |
|
26 * buffer timestamps should increment, etc.) |
|
27 */ |
|
28 |
|
29 #ifdef HAVE_CONFIG_H |
|
30 #include "config.h" |
|
31 #endif |
|
32 |
|
33 #include <unistd.h> |
|
34 |
|
35 #include <gst/check/gstcheck.h> |
|
36 #include <gst/check/gstbufferstraw.h> |
|
37 |
|
38 #include <gst/cdda/gstcddabasesrc.h> |
|
39 #include <string.h> |
|
40 |
|
41 #define CD_FRAMESIZE_RAW 2352 |
|
42 |
|
43 #define GST_TYPE_CD_FOO_SRC (gst_cd_foo_src_get_type()) |
|
44 #define GST_CD_FOO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CD_FOO_SRC,GstCdFooSrc)) |
|
45 #define GST_CD_FOO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CD_FOO_SRC,GstCdFooSrcClass)) |
|
46 #define GST_IS_CD_FOO_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CD_FOO_SRC)) |
|
47 #define GST_IS_CD_FOO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CD_FOO_SRC)) |
|
48 #define GST_CD_FOO_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CDDA_BASAE_SRC, GstCdFooSrcClass)) |
|
49 |
|
50 typedef struct _GstCdFooSrc GstCdFooSrc; |
|
51 typedef struct _GstCdFooSrcClass GstCdFooSrcClass; |
|
52 |
|
53 |
|
54 /* Neue Heimat (CD 2) */ |
|
55 static GstCddaBaseSrcTrack nh_cd2_tracks[] = { |
|
56 {TRUE, 1, 0, 20664, NULL,}, |
|
57 {TRUE, 2, 20665, 52377, NULL,}, |
|
58 {TRUE, 3, 52378, 84100, NULL,}, |
|
59 {TRUE, 4, 84101, 105401, NULL,}, |
|
60 {TRUE, 5, 105402, 123060, NULL,}, |
|
61 {TRUE, 6, 123061, 146497, NULL,}, |
|
62 {TRUE, 7, 146498, 175693, NULL,}, |
|
63 {TRUE, 8, 175694, 203272, NULL,}, |
|
64 {TRUE, 9, 203273, 217909, NULL,}, |
|
65 {TRUE, 10, 217910, 240938, NULL,}, |
|
66 {TRUE, 11, 240939, 256169, NULL,}, |
|
67 {TRUE, 12, 256170, 282237, NULL,}, |
|
68 {TRUE, 13, 282238, 307606, NULL,}, |
|
69 {TRUE, 14, 307607, 337245, NULL,} |
|
70 }; |
|
71 |
|
72 /* Offspring - Smash */ |
|
73 static GstCddaBaseSrcTrack offspring_tracks[] = { |
|
74 {TRUE, 1, 0, 1924, NULL,}, |
|
75 {TRUE, 2, 1925, 12947, NULL,}, |
|
76 {TRUE, 3, 12948, 29739, NULL,}, |
|
77 {TRUE, 4, 29740, 47202, NULL,}, |
|
78 {TRUE, 5, 47203, 63134, NULL,}, |
|
79 {TRUE, 6, 63135, 77954, NULL,}, |
|
80 {TRUE, 7, 77955, 92789, NULL,}, |
|
81 {TRUE, 8, 92790, 112127, NULL,}, |
|
82 {TRUE, 9, 112128, 124372, NULL,}, |
|
83 {TRUE, 10, 124373, 133574, NULL,}, |
|
84 {TRUE, 11, 133575, 143484, NULL,}, |
|
85 {TRUE, 12, 143485, 149279, NULL,}, |
|
86 {TRUE, 13, 149280, 162357, NULL,}, |
|
87 {TRUE, 14, 162358, 210372, NULL,} |
|
88 }; |
|
89 |
|
90 /* this matches the sample TOC from the DiscIDCalculation |
|
91 * page in the Musicbrainz wiki. It's a tricky one because |
|
92 * it's got a data track as well. */ |
|
93 static GstCddaBaseSrcTrack mb_sample_tracks[] = { |
|
94 {TRUE, 1, 0, 18640, NULL,}, |
|
95 {TRUE, 2, 18641, 34666, NULL,}, |
|
96 {TRUE, 3, 34667, 56349, NULL,}, |
|
97 {TRUE, 4, 56350, 77005, NULL,}, |
|
98 {TRUE, 5, 77006, 106093, NULL,}, |
|
99 {TRUE, 6, 106094, 125728, NULL,}, |
|
100 {TRUE, 7, 125729, 149784, NULL,}, |
|
101 {TRUE, 8, 149785, 168884, NULL,}, |
|
102 {TRUE, 9, 168885, 185909, NULL,}, |
|
103 {TRUE, 10, 185910, 205828, NULL,}, |
|
104 {TRUE, 11, 205829, 230141, NULL,}, |
|
105 {TRUE, 12, 230142, 246658, NULL,}, |
|
106 {TRUE, 13, 246659, 265613, NULL,}, |
|
107 {TRUE, 14, 265614, 289478, NULL,}, |
|
108 {FALSE, 15, 289479, 325731, NULL,} |
|
109 }; |
|
110 |
|
111 /* Nicola Conte - Other Directions (also |
|
112 * tricky due to the extra data track) */ |
|
113 static GstCddaBaseSrcTrack nconte_odir_tracks[] = { |
|
114 {TRUE, 1, 0, 17852, NULL,}, |
|
115 {TRUE, 2, 17853, 39956, NULL,}, |
|
116 {TRUE, 3, 39957, 68449, NULL,}, |
|
117 {TRUE, 4, 68450, 88725, NULL,}, |
|
118 {TRUE, 5, 88726, 106413, NULL,}, |
|
119 {TRUE, 6, 106414, 131966, NULL,}, |
|
120 {TRUE, 7, 131967, 152372, NULL,}, |
|
121 {TRUE, 8, 152373, 168602, NULL,}, |
|
122 {TRUE, 9, 168603, 190348, NULL,}, |
|
123 {TRUE, 10, 190349, 209044, NULL,}, |
|
124 {TRUE, 11, 209045, 235586, NULL,}, |
|
125 {TRUE, 12, 235587, 253830, NULL,}, |
|
126 {TRUE, 13, 253831, 272213, NULL,}, |
|
127 {FALSE, 14, 272214, 332849, NULL,} |
|
128 }; |
|
129 |
|
130 /* Pink Martini - Sympathique (11 track version) */ |
|
131 static GstCddaBaseSrcTrack pm_symp_tracks[] = { |
|
132 {TRUE, 1, 0, 21667, NULL,}, |
|
133 {TRUE, 2, 21668, 49576, NULL,}, |
|
134 {TRUE, 3, 49577, 62397, NULL,}, |
|
135 {TRUE, 4, 62398, 81087, NULL,}, |
|
136 {TRUE, 5, 81088, 106595, NULL,}, |
|
137 {TRUE, 6, 106596, 122012, NULL,}, |
|
138 {TRUE, 7, 122013, 138469, NULL,}, |
|
139 {TRUE, 8, 138470, 157306, NULL,}, |
|
140 {TRUE, 9, 157307, 179635, NULL,}, |
|
141 {TRUE, 10, 179636, 203673, NULL,}, |
|
142 {TRUE, 11, 203674, 213645, NULL,} |
|
143 }; |
|
144 |
|
145 #define NUM_TEST_DISCS 5 |
|
146 |
|
147 struct _test_disc |
|
148 { |
|
149 GstCddaBaseSrcTrack *tracks; |
|
150 guint num_tracks; |
|
151 guint32 cddb_discid; |
|
152 const gchar *musicbrainz_discid; |
|
153 }; |
|
154 |
|
155 /* FIXME: now we just need to find out how to treat |
|
156 * data tracks for the cddb id calculation .... */ |
|
157 static struct _test_disc test_discs[NUM_TEST_DISCS] = { |
|
158 {nh_cd2_tracks, G_N_ELEMENTS (nh_cd2_tracks), 0xae11900e, |
|
159 NULL}, |
|
160 {mb_sample_tracks, G_N_ELEMENTS (mb_sample_tracks), 0x00000000, |
|
161 "MUtMmKN402WPj3_VFsgUelxpc8U-"}, |
|
162 {offspring_tracks, G_N_ELEMENTS (offspring_tracks), 0xc20af40e, |
|
163 "ahg7JUcfR3vCYBphSDIogOOWrr0-"}, |
|
164 {nconte_odir_tracks, G_N_ELEMENTS (nconte_odir_tracks), 0x00000000, |
|
165 /* hKx_PejjG47X161ND_Sh0HyqaS0- according to libmusicbrainz, but that's |
|
166 * wrong according to the wiki docs (or not?) (neither discid is listed) */ |
|
167 "fboaOQtfqwENv8WyXa9tRyvyUbQ-"}, |
|
168 {pm_symp_tracks, G_N_ELEMENTS (pm_symp_tracks), 0xa00b200b, |
|
169 "iP0DOLdr4vt_IfKSIXoRUR.q_Wc-"} |
|
170 }; |
|
171 |
|
172 struct _GstCdFooSrc |
|
173 { |
|
174 GstCddaBaseSrc cddabasesrc; |
|
175 |
|
176 struct _test_disc *cur_test; |
|
177 guint cur_disc; |
|
178 }; |
|
179 |
|
180 struct _GstCdFooSrcClass |
|
181 { |
|
182 GstCddaBaseSrcClass parent_class; |
|
183 }; |
|
184 |
|
185 GST_BOILERPLATE (GstCdFooSrc, gst_cd_foo_src, GstCddaBaseSrc, |
|
186 GST_TYPE_CDDA_BASE_SRC); |
|
187 |
|
188 static GstBuffer *gst_cd_foo_src_read_sector (GstCddaBaseSrc * src, |
|
189 gint sector); |
|
190 static gboolean gst_cd_foo_src_open (GstCddaBaseSrc * src, |
|
191 const gchar * device); |
|
192 static void gst_cd_foo_src_close (GstCddaBaseSrc * src); |
|
193 |
|
194 static const GstElementDetails cdfoo_details = |
|
195 GST_ELEMENT_DETAILS ("CD Audio (cdda) Source, FooBar", |
|
196 "Source/File", |
|
197 "Read audio from CD", |
|
198 "Foo Bar <foo@bar.com>"); |
|
199 |
|
200 static void |
|
201 gst_cd_foo_src_base_init (gpointer g_class) |
|
202 { |
|
203 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); |
|
204 |
|
205 gst_element_class_set_details (element_class, &cdfoo_details); |
|
206 } |
|
207 |
|
208 static void |
|
209 gst_cd_foo_src_init (GstCdFooSrc * src, GstCdFooSrcClass * klass) |
|
210 { |
|
211 src->cur_disc = 0; |
|
212 } |
|
213 |
|
214 static void |
|
215 gst_cd_foo_src_class_init (GstCdFooSrcClass * klass) |
|
216 { |
|
217 GstCddaBaseSrcClass *cddabasesrc_class = GST_CDDA_BASE_SRC_CLASS (klass); |
|
218 |
|
219 cddabasesrc_class->open = gst_cd_foo_src_open; |
|
220 cddabasesrc_class->close = gst_cd_foo_src_close; |
|
221 cddabasesrc_class->read_sector = gst_cd_foo_src_read_sector; |
|
222 } |
|
223 |
|
224 static gboolean |
|
225 gst_cd_foo_src_open (GstCddaBaseSrc * cddabasesrc, const gchar * device) |
|
226 { |
|
227 GstCddaBaseSrcTrack *tracks; |
|
228 GstCdFooSrc *src; |
|
229 gint i; |
|
230 |
|
231 src = GST_CD_FOO_SRC (cddabasesrc); |
|
232 |
|
233 /* if this fails, the test is wrong */ |
|
234 g_assert (src->cur_disc < NUM_TEST_DISCS); |
|
235 |
|
236 src->cur_test = &test_discs[src->cur_disc]; |
|
237 |
|
238 /* add tracks */ |
|
239 tracks = src->cur_test->tracks; |
|
240 for (i = 0; i < src->cur_test->num_tracks; ++i) { |
|
241 gst_cdda_base_src_add_track (GST_CDDA_BASE_SRC (src), &tracks[i]); |
|
242 } |
|
243 |
|
244 return TRUE; |
|
245 } |
|
246 |
|
247 static void |
|
248 gst_cd_foo_src_close (GstCddaBaseSrc * cddabasesrc) |
|
249 { |
|
250 GstCdFooSrc *src = GST_CD_FOO_SRC (cddabasesrc); |
|
251 |
|
252 if (src->cur_test->cddb_discid != 0) { |
|
253 g_assert (cddabasesrc->discid == src->cur_test->cddb_discid); |
|
254 } |
|
255 |
|
256 if (src->cur_test->musicbrainz_discid != NULL) { |
|
257 g_assert (g_str_equal (cddabasesrc->mb_discid, |
|
258 src->cur_test->musicbrainz_discid)); |
|
259 } |
|
260 } |
|
261 |
|
262 static GstBuffer * |
|
263 gst_cd_foo_src_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector) |
|
264 { |
|
265 GstBuffer *buf; |
|
266 |
|
267 buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW); |
|
268 memset (GST_BUFFER_DATA (buf), 0, CD_FRAMESIZE_RAW); |
|
269 |
|
270 return buf; |
|
271 } |
|
272 |
|
273 GST_START_TEST (test_discid_calculations) |
|
274 { |
|
275 GstElement *foosrc; |
|
276 gint i; |
|
277 |
|
278 fail_unless (gst_element_register (NULL, "cdfoosrc", GST_RANK_SECONDARY, |
|
279 GST_TYPE_CD_FOO_SRC)); |
|
280 |
|
281 foosrc = gst_element_factory_make ("cdfoosrc", "cdfoosrc"); |
|
282 |
|
283 for (i = 0; i < G_N_ELEMENTS (test_discs); ++i) { |
|
284 GST_LOG ("Testing disc layout %u ...", i); |
|
285 GST_CD_FOO_SRC (foosrc)->cur_disc = i; |
|
286 gst_element_set_state (foosrc, GST_STATE_PLAYING); |
|
287 gst_element_get_state (foosrc, NULL, NULL, -1); |
|
288 gst_element_set_state (foosrc, GST_STATE_NULL); |
|
289 } |
|
290 |
|
291 gst_object_unref (foosrc); |
|
292 |
|
293 gst_task_cleanup_all (); |
|
294 } |
|
295 |
|
296 GST_END_TEST; |
|
297 |
|
298 GST_START_TEST (test_buffer_timestamps) |
|
299 { |
|
300 GstElement *foosrc, *pipeline, *fakesink; |
|
301 GstClockTime prev_ts, prev_duration, ts; |
|
302 GstPad *sinkpad; |
|
303 gint i; |
|
304 |
|
305 fail_unless (gst_element_register (NULL, "cdfoosrc", GST_RANK_SECONDARY, |
|
306 GST_TYPE_CD_FOO_SRC)); |
|
307 |
|
308 pipeline = gst_pipeline_new ("pipeline"); |
|
309 foosrc = gst_element_factory_make ("cdfoosrc", "cdfoosrc"); |
|
310 fakesink = gst_element_factory_make ("fakesink", "fakesink"); |
|
311 gst_bin_add_many (GST_BIN (pipeline), foosrc, fakesink, NULL); |
|
312 fail_unless (gst_element_link (foosrc, fakesink)); |
|
313 sinkpad = gst_element_get_pad (fakesink, "sink"); |
|
314 |
|
315 GST_CD_FOO_SRC (foosrc)->cur_disc = 0; |
|
316 |
|
317 gst_buffer_straw_start_pipeline (pipeline, sinkpad); |
|
318 |
|
319 prev_ts = GST_CLOCK_TIME_NONE; |
|
320 prev_duration = GST_CLOCK_TIME_NONE; |
|
321 |
|
322 for (i = 0; i < 100; ++i) { |
|
323 GstBuffer *buf; |
|
324 |
|
325 buf = gst_buffer_straw_get_buffer (pipeline, sinkpad); |
|
326 GST_LOG ("buffer, ts=%" GST_TIME_FORMAT ", dur=%" GST_TIME_FORMAT, |
|
327 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), |
|
328 GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); |
|
329 ts = GST_BUFFER_TIMESTAMP (buf); |
|
330 fail_unless (GST_CLOCK_TIME_IS_VALID (ts)); |
|
331 fail_unless (GST_BUFFER_DURATION_IS_VALID (buf)); |
|
332 if (i > 0) { |
|
333 fail_unless (GST_CLOCK_TIME_IS_VALID (prev_ts)); |
|
334 fail_unless (GST_CLOCK_TIME_IS_VALID (prev_duration)); |
|
335 fail_unless ((prev_ts + prev_duration) == ts); |
|
336 } |
|
337 prev_ts = ts; |
|
338 prev_duration = GST_BUFFER_DURATION (buf); |
|
339 gst_buffer_unref (buf); |
|
340 } |
|
341 |
|
342 gst_buffer_straw_stop_pipeline (pipeline, sinkpad); |
|
343 |
|
344 gst_task_cleanup_all (); |
|
345 gst_object_unref (pipeline); |
|
346 gst_object_unref (sinkpad); |
|
347 } |
|
348 |
|
349 GST_END_TEST; |
|
350 |
|
351 static Suite * |
|
352 cddabasesrc_suite (void) |
|
353 { |
|
354 Suite *s = suite_create ("cddabasesrc"); |
|
355 TCase *tc_chain = tcase_create ("general"); |
|
356 |
|
357 suite_add_tcase (s, tc_chain); |
|
358 tcase_add_test (tc_chain, test_discid_calculations); |
|
359 tcase_add_test (tc_chain, test_buffer_timestamps); |
|
360 |
|
361 return s; |
|
362 } |
|
363 |
|
364 GST_CHECK_MAIN (cddabasesrc) |