1 /* GStreamer
2 *
3 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
4 * Author: Thiago Santos <ts.santos@sisa.samsung.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <gst/gst.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/check/gstharness.h>
28 #include <gst/video/video.h>
29 #include <gst/app/app.h>
30
31 static GstPad *mysrcpad, *mysinkpad;
32 static GstElement *enc;
33 static GList *events = NULL;
34
35 #define TEST_VIDEO_WIDTH 640
36 #define TEST_VIDEO_HEIGHT 480
37 #define TEST_VIDEO_FPS_N 30
38 #define TEST_VIDEO_FPS_D 1
39
40 #define GST_VIDEO_ENCODER_TESTER_TYPE gst_video_encoder_tester_get_type()
41 #define GST_VIDEO_ENCODER_TESTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_VIDEO_ENCODER_TESTER_TYPE, GstVideoEncoderTester))
42 static GType gst_video_encoder_tester_get_type (void);
43
44 typedef struct _GstVideoEncoderTester GstVideoEncoderTester;
45 typedef struct _GstVideoEncoderTesterClass GstVideoEncoderTesterClass;
46
47 struct _GstVideoEncoderTester
48 {
49 GstVideoEncoder parent;
50
51 GstFlowReturn pre_push_result;
52 gint num_subframes;
53 gint current_subframe;
54 gboolean send_headers;
55 gboolean key_frame_sent;
56 gboolean enable_step_by_step;
57 gboolean negotiate_in_set_format;
58 GstVideoCodecFrame *last_frame;
59 };
60
61 struct _GstVideoEncoderTesterClass
62 {
63 GstFlowReturn (*step_by_step) (GstVideoEncoder * encoder,
64 GstVideoCodecFrame * frame, int steps);
65 GstVideoEncoderClass parent_class;
66 };
67
68 G_DEFINE_TYPE (GstVideoEncoderTester, gst_video_encoder_tester,
69 GST_TYPE_VIDEO_ENCODER);
70
71 static gboolean
gst_video_encoder_tester_start(GstVideoEncoder * enc)72 gst_video_encoder_tester_start (GstVideoEncoder * enc)
73 {
74 return TRUE;
75 }
76
77 static gboolean
gst_video_encoder_tester_stop(GstVideoEncoder * enc)78 gst_video_encoder_tester_stop (GstVideoEncoder * enc)
79 {
80 return TRUE;
81 }
82
83 static gboolean
gst_video_encoder_tester_set_format(GstVideoEncoder * enc,GstVideoCodecState * state)84 gst_video_encoder_tester_set_format (GstVideoEncoder * enc,
85 GstVideoCodecState * state)
86 {
87 GstVideoEncoderTester *enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
88
89 GstVideoCodecState *res = gst_video_encoder_set_output_state (enc,
90 gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
91 480, "height", G_TYPE_INT, 360, NULL),
92 state);
93
94 gst_video_codec_state_unref (res);
95
96 if (enc_tester->negotiate_in_set_format) {
97 gst_video_encoder_negotiate (enc);
98 }
99
100 return TRUE;
101 }
102
103 static GstFlowReturn
gst_video_encoder_push_subframe(GstVideoEncoder * enc,GstVideoCodecFrame * frame,int current_subframe)104 gst_video_encoder_push_subframe (GstVideoEncoder * enc,
105 GstVideoCodecFrame * frame, int current_subframe)
106 {
107 guint8 *data;
108 GstMapInfo map;
109 guint64 input_num;
110 GstVideoEncoderTester *enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
111
112 if (enc_tester->send_headers) {
113 GstBuffer *hdr;
114 GList *headers = NULL;
115 hdr = gst_buffer_new_and_alloc (0);
116 GST_BUFFER_FLAG_SET (hdr, GST_BUFFER_FLAG_HEADER);
117 headers = g_list_append (headers, hdr);
118 gst_video_encoder_set_headers (enc, headers);
119 enc_tester->send_headers = FALSE;
120 }
121
122 gst_buffer_map (frame->input_buffer, &map, GST_MAP_READ);
123 input_num = *((guint64 *) map.data);
124 gst_buffer_unmap (frame->input_buffer, &map);
125
126 if (!enc_tester->key_frame_sent
127 || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) {
128 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
129 enc_tester->key_frame_sent = TRUE;
130 }
131
132 data = g_malloc (sizeof (guint64));
133 *(guint64 *) data = input_num;
134 frame->output_buffer = gst_buffer_new_wrapped (data, sizeof (guint64));
135 frame->pts = GST_BUFFER_PTS (frame->input_buffer);
136 frame->duration = GST_BUFFER_DURATION (frame->input_buffer);
137
138 if (current_subframe < enc_tester->num_subframes - 1)
139 return gst_video_encoder_finish_subframe (enc, frame);
140 else
141 return gst_video_encoder_finish_frame (enc, frame);
142 }
143
144 static GstFlowReturn
gst_video_encoder_tester_output_step_by_step(GstVideoEncoder * enc,GstVideoCodecFrame * frame,gint steps)145 gst_video_encoder_tester_output_step_by_step (GstVideoEncoder * enc,
146 GstVideoCodecFrame * frame, gint steps)
147 {
148 GstVideoEncoderTester *enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
149 GstFlowReturn ret = GST_FLOW_OK;
150 int i;
151 for (i = enc_tester->current_subframe;
152 i < MIN (steps + enc_tester->current_subframe, enc_tester->num_subframes);
153 i++) {
154 ret = gst_video_encoder_push_subframe (enc, frame, i);
155 }
156 enc_tester->current_subframe = i;
157 if (enc_tester->current_subframe >= enc_tester->num_subframes) {
158 enc_tester->current_subframe = 0;
159 gst_video_codec_frame_unref (enc_tester->last_frame);
160 }
161
162 return ret;
163 }
164
165 static GstFlowReturn
gst_video_encoder_tester_handle_frame(GstVideoEncoder * enc,GstVideoCodecFrame * frame)166 gst_video_encoder_tester_handle_frame (GstVideoEncoder * enc,
167 GstVideoCodecFrame * frame)
168 {
169 GstClockTimeDiff deadline;
170 GstVideoEncoderTester *enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
171
172 deadline = gst_video_encoder_get_max_encode_time (enc, frame);
173 if (deadline < 0) {
174 /* Calling finish_frame() with frame->output_buffer == NULL means to drop it */
175 return gst_video_encoder_finish_frame (enc, frame);
176 }
177
178 enc_tester->last_frame = gst_video_codec_frame_ref (frame);
179 if (enc_tester->enable_step_by_step)
180 return GST_FLOW_OK;
181
182 return gst_video_encoder_tester_output_step_by_step (enc, frame,
183 enc_tester->num_subframes);
184 }
185
186 static GstFlowReturn
gst_video_encoder_tester_pre_push(GstVideoEncoder * enc,GstVideoCodecFrame * frame)187 gst_video_encoder_tester_pre_push (GstVideoEncoder * enc,
188 GstVideoCodecFrame * frame)
189 {
190 GstVideoEncoderTester *tester = (GstVideoEncoderTester *) enc;
191 return tester->pre_push_result;
192 }
193
194 static void
gst_video_encoder_tester_class_init(GstVideoEncoderTesterClass * klass)195 gst_video_encoder_tester_class_init (GstVideoEncoderTesterClass * klass)
196 {
197 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
198 GstVideoEncoderClass *videoencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
199
200 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
201 GST_PAD_SINK, GST_PAD_ALWAYS,
202 GST_STATIC_CAPS ("video/x-raw"));
203
204 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
205 GST_PAD_SRC, GST_PAD_ALWAYS,
206 GST_STATIC_CAPS ("video/x-test-custom"));
207
208 gst_element_class_add_static_pad_template (element_class, &sink_templ);
209 gst_element_class_add_static_pad_template (element_class, &src_templ);
210
211 gst_element_class_set_metadata (element_class,
212 "VideoEncoderTester", "Encoder/Video", "yep", "me");
213
214 videoencoder_class->start = gst_video_encoder_tester_start;
215 videoencoder_class->stop = gst_video_encoder_tester_stop;
216 videoencoder_class->handle_frame = gst_video_encoder_tester_handle_frame;
217 videoencoder_class->pre_push = gst_video_encoder_tester_pre_push;
218 videoencoder_class->set_format = gst_video_encoder_tester_set_format;
219
220 }
221
222 static void
gst_video_encoder_tester_init(GstVideoEncoderTester * tester)223 gst_video_encoder_tester_init (GstVideoEncoderTester * tester)
224 {
225 tester->pre_push_result = GST_FLOW_OK;
226 /* One subframe is considered as a whole single frame. */
227 tester->num_subframes = 1;
228 }
229
230 static gboolean
_mysinkpad_event(GstPad * pad,GstObject * parent,GstEvent * event)231 _mysinkpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
232 {
233 events = g_list_append (events, event);
234 return TRUE;
235 }
236
237 static void
setup_videoencodertester(void)238 setup_videoencodertester (void)
239 {
240 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
241 GST_PAD_SINK,
242 GST_PAD_ALWAYS,
243 GST_STATIC_CAPS ("video/x-test-custom")
244 );
245 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
246 GST_PAD_SRC,
247 GST_PAD_ALWAYS,
248 GST_STATIC_CAPS ("video/x-raw")
249 );
250
251 enc = g_object_new (GST_VIDEO_ENCODER_TESTER_TYPE, NULL);
252 mysrcpad = gst_check_setup_src_pad (enc, &srctemplate);
253 mysinkpad = gst_check_setup_sink_pad (enc, &sinktemplate);
254
255 gst_pad_set_event_function (mysinkpad, _mysinkpad_event);
256 }
257
258 static void
setup_videoencodertester_with_subframes(int num_subframes)259 setup_videoencodertester_with_subframes (int num_subframes)
260 {
261 GstVideoEncoderTester *enc_tester;
262 setup_videoencodertester ();
263 enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
264 enc_tester->num_subframes = num_subframes;
265 enc_tester->send_headers = TRUE;
266 }
267
268 static void
cleanup_videoencodertest(void)269 cleanup_videoencodertest (void)
270 {
271 gst_pad_set_active (mysrcpad, FALSE);
272 gst_pad_set_active (mysinkpad, FALSE);
273
274 gst_element_set_state (enc, GST_STATE_NULL);
275
276 gst_check_teardown_src_pad (enc);
277 gst_check_teardown_sink_pad (enc);
278 gst_check_teardown_element (enc);
279
280 g_list_free_full (events, (GDestroyNotify) gst_event_unref);
281 events = NULL;
282 }
283
284 static GstBuffer *
create_test_buffer(guint64 num)285 create_test_buffer (guint64 num)
286 {
287 GstBuffer *buffer;
288 guint64 *data = g_malloc (sizeof (guint64));
289
290 *data = num;
291
292 buffer = gst_buffer_new_wrapped (data, sizeof (guint64));
293
294 GST_BUFFER_PTS (buffer) =
295 gst_util_uint64_scale_round (num, GST_SECOND * TEST_VIDEO_FPS_D,
296 TEST_VIDEO_FPS_N);
297 GST_BUFFER_DURATION (buffer) =
298 gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
299 TEST_VIDEO_FPS_N);
300
301 return buffer;
302 }
303
304 static GstCaps *
create_test_caps(void)305 create_test_caps (void)
306 {
307 return gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
308 TEST_VIDEO_WIDTH, "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, "framerate",
309 GST_TYPE_FRACTION, TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D,
310 "format", G_TYPE_STRING, "GRAY8", NULL);
311 }
312
313 static void
send_startup_events(void)314 send_startup_events (void)
315 {
316 GstCaps *caps;
317
318 fail_unless (gst_pad_push_event (mysrcpad,
319 gst_event_new_stream_start ("randomvalue")));
320
321 /* push caps */
322 caps = create_test_caps ();
323 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps)));
324 gst_caps_unref (caps);
325 }
326
327 #define NUM_BUFFERS 100
GST_START_TEST(videoencoder_playback)328 GST_START_TEST (videoencoder_playback)
329 {
330 GstSegment segment;
331 GstBuffer *buffer;
332 guint64 i;
333 GList *iter;
334
335 setup_videoencodertester ();
336
337 gst_pad_set_active (mysrcpad, TRUE);
338 gst_element_set_state (enc, GST_STATE_PLAYING);
339 gst_pad_set_active (mysinkpad, TRUE);
340
341 send_startup_events ();
342
343 /* push a new segment */
344 gst_segment_init (&segment, GST_FORMAT_TIME);
345 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
346
347 /* push buffers, the data is actually a number so we can track them */
348 for (i = 0; i < NUM_BUFFERS; i++) {
349 buffer = create_test_buffer (i);
350
351 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
352 }
353
354 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
355
356 /* check that all buffers were received by our source pad */
357 fail_unless (g_list_length (buffers) == NUM_BUFFERS);
358 i = 0;
359 for (iter = buffers; iter; iter = g_list_next (iter)) {
360 GstMapInfo map;
361 guint64 num;
362
363 buffer = iter->data;
364
365 gst_buffer_map (buffer, &map, GST_MAP_READ);
366
367 num = *(guint64 *) map.data;
368 fail_unless (i == num);
369 fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
370 GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
371 fail_unless (GST_BUFFER_DURATION (buffer) ==
372 gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
373 TEST_VIDEO_FPS_N));
374
375 gst_buffer_unmap (buffer, &map);
376 i++;
377 }
378
379 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
380 buffers = NULL;
381
382 cleanup_videoencodertest ();
383 }
384
385 GST_END_TEST;
386
387 /* make sure tags sent right before eos are pushed */
GST_START_TEST(videoencoder_tags_before_eos)388 GST_START_TEST (videoencoder_tags_before_eos)
389 {
390 GstSegment segment;
391 GstBuffer *buffer;
392 GstTagList *tags;
393
394 setup_videoencodertester ();
395
396 gst_pad_set_active (mysrcpad, TRUE);
397 gst_element_set_state (enc, GST_STATE_PLAYING);
398 gst_pad_set_active (mysinkpad, TRUE);
399
400 send_startup_events ();
401
402 /* push a new segment */
403 gst_segment_init (&segment, GST_FORMAT_TIME);
404 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
405
406 /* push buffer */
407 buffer = create_test_buffer (0);
408 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
409
410 /* clean received events list */
411 g_list_free_full (events, (GDestroyNotify) gst_event_unref);
412 events = NULL;
413
414 /* push a tag event */
415 tags = gst_tag_list_new (GST_TAG_COMMENT, "test-comment", NULL);
416 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_tag (tags)));
417
418 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
419
420 /* check that the tag was received */
421 {
422 GstEvent *tag_event = events->data;
423 gchar *str;
424
425 fail_unless (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG);
426 gst_event_parse_tag (tag_event, &tags);
427 fail_unless (gst_tag_list_get_string (tags, GST_TAG_COMMENT, &str));
428 fail_unless (strcmp (str, "test-comment") == 0);
429 g_free (str);
430 }
431
432 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
433 buffers = NULL;
434 g_list_free_full (events, (GDestroyNotify) gst_event_unref);
435 events = NULL;
436
437 cleanup_videoencodertest ();
438 }
439
440 GST_END_TEST;
441
442 /* make sure events sent right before eos are pushed */
GST_START_TEST(videoencoder_events_before_eos)443 GST_START_TEST (videoencoder_events_before_eos)
444 {
445 GstSegment segment;
446 GstBuffer *buffer;
447 GstMessage *msg;
448
449 setup_videoencodertester ();
450
451 gst_pad_set_active (mysrcpad, TRUE);
452 gst_element_set_state (enc, GST_STATE_PLAYING);
453 gst_pad_set_active (mysinkpad, TRUE);
454
455 send_startup_events ();
456
457 /* push a new segment */
458 gst_segment_init (&segment, GST_FORMAT_TIME);
459 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
460
461 /* push buffer */
462 buffer = create_test_buffer (0);
463 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
464
465 /* clean received events list */
466 g_list_free_full (events, (GDestroyNotify) gst_event_unref);
467 events = NULL;
468
469 /* push a serialized event */
470 msg =
471 gst_message_new_element (GST_OBJECT (mysrcpad),
472 gst_structure_new_empty ("test"));
473 fail_unless (gst_pad_push_event (mysrcpad,
474 gst_event_new_sink_message ("sink-test", msg)));
475 gst_message_unref (msg);
476
477 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
478
479 /* check that the tag was received */
480 {
481 GstEvent *msg_event = events->data;
482 const GstStructure *structure;
483
484 fail_unless (GST_EVENT_TYPE (msg_event) == GST_EVENT_SINK_MESSAGE);
485 fail_unless (gst_event_has_name (msg_event, "sink-test"));
486 gst_event_parse_sink_message (msg_event, &msg);
487 structure = gst_message_get_structure (msg);
488 fail_unless (gst_structure_has_name (structure, "test"));
489 gst_message_unref (msg);
490 }
491
492 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
493 buffers = NULL;
494 g_list_free_full (events, (GDestroyNotify) gst_event_unref);
495 events = NULL;
496
497 cleanup_videoencodertest ();
498 }
499
500 GST_END_TEST;
501
GST_START_TEST(videoencoder_flush_events)502 GST_START_TEST (videoencoder_flush_events)
503 {
504 GstSegment segment;
505 GstBuffer *buffer;
506 guint i;
507 GList *events_iter;
508
509 setup_videoencodertester ();
510
511 gst_pad_set_active (mysrcpad, TRUE);
512 gst_element_set_state (enc, GST_STATE_PLAYING);
513 gst_pad_set_active (mysinkpad, TRUE);
514
515 send_startup_events ();
516
517 /* push a new segment */
518 gst_segment_init (&segment, GST_FORMAT_TIME);
519 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
520
521 /* push buffers, the data is actually a number so we can track them */
522 for (i = 0; i < NUM_BUFFERS; i++) {
523 if (i % 10 == 0) {
524 GstTagList *tags;
525
526 tags = gst_tag_list_new (GST_TAG_TRACK_NUMBER, i, NULL);
527 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_tag (tags)));
528 } else {
529 buffer = create_test_buffer (i);
530
531 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
532 }
533 }
534
535 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
536
537 events_iter = events;
538 /* make sure the usual events have been received */
539 {
540 GstEvent *sstart = events_iter->data;
541 fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
542 events_iter = g_list_next (events_iter);
543 }
544 {
545 GstEvent *caps_event = events_iter->data;
546 fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
547 events_iter = g_list_next (events_iter);
548 }
549 {
550 GstEvent *segment_event = events_iter->data;
551 fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
552 events_iter = g_list_next (events_iter);
553 }
554
555 /* check that EOS was received */
556 fail_unless (GST_PAD_IS_EOS (mysrcpad));
557 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_start ()));
558 fail_unless (GST_PAD_IS_EOS (mysrcpad));
559
560 /* Check that we have tags */
561 {
562 GstEvent *tags = gst_pad_get_sticky_event (mysrcpad, GST_EVENT_TAG, 0);
563
564 fail_unless (tags != NULL);
565 gst_event_unref (tags);
566 }
567
568 /* Check that we still have a segment set */
569 {
570 GstEvent *segment =
571 gst_pad_get_sticky_event (mysrcpad, GST_EVENT_SEGMENT, 0);
572
573 fail_unless (segment != NULL);
574 gst_event_unref (segment);
575 }
576
577 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_stop (TRUE)));
578 fail_if (GST_PAD_IS_EOS (mysrcpad));
579
580 /* Check that the segment was flushed on FLUSH_STOP */
581 {
582 GstEvent *segment =
583 gst_pad_get_sticky_event (mysrcpad, GST_EVENT_SEGMENT, 0);
584
585 fail_unless (segment == NULL);
586 }
587
588 /* Check the tags were not lost on FLUSH_STOP */
589 {
590 GstEvent *tags = gst_pad_get_sticky_event (mysrcpad, GST_EVENT_TAG, 0);
591
592 fail_unless (tags != NULL);
593 gst_event_unref (tags);
594
595 }
596
597 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
598 buffers = NULL;
599
600 cleanup_videoencodertest ();
601 }
602
603 GST_END_TEST;
604
605 /* When pre_push fails the correct GstFlowReturn should be returned and there
606 * should be no leaks */
GST_START_TEST(videoencoder_pre_push_fails)607 GST_START_TEST (videoencoder_pre_push_fails)
608 {
609 GstVideoEncoderTester *tester;
610 GstHarness *h;
611 GstFlowReturn ret;
612
613 tester = g_object_new (GST_VIDEO_ENCODER_TESTER_TYPE, NULL);
614 tester->pre_push_result = GST_FLOW_ERROR;
615
616 h = gst_harness_new_with_element (GST_ELEMENT (tester), "sink", "src");
617 gst_harness_set_src_caps (h, create_test_caps ());
618
619 ret = gst_harness_push (h, create_test_buffer (0));
620 fail_unless_equals_int (ret, GST_FLOW_ERROR);
621
622 gst_harness_teardown (h);
623 gst_object_unref (tester);
624 }
625
626 GST_END_TEST;
627
GST_START_TEST(videoencoder_qos)628 GST_START_TEST (videoencoder_qos)
629 {
630 GstSegment segment;
631 GstBuffer *buffer;
632 GstClockTime ts, rt;
633 GstBus *bus;
634 GstMessage *msg;
635
636 setup_videoencodertester ();
637
638 gst_video_encoder_set_qos_enabled (GST_VIDEO_ENCODER (enc), TRUE);
639
640 gst_pad_set_active (mysrcpad, TRUE);
641 gst_element_set_state (enc, GST_STATE_PLAYING);
642 gst_pad_set_active (mysinkpad, TRUE);
643
644 bus = gst_bus_new ();
645 gst_element_set_bus (enc, bus);
646
647 send_startup_events ();
648
649 /* push a new segment */
650 gst_segment_init (&segment, GST_FORMAT_TIME);
651 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
652
653 /* push the first buffer */
654 buffer = create_test_buffer (0);
655 ts = GST_BUFFER_PTS (buffer);
656 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
657 buffer = NULL;
658
659 /* pretend this buffer was late in the sink */
660 rt = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, ts);
661 fail_unless (gst_pad_push_event (mysinkpad,
662 gst_event_new_qos (GST_QOS_TYPE_UNDERFLOW, 1.5, 500 * GST_MSECOND,
663 rt)));
664
665 /* push a second buffer which will be dropped as it's already late */
666 buffer = create_test_buffer (1);
667 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
668 buffer = NULL;
669
670 /* A QoS message was sent by the encoder */
671 msg = gst_bus_pop_filtered (bus, GST_MESSAGE_QOS);
672 g_assert (msg != NULL);
673 gst_message_unref (msg);
674
675 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
676
677 gst_bus_set_flushing (bus, TRUE);
678 gst_object_unref (bus);
679
680 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
681 buffers = NULL;
682
683 cleanup_videoencodertest ();
684 }
685
686 GST_END_TEST;
687
688 #define NUM_BUFFERS 100
GST_START_TEST(videoencoder_playback_subframes)689 GST_START_TEST (videoencoder_playback_subframes)
690 {
691 GstSegment segment;
692 GstBuffer *buffer;
693 guint64 i;
694 GList *iter;
695 int subframes = 4;
696
697 setup_videoencodertester_with_subframes (subframes);
698
699 gst_pad_set_active (mysrcpad, TRUE);
700 gst_element_set_state (enc, GST_STATE_PLAYING);
701 gst_pad_set_active (mysinkpad, TRUE);
702
703 send_startup_events ();
704
705 /* push a new segment */
706 gst_segment_init (&segment, GST_FORMAT_TIME);
707 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
708
709 /* push buffers, the data is actually a number so we can track them */
710 for (i = 0; i < NUM_BUFFERS; i++) {
711 buffer = create_test_buffer (i);
712
713 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
714 }
715
716 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
717
718 /* check that all buffers (plus one header buffer) were received by our source pad */
719 fail_unless (g_list_length (buffers) == NUM_BUFFERS * subframes + 1);
720 /* check that first buffer is an header */
721 buffer = buffers->data;
722 fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER));
723 /* check the other buffers */
724 i = 0;
725 for (iter = g_list_next (buffers); iter; iter = g_list_next (iter)) {
726 /* first buffer should be the header */
727 GstMapInfo map;
728 guint64 num;
729 buffer = iter->data;
730 fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER));
731 gst_buffer_map (buffer, &map, GST_MAP_READ);
732
733 num = *(guint64 *) map.data;
734 fail_unless (i / subframes == num);
735
736 if (i % subframes)
737 fail_unless (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
738
739 fail_unless (GST_BUFFER_PTS (buffer) ==
740 gst_util_uint64_scale_round (i / subframes,
741 GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
742 fail_unless (GST_BUFFER_DURATION (buffer) ==
743 gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
744 TEST_VIDEO_FPS_N));
745 gst_buffer_unmap (buffer, &map);
746
747
748 i++;
749 }
750
751 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
752 buffers = NULL;
753
754 cleanup_videoencodertest ();
755 }
756
757 GST_END_TEST;
758
GST_START_TEST(videoencoder_playback_events_subframes)759 GST_START_TEST (videoencoder_playback_events_subframes)
760 {
761 GstSegment segment;
762 GstBuffer *buffer;
763 GList *iter;
764 gint subframes = 4;
765 gint i, header_found;
766 GstVideoEncoderTester *enc_tester;
767
768 setup_videoencodertester_with_subframes (subframes);
769
770 enc_tester = GST_VIDEO_ENCODER_TESTER (enc);
771 enc_tester->send_headers = TRUE;
772 enc_tester->enable_step_by_step = TRUE;
773
774 gst_pad_set_active (mysrcpad, TRUE);
775 gst_element_set_state (enc, GST_STATE_PLAYING);
776 gst_pad_set_active (mysinkpad, TRUE);
777
778 send_startup_events ();
779
780 /* push a new segment -> no new buffer and no new events (still pending two custom events) */
781 gst_segment_init (&segment, GST_FORMAT_TIME);
782 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
783 fail_unless (g_list_length (buffers) == 0 && g_list_length (events) == 0);
784
785 /* push a first buffer -> no new buffer and no new events (still pending two custom events) */
786 buffer = create_test_buffer (0);
787 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
788 fail_unless (g_list_length (buffers) == 0 && g_list_length (events) == 0);
789
790 /* ouput only one subframe -> 2 buffers(header + subframe) and 3 events (stream-start, caps, segment) */
791 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
792 enc_tester->last_frame, 1);
793 fail_unless (g_list_length (buffers) == 2 && g_list_length (events) == 3);
794 fail_unless (GST_BUFFER_FLAG_IS_SET ((GstBuffer *) buffers->data,
795 GST_BUFFER_FLAG_HEADER));
796 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
797 0)->data)) == GST_EVENT_STREAM_START);
798 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
799 1)->data)) == GST_EVENT_CAPS);
800 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
801 2)->data)) == GST_EVENT_SEGMENT);
802
803 /* output 3 last subframes -> 2 more buffers and no new events */
804 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
805 enc_tester->last_frame, 3);
806 fail_unless (g_list_length (buffers) == 5 && g_list_length (events) == 3);
807
808 /* push a new buffer -> no new buffer and no new events */
809 buffer = create_test_buffer (1);
810 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
811 fail_unless (g_list_length (buffers) == 5 && g_list_length (events) == 3);
812
813 /* push an event in between -> no new buffer and no new event */
814 fail_unless (gst_pad_push_event (mysrcpad,
815 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
816 gst_structure_new_empty ("custom1"))));
817 fail_unless (g_list_length (buffers) == 5 && g_list_length (events) == 3);
818
819 /* output 1 subframe -> one new buffer and no new events */
820 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
821 enc_tester->last_frame, 1);
822 fail_unless (g_list_length (buffers) == 6 && g_list_length (events) == 3);
823
824 /* push another custom event in between , no new event should appear until the next frame is handled */
825 fail_unless (gst_pad_push_event (mysrcpad,
826 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
827 gst_structure_new_empty ("custom2"))));
828 fail_unless (g_list_length (buffers) == 6 && g_list_length (events) == 3);
829
830 /* output 2 subframes -> 2 new buffers and no new events */
831 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
832 enc_tester->last_frame, 2);
833 fail_unless (g_list_length (buffers) == 8 && g_list_length (events) == 3);
834
835 /* output 1 last subframe -> 1 new buffers and no new events */
836 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
837 enc_tester->last_frame, 1);
838 fail_unless (g_list_length (buffers) == 9 && g_list_length (events) == 3);
839
840 /* push a third buffer -> no new buffer and no new events (still pending two custom events) */
841 buffer = create_test_buffer (2);
842 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
843 fail_unless (g_list_length (buffers) == 9 && g_list_length (events) == 3);
844
845 /* output 1 subframes -> 1 new buffer and 2 custom events from the last input frame */
846 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
847 enc_tester->last_frame, 1);
848 fail_unless (g_list_length (buffers) == 10 && g_list_length (events) == 5);
849 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
850 3)->data)) == GST_EVENT_CUSTOM_DOWNSTREAM);
851 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
852 4)->data)) == GST_EVENT_CUSTOM_DOWNSTREAM);
853
854 /* push another custom event in between , no new event should appear until eos */
855 fail_unless (gst_pad_push_event (mysrcpad,
856 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
857 gst_structure_new_empty ("custom3"))));
858 fail_unless (g_list_length (buffers) == 10 && g_list_length (events) == 5);
859
860 /* output 3 subframes -> 3 new buffer and no new events */
861 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
862 enc_tester->last_frame, 3);
863 fail_unless (g_list_length (buffers) == 13 && g_list_length (events) == 5);
864
865 /* push a force key-unit event */
866 fail_unless (gst_pad_push_event (mysinkpad,
867 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
868 TRUE, 1)));
869
870 /* Create a new buffer which should be a key unit -> no new buffer and no new event */
871 buffer = create_test_buffer (3);
872 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
873 fail_unless (g_list_length (buffers) == 13 && g_list_length (events) == 5);
874
875 /* output 2 subframes -> 3 new buffer(one header and two subframes and two events key-unit and custom3 */
876 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
877 enc_tester->last_frame, 2);
878 fail_unless (g_list_length (buffers) == 16 && g_list_length (events) == 7);
879
880 /* output 2 subframes -> 2 new buffer corresponding the two last subframes */
881 gst_video_encoder_tester_output_step_by_step (GST_VIDEO_ENCODER (enc),
882 enc_tester->last_frame, 2);
883 fail_unless (g_list_length (buffers) == 18 && g_list_length (events) == 7);
884
885 /* push eos event -> 1 new event ( eos) */
886 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
887 fail_unless (g_list_length (buffers) == 18 && g_list_length (events) == 8);
888
889 /* check the order of the last events received */
890 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
891 6)->data)) == GST_EVENT_CUSTOM_DOWNSTREAM);
892 fail_unless (GST_EVENT_TYPE ((GstEvent *) (g_list_nth (events,
893 7)->data)) == GST_EVENT_EOS);
894
895 /* check that only last subframe owns the GST_VIDEO_BUFFER_FLAG_MARKER flag */
896 header_found = 0;
897 for (iter = buffers, i = 0; iter; iter = g_list_next (iter), i++) {
898 buffer = (GstBuffer *) (iter->data);
899 if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) {
900 if ((i - header_found) % subframes == (subframes - 1))
901 fail_unless (GST_BUFFER_FLAG_IS_SET (buffer,
902 GST_VIDEO_BUFFER_FLAG_MARKER));
903 else
904 fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer,
905 GST_VIDEO_BUFFER_FLAG_MARKER));
906 } else {
907 fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer,
908 GST_VIDEO_BUFFER_FLAG_MARKER));
909 header_found++;
910 }
911
912 /* Only the 0th (header), 1st, 13th (header) and 14th buffer should be keyframes */
913 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
914 fail_if (i == 0 || i == 1 || i == 13 || i == 14);
915 } else {
916 fail_unless (i == 0 || i == 1 || i == 13 || i == 14);
917 }
918 }
919
920 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
921 buffers = NULL;
922
923 cleanup_videoencodertest ();
924 }
925
926 GST_END_TEST;
927
GST_START_TEST(videoencoder_force_keyunit_handling)928 GST_START_TEST (videoencoder_force_keyunit_handling)
929 {
930 GstSegment segment;
931 GstBuffer *buffer;
932 GList *l;
933 gint i;
934
935 setup_videoencodertester ();
936
937 gst_pad_set_active (mysrcpad, TRUE);
938 gst_element_set_state (enc, GST_STATE_PLAYING);
939 gst_pad_set_active (mysinkpad, TRUE);
940
941 send_startup_events ();
942
943 /* push a new segment */
944 gst_segment_init (&segment, GST_FORMAT_TIME);
945 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
946
947 /* push the first buffer */
948 buffer = create_test_buffer (0);
949 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
950 buffer = NULL;
951
952 fail_unless_equals_int (g_list_length (buffers), 1);
953
954 buffer = create_test_buffer (1);
955 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
956 buffer = NULL;
957
958 fail_unless_equals_int (g_list_length (buffers), 2);
959
960 /* send a force-keyunit event, the next buffer should be a keyframe now */
961 fail_unless (gst_pad_push_event (mysinkpad,
962 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
963 TRUE, 1)));
964
965 buffer = create_test_buffer (2);
966 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
967 buffer = NULL;
968
969 fail_unless_equals_int (g_list_length (buffers), 3);
970
971 buffer = create_test_buffer (3);
972 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
973 buffer = NULL;
974
975 fail_unless_equals_int (g_list_length (buffers), 4);
976
977 /* send multiple force-keyunit events now, this should still only cause a
978 * single keyframe */
979 fail_unless (gst_pad_push_event (mysinkpad,
980 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
981 TRUE, 1)));
982 fail_unless (gst_pad_push_event (mysinkpad,
983 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
984 TRUE, 1)));
985
986 buffer = create_test_buffer (4);
987 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
988 buffer = NULL;
989
990 fail_unless_equals_int (g_list_length (buffers), 5);
991
992 buffer = create_test_buffer (5);
993 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
994 buffer = NULL;
995
996 fail_unless_equals_int (g_list_length (buffers), 6);
997
998 /* send a force-keyunit event for the running time of the next buffer */
999 fail_unless (gst_pad_push_event (mysinkpad,
1000 gst_video_event_new_upstream_force_key_unit
1001 (gst_util_uint64_scale_round (6, GST_SECOND * TEST_VIDEO_FPS_D,
1002 TEST_VIDEO_FPS_N), TRUE, 1)));
1003
1004 buffer = create_test_buffer (6);
1005 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1006 buffer = NULL;
1007
1008 fail_unless_equals_int (g_list_length (buffers), 7);
1009
1010 buffer = create_test_buffer (7);
1011 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1012 buffer = NULL;
1013
1014 fail_unless_equals_int (g_list_length (buffers), 8);
1015
1016 /* send a force-keyunit event for the running time of the next buffer
1017 * and another one right before. This should only cause a single keyframe
1018 * again */
1019 fail_unless (gst_pad_push_event (mysinkpad,
1020 gst_video_event_new_upstream_force_key_unit
1021 (gst_util_uint64_scale_round (8, GST_SECOND * TEST_VIDEO_FPS_D,
1022 TEST_VIDEO_FPS_N), TRUE, 1)));
1023 fail_unless (gst_pad_push_event (mysinkpad,
1024 gst_video_event_new_upstream_force_key_unit
1025 (gst_util_uint64_scale_round (8, GST_SECOND * TEST_VIDEO_FPS_D,
1026 TEST_VIDEO_FPS_N) - 10 * GST_MSECOND, TRUE, 1)));
1027
1028 buffer = create_test_buffer (8);
1029 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1030 buffer = NULL;
1031
1032 fail_unless_equals_int (g_list_length (buffers), 9);
1033
1034 buffer = create_test_buffer (9);
1035 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1036 buffer = NULL;
1037
1038 fail_unless_equals_int (g_list_length (buffers), 10);
1039
1040 /* send a force-keyunit event for the 12th buffer, see below */
1041 fail_unless (gst_pad_push_event (mysinkpad,
1042 gst_video_event_new_upstream_force_key_unit
1043 (gst_util_uint64_scale_round (12, GST_SECOND * TEST_VIDEO_FPS_D,
1044 TEST_VIDEO_FPS_N), TRUE, 1)));
1045
1046 /* send two force-keyunit events. This should only cause a single keyframe
1047 * again */
1048 fail_unless (gst_pad_push_event (mysinkpad,
1049 gst_video_event_new_upstream_force_key_unit
1050 (gst_util_uint64_scale_round (10, GST_SECOND * TEST_VIDEO_FPS_D,
1051 TEST_VIDEO_FPS_N), TRUE, 1)));
1052 fail_unless (gst_pad_push_event (mysinkpad,
1053 gst_video_event_new_upstream_force_key_unit
1054 (gst_util_uint64_scale_round (10, GST_SECOND * TEST_VIDEO_FPS_D,
1055 TEST_VIDEO_FPS_N) - 10 * GST_MSECOND, TRUE, 1)));
1056
1057 buffer = create_test_buffer (10);
1058 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1059 buffer = NULL;
1060
1061 fail_unless_equals_int (g_list_length (buffers), 11);
1062
1063 buffer = create_test_buffer (11);
1064 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1065 buffer = NULL;
1066
1067 fail_unless_equals_int (g_list_length (buffers), 12);
1068
1069 /* we already sent a force-keyunit event for the 12th buffer long ago */
1070 buffer = create_test_buffer (12);
1071 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1072 buffer = NULL;
1073
1074 fail_unless_equals_int (g_list_length (buffers), 13);
1075
1076 /* we already received a keyframe after the given time, so the next frame
1077 * is not going to be another keyframe */
1078 fail_unless (gst_pad_push_event (mysinkpad,
1079 gst_video_event_new_upstream_force_key_unit
1080 (gst_util_uint64_scale_round (12, GST_SECOND * TEST_VIDEO_FPS_D,
1081 TEST_VIDEO_FPS_N), TRUE, 1)));
1082
1083 buffer = create_test_buffer (13);
1084 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1085 buffer = NULL;
1086
1087 fail_unless_equals_int (g_list_length (buffers), 14);
1088
1089 /* every second buffer should be a keyframe */
1090 for (l = buffers, i = 0; l; l = l->next, i++) {
1091 if (i % 2 == 0)
1092 fail_if (GST_BUFFER_FLAG_IS_SET (l->data, GST_BUFFER_FLAG_DELTA_UNIT));
1093 else
1094 fail_unless (GST_BUFFER_FLAG_IS_SET (l->data,
1095 GST_BUFFER_FLAG_DELTA_UNIT));
1096 }
1097
1098 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
1099 buffers = NULL;
1100
1101 cleanup_videoencodertest ();
1102 }
1103
1104 GST_END_TEST;
1105
GST_START_TEST(videoencoder_force_keyunit_min_interval)1106 GST_START_TEST (videoencoder_force_keyunit_min_interval)
1107 {
1108 GstSegment segment;
1109 GstBuffer *buffer;
1110 GList *l;
1111 gint i;
1112
1113 setup_videoencodertester ();
1114
1115 gst_pad_set_active (mysrcpad, TRUE);
1116 /* Only one keyframe request every 3 frames at most */
1117 g_object_set (enc, "min-force-key-unit-interval", 100 * GST_MSECOND, NULL);
1118 gst_element_set_state (enc, GST_STATE_PLAYING);
1119 gst_pad_set_active (mysinkpad, TRUE);
1120
1121 send_startup_events ();
1122
1123 /* push a new segment */
1124 gst_segment_init (&segment, GST_FORMAT_TIME);
1125 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
1126
1127 /* push the first two buffers */
1128 buffer = create_test_buffer (0);
1129 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1130
1131 buffer = create_test_buffer (1);
1132 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1133
1134 /* send a force-keyunit event, the next buffer should not be a keyframe yet */
1135 fail_unless (gst_pad_push_event (mysinkpad,
1136 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
1137 TRUE, 1)));
1138
1139 buffer = create_test_buffer (2);
1140 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1141
1142 /* this buffer should be a keyframe */
1143 buffer = create_test_buffer (3);
1144 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1145
1146 /* send two force-keyunit event, the 6th buffer should be a keyframe */
1147 fail_unless (gst_pad_push_event (mysinkpad,
1148 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
1149 TRUE, 1)));
1150 fail_unless (gst_pad_push_event (mysinkpad,
1151 gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
1152 TRUE, 1)));
1153
1154 buffer = create_test_buffer (4);
1155 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1156 buffer = create_test_buffer (5);
1157 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1158 buffer = create_test_buffer (6);
1159 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1160
1161 /* send a force-keyunit event for the 9th buffer, this should happen */
1162 fail_unless (gst_pad_push_event (mysinkpad,
1163 gst_video_event_new_upstream_force_key_unit
1164 (gst_util_uint64_scale_round (9, GST_SECOND * TEST_VIDEO_FPS_D,
1165 TEST_VIDEO_FPS_N), TRUE, 1)));
1166 buffer = create_test_buffer (7);
1167 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1168 buffer = create_test_buffer (8);
1169 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1170 buffer = create_test_buffer (9);
1171 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1172
1173 /* send a force-keyunit event for the 11th buffer, this should happen on the
1174 * 12th */
1175 fail_unless (gst_pad_push_event (mysinkpad,
1176 gst_video_event_new_upstream_force_key_unit
1177 (gst_util_uint64_scale_round (11, GST_SECOND * TEST_VIDEO_FPS_D,
1178 TEST_VIDEO_FPS_N), TRUE, 1)));
1179 buffer = create_test_buffer (10);
1180 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1181 buffer = create_test_buffer (11);
1182 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1183 buffer = create_test_buffer (12);
1184 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1185
1186 fail_unless_equals_int (g_list_length (buffers), 13);
1187
1188 /* every third buffer should be a keyframe */
1189 for (l = buffers, i = 0; l; l = l->next, i++) {
1190 if (i % 3 == 0)
1191 fail_if (GST_BUFFER_FLAG_IS_SET (l->data, GST_BUFFER_FLAG_DELTA_UNIT));
1192 else
1193 fail_unless (GST_BUFFER_FLAG_IS_SET (l->data,
1194 GST_BUFFER_FLAG_DELTA_UNIT));
1195 }
1196
1197 g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
1198 buffers = NULL;
1199
1200 cleanup_videoencodertest ();
1201 }
1202
1203 GST_END_TEST;
1204
GST_START_TEST(videoencoder_hdr_metadata)1205 GST_START_TEST (videoencoder_hdr_metadata)
1206 {
1207 const gchar *mdi_str =
1208 "35399:14599:8500:39850:6550:2300:15634:16450:10000000:1";
1209 const gchar *cll_str = "1000:50";
1210 gint i;
1211
1212 /* Check that HDR metadata get passed to src pad no matter if negotiate gets
1213 * called from gst_video_encoder_finish_frame() or GstVideoEncoder::set_format
1214 */
1215 for (i = 1; i >= 0; --i) {
1216 GstVideoMasteringDisplayInfo mdi;
1217 GstVideoContentLightLevel cll;
1218 GstSegment segment;
1219 GstCaps *caps;
1220 GstStructure *s;
1221 const gchar *str;
1222
1223 setup_videoencodertester ();
1224 GST_VIDEO_ENCODER_TESTER (enc)->negotiate_in_set_format = i;
1225
1226 gst_pad_set_active (mysrcpad, TRUE);
1227 gst_element_set_state (enc, GST_STATE_PLAYING);
1228 gst_pad_set_active (mysinkpad, TRUE);
1229
1230 fail_unless (gst_pad_push_event (mysrcpad,
1231 gst_event_new_stream_start ("id")));
1232
1233 gst_video_mastering_display_info_from_string (&mdi, mdi_str);
1234 gst_video_content_light_level_from_string (&cll, cll_str);
1235
1236 caps = create_test_caps ();
1237 gst_video_mastering_display_info_add_to_caps (&mdi, caps);
1238 gst_video_content_light_level_add_to_caps (&cll, caps);
1239
1240 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps)));
1241 gst_caps_unref (caps);
1242
1243 gst_segment_init (&segment, GST_FORMAT_TIME);
1244 fail_unless (gst_pad_push_event (mysrcpad,
1245 gst_event_new_segment (&segment)));
1246
1247 gst_pad_push (mysrcpad, create_test_buffer (0));
1248
1249 caps = gst_pad_get_current_caps (mysinkpad);
1250
1251 s = gst_caps_get_structure (caps, 0);
1252 fail_unless (str = gst_structure_get_string (s, "mastering-display-info"));
1253 fail_unless_equals_string (str, mdi_str);
1254
1255 fail_unless (str = gst_structure_get_string (s, "content-light-level"));
1256 fail_unless_equals_string (str, cll_str);
1257
1258 gst_caps_unref (caps);
1259
1260 cleanup_videoencodertest ();
1261 }
1262 }
1263
1264 GST_END_TEST;
1265
1266 static Suite *
gst_videoencoder_suite(void)1267 gst_videoencoder_suite (void)
1268 {
1269 Suite *s = suite_create ("GstVideoEncoder");
1270 TCase *tc = tcase_create ("general");
1271
1272 suite_add_tcase (s, tc);
1273 tcase_add_test (tc, videoencoder_playback);
1274
1275 tcase_add_test (tc, videoencoder_tags_before_eos);
1276 tcase_add_test (tc, videoencoder_events_before_eos);
1277 tcase_add_test (tc, videoencoder_flush_events);
1278 tcase_add_test (tc, videoencoder_pre_push_fails);
1279 tcase_add_test (tc, videoencoder_qos);
1280 tcase_add_test (tc, videoencoder_playback_subframes);
1281 tcase_add_test (tc, videoencoder_playback_events_subframes);
1282 tcase_add_test (tc, videoencoder_force_keyunit_handling);
1283 tcase_add_test (tc, videoencoder_force_keyunit_min_interval);
1284 tcase_add_test (tc, videoencoder_hdr_metadata);
1285
1286 return s;
1287 }
1288
1289 GST_CHECK_MAIN (gst_videoencoder);
1290