• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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