1 /* GStreamer
2  *
3  * unit test for mpeg2enc
4  *
5  * Copyright (C) <2006> Mark Nauwelaerts <manauw@skynet.be>
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 
27 /* For ease of programming we use globals to keep refs for our floating
28  * src and sink pads we create; otherwise we always have to do get_pad,
29  * get_peer, and then remove references in every test function */
30 static GstPad *mysrcpad, *mysinkpad;
31 
32 #define VIDEO_CAPS_STRING "video/x-raw, " \
33                            "format = (string) I420, " \
34                            "width = (int) 384, " \
35                            "height = (int) 288, " \
36                            "framerate = (fraction) 25/1"
37 
38 #define MPEG_CAPS_STRING "video/mpeg, " \
39                            "mpegversion = (int) { 1, 2 }, " \
40                            "systemstream = (bool) false, " \
41                            "height = (int) 288, " \
42                            "framerate = (fraction) 25/1"
43 
44 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
45     GST_PAD_SINK,
46     GST_PAD_ALWAYS,
47     GST_STATIC_CAPS (MPEG_CAPS_STRING));
48 
49 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
50     GST_PAD_SRC,
51     GST_PAD_ALWAYS,
52     GST_STATIC_CAPS (VIDEO_CAPS_STRING));
53 
54 
55 /* some global vars, makes it easy as for the ones above */
56 static GMutex mpeg2enc_mutex;
57 static GCond mpeg2enc_cond;
58 static gboolean arrived_eos;
59 
60 static gboolean
test_sink_event(GstPad * pad,GstObject * parent,GstEvent * event)61 test_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
62 {
63 
64   switch (GST_EVENT_TYPE (event)) {
65     case GST_EVENT_EOS:
66       g_mutex_lock (&mpeg2enc_mutex);
67       arrived_eos = TRUE;
68       g_cond_signal (&mpeg2enc_cond);
69       g_mutex_unlock (&mpeg2enc_mutex);
70       break;
71     default:
72       break;
73   }
74 
75   return gst_pad_event_default (pad, parent, event);
76 }
77 
78 static GstElement *
setup_mpeg2enc(void)79 setup_mpeg2enc (void)
80 {
81   GstElement *mpeg2enc;
82 
83   GST_DEBUG ("setup_mpeg2enc");
84   mpeg2enc = gst_check_setup_element ("mpeg2enc");
85   mysrcpad = gst_check_setup_src_pad (mpeg2enc, &srctemplate);
86   mysinkpad = gst_check_setup_sink_pad (mpeg2enc, &sinktemplate);
87   gst_pad_set_active (mysrcpad, TRUE);
88   gst_pad_set_active (mysinkpad, TRUE);
89 
90   /* need to know when we are eos */
91   gst_pad_set_event_function (mysinkpad, test_sink_event);
92 
93   /* and notify the test run */
94   g_mutex_init (&mpeg2enc_mutex);
95   g_cond_init (&mpeg2enc_cond);
96 
97   return mpeg2enc;
98 }
99 
100 static void
cleanup_mpeg2enc(GstElement * mpeg2enc)101 cleanup_mpeg2enc (GstElement * mpeg2enc)
102 {
103   GST_DEBUG ("cleanup_mpeg2enc");
104   gst_element_set_state (mpeg2enc, GST_STATE_NULL);
105 
106   gst_pad_set_active (mysrcpad, FALSE);
107   gst_pad_set_active (mysinkpad, FALSE);
108   gst_check_teardown_src_pad (mpeg2enc);
109   gst_check_teardown_sink_pad (mpeg2enc);
110   gst_check_teardown_element (mpeg2enc);
111 
112   g_mutex_clear (&mpeg2enc_mutex);
113   g_cond_clear (&mpeg2enc_cond);
114 }
115 
GST_START_TEST(test_video_pad)116 GST_START_TEST (test_video_pad)
117 {
118   GstElement *mpeg2enc;
119   GstBuffer *inbuffer, *outbuffer;
120   GstCaps *caps;
121   int i, num_buffers;
122   guint8 data0[] = { 0x00, 0x00, 0x01, 0xb3 };
123 
124 
125   mpeg2enc = setup_mpeg2enc ();
126   fail_unless (gst_element_set_state (mpeg2enc,
127           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
128       "could not set to playing");
129 
130   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
131   gst_check_setup_events_with_stream_id (mysrcpad, mpeg2enc, caps,
132       GST_FORMAT_TIME, "/test/mpeg2enc");
133   gst_caps_unref (caps);
134 
135   /* corresponds to I420 buffer for the size mentioned in the caps */
136   inbuffer = gst_buffer_new_and_alloc (384 * 288 * 3 / 2);
137   /* makes valgrind's memcheck happier */
138   gst_buffer_memset (inbuffer, 0, 0, -1);
139   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
140   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
141   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
142 
143   /* need to force eos and state change to make sure the encoding task ends */
144   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()) == TRUE);
145   /* need to wait a bit to make sure mpeg2enc task digested all this */
146   g_mutex_lock (&mpeg2enc_mutex);
147   while (!arrived_eos)
148     g_cond_wait (&mpeg2enc_cond, &mpeg2enc_mutex);
149   g_mutex_unlock (&mpeg2enc_mutex);
150 
151   num_buffers = g_list_length (buffers);
152   /* well, we do not really know much with mpeg, but at least something ... */
153   fail_unless (num_buffers >= 1);
154 
155   /* clean up buffers */
156   for (i = 0; i < num_buffers; ++i) {
157     outbuffer = GST_BUFFER (buffers->data);
158     fail_if (outbuffer == NULL);
159 
160     switch (i) {
161       case 0:
162         fail_unless (gst_buffer_get_size (outbuffer) >= sizeof (data0));
163         fail_unless (gst_buffer_memcmp (outbuffer, 0, data0,
164                 sizeof (data0)) == 0);
165         break;
166       default:
167         break;
168     }
169     buffers = g_list_remove (buffers, outbuffer);
170 
171     ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
172     gst_buffer_unref (outbuffer);
173     outbuffer = NULL;
174   }
175 
176   cleanup_mpeg2enc (mpeg2enc);
177   g_list_free (buffers);
178   buffers = NULL;
179 }
180 
181 GST_END_TEST;
182 
183 static Suite *
mpeg2enc_suite(void)184 mpeg2enc_suite (void)
185 {
186   Suite *s = suite_create ("mpeg2enc");
187   TCase *tc_chain = tcase_create ("general");
188 
189   suite_add_tcase (s, tc_chain);
190   tcase_add_test (tc_chain, test_video_pad);
191 
192   return s;
193 }
194 
195 GST_CHECK_MAIN (mpeg2enc);
196