tests: videorate: remove obsolete color-matrix caps field
[platform/upstream/gstreamer.git] / tests / check / elements / vorbistag.c
1 /* GStreamer
2  *
3  * unit test for vorbisdec
4  *
5  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
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 #include <unistd.h>
24 #include <glib.h>
25
26 #include <vorbis/codec.h>
27 #include <vorbis/vorbisenc.h>
28
29 #include <gst/gsttagsetter.h>
30 #include <gst/check/gstcheck.h>
31
32 /* a valid first header packet */
33 static guchar identification_header[30] = {
34   1,                            /* packet_type */
35   'v', 'o', 'r', 'b', 'i', 's',
36   0, 0, 0, 0,                   /* vorbis_version */
37   2,                            /* audio_channels */
38   0x44, 0xac, 0, 0,             /* sample_rate */
39   0xff, 0xff, 0xff, 0xff,       /* bitrate_maximum */
40   0x00, 0xee, 0x02, 0x00,       /* bitrate_nominal */
41   0xff, 0xff, 0xff, 0xff,       /* bitrate_minimum */
42   0xb8,                         /* blocksize_0, blocksize_1 */
43   0x01                          /* framing_flag */
44 };
45
46 static guchar artist_comment_header[] = {
47   3,                            /* packet_type */
48   'v', 'o', 'r', 'b', 'i', 's',
49   2, 0, 0, 0,                   /* vendor_length */
50   'm', 'e',
51   1, 0, 0, 0,                   /* user_comment_list_length */
52   9, 0, 0, 0,                   /* length comment[0] */
53   'A', 'R', 'T', 'I', 'S', 'T', '=', 'm', 'e',
54   0x01,                         /* framing bit */
55 };
56
57 static guchar title_comment_header[] = {
58   3,                            /* packet_type */
59   'v', 'o', 'r', 'b', 'i', 's',
60   2, 0, 0, 0,                   /* vendor_length */
61   'm', 'e',
62   1, 0, 0, 0,                   /* user_comment_list_length */
63   12, 0, 0, 0,                  /* length comment[0] */
64   'T', 'I', 'T', 'L', 'E', '=', 'f', 'o', 'o', 'b', 'a', 'r',
65   0x01,                         /* framing bit */
66 };
67
68 static guchar empty_comment_header[] = {
69   3,                            /* packet_type */
70   'v', 'o', 'r', 'b', 'i', 's',
71   2, 0, 0, 0,                   /* vendor_length */
72   'm', 'e',
73   0, 0, 0, 0,                   /* user_comment_list_length */
74   0x01,                         /* framing bit */
75 };
76
77
78 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
79     GST_PAD_SINK,
80     GST_PAD_ALWAYS,
81     GST_STATIC_CAPS_ANY);
82 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
83     GST_PAD_SRC,
84     GST_PAD_ALWAYS,
85     GST_STATIC_CAPS_ANY);
86
87 static GstPad *mysrcpad, *mysinkpad;
88 static GAsyncQueue *pending_buffers;
89 static gulong id;
90
91
92 static GstElement *
93 setup_vorbistag (void)
94 {
95   GstElement *vorbistag;
96
97   GST_DEBUG ("setup_vorbistag");
98   vorbistag = gst_check_setup_element ("vorbistag");
99   mysrcpad = gst_check_setup_src_pad (vorbistag, &srctemplate);
100   mysinkpad = gst_check_setup_sink_pad (vorbistag, &sinktemplate);
101   gst_pad_set_active (mysrcpad, TRUE);
102   gst_pad_set_active (mysinkpad, TRUE);
103
104   return vorbistag;
105 }
106
107 static void
108 cleanup_vorbistag (GstElement * vorbistag)
109 {
110   GST_DEBUG ("cleanup_vorbistag");
111   gst_element_set_state (vorbistag, GST_STATE_NULL);
112
113   gst_pad_set_active (mysrcpad, FALSE);
114   gst_pad_set_active (mysinkpad, FALSE);
115   gst_check_teardown_src_pad (vorbistag);
116   gst_check_teardown_sink_pad (vorbistag);
117   gst_check_teardown_element (vorbistag);
118 }
119
120
121 static GstPadProbeReturn
122 buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
123 {
124   GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
125
126   g_async_queue_push (pending_buffers, gst_buffer_ref (buffer));
127
128   return GST_PAD_PROBE_OK;
129 }
130
131 static void
132 start_pipeline (GstElement * element)
133 {
134   id = gst_pad_add_probe (mysinkpad, GST_PAD_PROBE_TYPE_BUFFER,
135       (GstPadProbeCallback) buffer_probe, NULL, NULL);
136
137   pending_buffers = g_async_queue_new ();
138   gst_element_set_state (element, GST_STATE_PLAYING);
139 }
140
141 static GstBuffer *
142 get_buffer (void)
143 {
144   return GST_BUFFER (g_async_queue_pop (pending_buffers));
145 }
146
147 static void
148 stop_pipeline (GstElement * element)
149 {
150   GstBuffer *buf;
151
152   while ((buf = g_async_queue_try_pop (pending_buffers)))
153     gst_buffer_unref (buf);
154
155   gst_pad_remove_probe (mysinkpad, id);
156   id = 0;
157
158   gst_element_set_state (element, GST_STATE_NULL);
159
160   while ((buf = g_async_queue_try_pop (pending_buffers)))
161     gst_buffer_unref (buf);
162
163   g_async_queue_unref (pending_buffers);
164   pending_buffers = NULL;
165 }
166
167 static void
168 compare_buffer (GstBuffer * buf, const guint8 * data, gsize size)
169 {
170   GstMapInfo map;
171
172   gst_buffer_map (buf, &map, GST_MAP_READ);
173   fail_unless_equals_int (map.size, size);
174   fail_unless_equals_int (memcmp (map.data, data, size), 0);
175   gst_buffer_unmap (buf, &map);
176 }
177
178 static vorbis_comment vc;
179 static vorbis_dsp_state vd;
180 static vorbis_info vi;
181 static vorbis_block vb;
182
183 static GstBuffer *
184 _create_codebook_header_buffer (void)
185 {
186   GstBuffer *buffer;
187   ogg_packet header;
188   ogg_packet header_comm;
189   ogg_packet header_code;
190
191   vorbis_info_init (&vi);
192   vorbis_encode_setup_vbr (&vi, 1, 44000, 0.5);
193   vorbis_encode_setup_init (&vi);
194   vorbis_analysis_init (&vd, &vi);
195   vorbis_block_init (&vd, &vb);
196   vorbis_comment_init (&vc);
197   vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code);
198
199   buffer = gst_buffer_new_and_alloc (header_code.bytes);
200   gst_buffer_fill (buffer, 0, header_code.packet, header_code.bytes);
201
202   return buffer;
203 }
204
205 static GstBuffer *
206 _create_audio_buffer (void)
207 {
208   GstBuffer *buffer;
209   ogg_packet packet;
210   float **vorbis_buffer G_GNUC_UNUSED;
211
212   vorbis_buffer = vorbis_analysis_buffer (&vd, 0);
213   vorbis_analysis_wrote (&vd, 0);
214   vorbis_analysis_blockout (&vd, &vb);
215   vorbis_analysis (&vb, NULL);
216   vorbis_bitrate_addblock (&vb);
217   vorbis_bitrate_flushpacket (&vd, &packet);
218   buffer = gst_buffer_new_and_alloc (packet.bytes);
219   gst_buffer_fill (buffer, 0, packet.packet, packet.bytes);
220   GST_DEBUG ("%p %d", packet.packet, packet.bytes);
221
222   vorbis_comment_clear (&vc);
223   vorbis_block_clear (&vb);
224   vorbis_dsp_clear (&vd);
225   vorbis_info_clear (&vi);
226
227   return buffer;
228 }
229
230
231 GST_START_TEST (test_empty_tags_set)
232 {
233   GstTagList *tags;
234   GstElement *vorbistag;
235   GstBuffer *inbuffer, *outbuffer;
236
237   vorbistag = setup_vorbistag ();
238
239   tags = gst_tag_list_new_empty ();
240   gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, "foobar", NULL);
241   gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
242       GST_TAG_MERGE_REPLACE);
243   gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
244       GST_TAG_MERGE_KEEP_ALL);
245   gst_tag_list_free (tags);
246
247   start_pipeline (vorbistag);
248
249   /* send identification header */
250   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
251   gst_buffer_fill (inbuffer, 0, identification_header,
252       sizeof (identification_header));
253   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
254
255   /* send empty comment buffer */
256   inbuffer = gst_buffer_new_and_alloc (sizeof (empty_comment_header));
257   gst_buffer_fill (inbuffer, 0, empty_comment_header,
258       sizeof (empty_comment_header));
259   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
260
261   /* send minimal codebook header and audio packers */
262   inbuffer = _create_codebook_header_buffer ();
263   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
264   inbuffer = _create_audio_buffer ();
265   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
266
267
268   /* check identification header is unchanged */
269   outbuffer = get_buffer ();
270   compare_buffer (outbuffer, identification_header,
271       sizeof (identification_header));
272   gst_buffer_unref (outbuffer);
273
274   /* check comment header is correct */
275   outbuffer = get_buffer ();
276   compare_buffer (outbuffer, title_comment_header,
277       sizeof (title_comment_header));
278   gst_buffer_unref (outbuffer);
279
280   stop_pipeline (vorbistag);
281   cleanup_vorbistag (vorbistag);
282 }
283
284 GST_END_TEST;
285
286
287 GST_START_TEST (test_filled_tags_unset)
288 {
289   GstTagList *tags;
290   GstElement *vorbistag;
291   GstBuffer *inbuffer, *outbuffer;
292
293   vorbistag = setup_vorbistag ();
294
295   tags = gst_tag_list_new_empty ();
296   gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
297       GST_TAG_MERGE_REPLACE);
298   gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
299       GST_TAG_MERGE_KEEP_ALL);
300   gst_tag_list_free (tags);
301
302   start_pipeline (vorbistag);
303
304   /* send identification header */
305   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
306   gst_buffer_fill (inbuffer, 0, identification_header,
307       sizeof (identification_header));
308   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
309
310   /* send empty comment buffer */
311   inbuffer = gst_buffer_new_and_alloc (sizeof (title_comment_header));
312   gst_buffer_fill (inbuffer, 0, title_comment_header,
313       sizeof (title_comment_header));
314   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
315
316   /* send minimal codebook header and audio packers */
317   inbuffer = _create_codebook_header_buffer ();
318   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
319   inbuffer = _create_audio_buffer ();
320   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
321
322
323   /* check identification header is unchanged */
324   outbuffer = get_buffer ();
325   compare_buffer (outbuffer, identification_header,
326       sizeof (identification_header));
327   gst_buffer_unref (outbuffer);
328
329   /* check comment header is correct */
330   outbuffer = get_buffer ();
331   compare_buffer (outbuffer, empty_comment_header,
332       sizeof (empty_comment_header));
333   gst_buffer_unref (outbuffer);
334
335   stop_pipeline (vorbistag);
336   cleanup_vorbistag (vorbistag);
337 }
338
339 GST_END_TEST;
340
341
342 GST_START_TEST (test_filled_tags_change)
343 {
344   GstTagList *tags;
345   GstElement *vorbistag;
346   GstBuffer *inbuffer, *outbuffer;
347
348   vorbistag = setup_vorbistag ();
349
350   tags = gst_tag_list_new_empty ();
351   gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, "foobar", NULL);
352   gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
353       GST_TAG_MERGE_REPLACE);
354   gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
355       GST_TAG_MERGE_KEEP_ALL);
356   gst_tag_list_free (tags);
357
358   start_pipeline (vorbistag);
359
360   /* send identification header */
361   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
362   gst_buffer_fill (inbuffer, 0, identification_header,
363       sizeof (identification_header));
364   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
365
366   /* send empty comment buffer */
367   inbuffer = gst_buffer_new_and_alloc (sizeof (artist_comment_header));
368   gst_buffer_fill (inbuffer, 0, artist_comment_header,
369       sizeof (artist_comment_header));
370   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
371
372   /* send minimal codebook header and audio packers */
373   inbuffer = _create_codebook_header_buffer ();
374   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
375   inbuffer = _create_audio_buffer ();
376   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
377
378
379   /* check identification header is unchanged */
380   outbuffer = get_buffer ();
381   compare_buffer (outbuffer, identification_header,
382       sizeof (identification_header));
383   gst_buffer_unref (outbuffer);
384
385   /* check comment header is correct */
386   outbuffer = get_buffer ();
387   compare_buffer (outbuffer, title_comment_header,
388       sizeof (title_comment_header));
389   gst_buffer_unref (outbuffer);
390
391   stop_pipeline (vorbistag);
392   cleanup_vorbistag (vorbistag);
393 }
394
395 GST_END_TEST;
396
397
398
399 static Suite *
400 vorbistag_suite (void)
401 {
402   Suite *s = suite_create ("vorbistag");
403   TCase *tc_chain = tcase_create ("general");
404
405   suite_add_tcase (s, tc_chain);
406   tcase_add_test (tc_chain, test_empty_tags_set);
407   tcase_add_test (tc_chain, test_filled_tags_unset);
408   tcase_add_test (tc_chain, test_filled_tags_change);
409
410   return s;
411 }
412
413 GST_CHECK_MAIN (vorbistag)