1 /* GStreamer
2 * Copyright (C) 2019 Yeongjin Jeong <yeongjin.jeong@navercorp.com>
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/check/gstharness.h>
22
GST_START_TEST(test_encode_simple)23 GST_START_TEST (test_encode_simple)
24 {
25 GstHarness *h;
26 GstCaps *outcaps, *caps;
27 gint i = 0;
28
29 h = gst_harness_new_parse ("svthevcenc speed=9 bitrate=1000 ! h265parse");
30
31 gst_harness_add_src_parse (h, "videotestsrc is-live=true ! "
32 "capsfilter caps=\"video/x-raw,format=I420,width=320,height=240,framerate=25/1\"",
33 TRUE);
34
35 /* Push 25 buffers into the encoder */
36 fail_unless_equals_int (GST_FLOW_OK,
37 gst_harness_src_crank_and_push_many (h, 25, 25));
38
39 /* EOS will cause the remaining buffers to be drained */
40 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
41 fail_unless_equals_int (gst_harness_buffers_received (h), 25);
42
43 outcaps =
44 gst_caps_from_string
45 ("video/x-h265,width=(int)320,height=(int)240,framerate=(fraction)25/1");
46
47 caps = gst_pad_get_current_caps (h->sinkpad);
48 fail_unless (caps != NULL);
49 fail_unless (gst_caps_can_intersect (caps, outcaps));
50
51 for (i = 0; i < 25; i++) {
52 GstBuffer *buffer = gst_harness_pull (h);
53
54 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer),
55 gst_util_uint64_scale (1, GST_SECOND, 25));
56
57 gst_buffer_unref (buffer);
58 }
59 gst_caps_unref (outcaps);
60 gst_caps_unref (caps);
61
62 gst_harness_teardown (h);
63 }
64
65 GST_END_TEST;
66
GST_START_TEST(test_reuse)67 GST_START_TEST (test_reuse)
68 {
69 GstHarness *h;
70 GstCaps *srccaps, *outcaps, *caps;
71 GstBuffer *in_buf = NULL;
72 GstFlowReturn ret;
73 GstSegment seg;
74 gint loop, i;
75
76 h = gst_harness_new_parse ("svthevcenc speed=9 bitrate=1000");
77
78 srccaps =
79 gst_caps_from_string
80 ("video/x-raw,format=I420,width=(int)320,height=(int)240,framerate=(fraction)25/1");
81 outcaps =
82 gst_caps_from_string
83 ("video/x-h265,width=(int)320,height=(int)240,framerate=(fraction)25/1");
84
85 in_buf = gst_buffer_new_and_alloc ((320 * 240) * 3 / 2);
86 gst_buffer_memset (in_buf, 0, 0, -1);
87
88 GST_BUFFER_DURATION (in_buf) = gst_util_uint64_scale (1, GST_SECOND, 25);
89 GST_BUFFER_DTS (in_buf) = GST_CLOCK_TIME_NONE;
90
91 gst_segment_init (&seg, GST_FORMAT_TIME);
92
93 for (loop = 0; loop < 2; loop++) {
94 gst_harness_play (h);
95
96 fail_unless (gst_harness_push_event (h,
97 gst_event_new_stream_start ("test")));
98 fail_unless (gst_harness_push_event (h, gst_event_new_caps (srccaps)));
99 fail_unless (gst_harness_push_event (h, gst_event_new_segment (&seg)));
100
101 for (i = 0; i < 25; i++) {
102 GST_BUFFER_PTS (in_buf) = gst_util_uint64_scale (i, GST_SECOND, 25);
103
104 ret = gst_harness_push (h, gst_buffer_ref (in_buf));
105 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
106 gst_flow_get_name (ret));
107 }
108
109 /* EOS will cause the remaining buffers to be drained */
110 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
111 fail_unless_equals_int (gst_harness_buffers_received (h), (loop + 1) * 25);
112
113 caps = gst_pad_get_current_caps (h->sinkpad);
114 fail_unless (caps != NULL);
115 fail_unless (gst_caps_can_intersect (caps, outcaps));
116
117 for (i = 0; i < 25; i++) {
118 GstBuffer *buffer = gst_harness_pull (h);
119
120 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer),
121 gst_util_uint64_scale (1, GST_SECOND, 25));
122
123 gst_buffer_unref (buffer);
124 }
125 gst_caps_unref (caps);
126
127 ASSERT_SET_STATE (h->element, GST_STATE_READY, GST_STATE_CHANGE_SUCCESS);
128 }
129 gst_caps_unref (srccaps);
130 gst_caps_unref (outcaps);
131 gst_buffer_unref (in_buf);
132
133 gst_harness_teardown (h);
134 }
135
136 GST_END_TEST;
137
GST_START_TEST(test_no_encoding)138 GST_START_TEST (test_no_encoding)
139 {
140 GstHarness *h;
141 GstCaps *caps;
142 GstEvent *event;
143
144 h = gst_harness_new_parse ("svthevcenc");
145 fail_unless (h != NULL);
146
147 gst_harness_play (h);
148
149 caps = gst_caps_from_string
150 ("video/x-raw,format=I420,width=(int)320,height=(int)240,framerate=(fraction)25/1");
151 gst_harness_set_src_caps (h, caps);
152
153 /* Check if draining are performed well without a buffer push */
154 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
155
156 do {
157 gboolean term = FALSE;
158 event = gst_harness_pull_event (h);
159 /* wait until get EOS event */
160 if (event) {
161 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
162 term = TRUE;
163
164 gst_event_unref (event);
165
166 if (term)
167 break;
168 }
169 } while (TRUE);
170
171 gst_harness_teardown (h);
172 }
173
174 GST_END_TEST;
175
176 #define MAX_PUSH_BUFFER 300
177
GST_START_TEST(test_reconfigure)178 GST_START_TEST (test_reconfigure)
179 {
180 GstHarness *h;
181 GstElement *svthevcenc;
182 GstCaps *caps;
183 GstEvent *event;
184 GstBuffer *in_buf, *out_buf = NULL;
185 GstFlowReturn ret;
186 gint i = 0;
187
188 h = gst_harness_new_parse ("svthevcenc ! h265parse");
189 fail_unless (h != NULL);
190
191 svthevcenc = gst_harness_find_element (h, "svthevcenc");
192 g_object_set (svthevcenc, "speed", 9, NULL);
193
194 gst_harness_play (h);
195
196 caps = gst_caps_from_string
197 ("video/x-raw,format=I420,width=(int)320,height=(int)240,framerate=(fraction)25/1");
198 gst_harness_set_src_caps (h, caps);
199
200 in_buf = gst_buffer_new_and_alloc ((320 * 240) * 3 / 2);
201 gst_buffer_memset (in_buf, 0, 0, -1);
202
203 GST_BUFFER_DURATION (in_buf) = GST_SECOND;
204 GST_BUFFER_DTS (in_buf) = GST_CLOCK_TIME_NONE;
205
206 /* Push bufffers until get encoder output */
207 do {
208 fail_if (i > MAX_PUSH_BUFFER);
209
210 GST_BUFFER_PTS (in_buf) = i * GST_SECOND;
211
212 ret = gst_harness_push (h, gst_buffer_ref (in_buf));
213 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
214 gst_flow_get_name (ret));
215
216 out_buf = gst_harness_try_pull (h);
217 i++;
218 } while (out_buf == NULL);
219 gst_buffer_unref (out_buf);
220
221 /* Change property for reconfig */
222 g_object_set (svthevcenc, "speed", 8, NULL);
223
224 /* Push bufffers until get encoder output */
225 do {
226 fail_if (i > 2 * MAX_PUSH_BUFFER);
227
228 GST_BUFFER_PTS (in_buf) = i * GST_SECOND;
229
230 ret = gst_harness_push (h, gst_buffer_ref (in_buf));
231 fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s",
232 gst_flow_get_name (ret));
233
234 out_buf = gst_harness_try_pull (h);
235 i++;
236 } while (out_buf == NULL);
237 gst_buffer_unref (out_buf);
238 gst_buffer_unref (in_buf);
239
240 /* push EOS to drain all buffers */
241 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
242
243 do {
244 gboolean term = FALSE;
245 event = gst_harness_pull_event (h);
246 /* wait until get EOS event */
247 if (event) {
248 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
249 term = TRUE;
250
251 gst_event_unref (event);
252
253 if (term)
254 break;
255 }
256 } while (out_buf == NULL);
257
258 gst_object_unref (svthevcenc);
259 gst_harness_teardown (h);
260 }
261
262 GST_END_TEST;
263
264 static Suite *
svthevcenc_suite(void)265 svthevcenc_suite (void)
266 {
267 Suite *s = suite_create ("svthevcenc");
268 TCase *tc_chain = tcase_create ("general");
269
270 suite_add_tcase (s, tc_chain);
271
272 tcase_add_test (tc_chain, test_encode_simple);
273 tcase_add_test (tc_chain, test_reuse);
274 tcase_add_test (tc_chain, test_no_encoding);
275 tcase_add_test (tc_chain, test_reconfigure);
276
277 return s;
278 }
279
280 GST_CHECK_MAIN (svthevcenc);
281