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 GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
32     GST_PAD_SINK,
33     GST_PAD_ALWAYS,
34     GST_STATIC_CAPS ("video/x-raw")
35     );
36 
37 #define RESTRICTED_CAPS_WIDTH 800
38 #define RESTRICTED_CAPS_HEIGHT 600
39 #define RESTRICTED_CAPS_FPS_N 30
40 #define RESTRICTED_CAPS_FPS_D 1
41 static GstStaticPadTemplate sinktemplate_restricted =
42 GST_STATIC_PAD_TEMPLATE ("sink",
43     GST_PAD_SINK,
44     GST_PAD_ALWAYS,
45     GST_STATIC_CAPS ("video/x-raw, width=(int)800, height=(int)600,"
46         " framerate=(fraction)30/1")
47     );
48 
49 static GstStaticPadTemplate sinktemplate_with_range =
50 GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("video/x-raw, width=(int)[1,800], height=(int)[1,600],"
54         " framerate=(fraction)[1/1, 30/1]")
55     );
56 
57 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
58     GST_PAD_SRC,
59     GST_PAD_ALWAYS,
60     GST_STATIC_CAPS ("video/x-test-custom")
61     );
62 
63 static GstPad *mysrcpad, *mysinkpad;
64 static GstElement *dec;
65 static GList *events = NULL;
66 
67 #define TEST_VIDEO_WIDTH 640
68 #define TEST_VIDEO_HEIGHT 480
69 #define TEST_VIDEO_FPS_N 30
70 #define TEST_VIDEO_FPS_D 1
71 
72 #define GST_VIDEO_DECODER_TESTER_TYPE gst_video_decoder_tester_get_type()
73 static GType gst_video_decoder_tester_get_type (void);
74 
75 typedef struct _GstVideoDecoderTester GstVideoDecoderTester;
76 typedef struct _GstVideoDecoderTesterClass GstVideoDecoderTesterClass;
77 
78 struct _GstVideoDecoderTester
79 {
80   GstVideoDecoder parent;
81 
82   guint64 last_buf_num;
83   guint64 last_kf_num;
84   gboolean set_output_state;
85 };
86 
87 struct _GstVideoDecoderTesterClass
88 {
89   GstVideoDecoderClass parent_class;
90 };
91 
92 G_DEFINE_TYPE (GstVideoDecoderTester, gst_video_decoder_tester,
93     GST_TYPE_VIDEO_DECODER);
94 
95 static gboolean
gst_video_decoder_tester_start(GstVideoDecoder * dec)96 gst_video_decoder_tester_start (GstVideoDecoder * dec)
97 {
98   GstVideoDecoderTester *dectester = (GstVideoDecoderTester *) dec;
99 
100   dectester->last_buf_num = -1;
101   dectester->last_kf_num = -1;
102   dectester->set_output_state = TRUE;
103 
104   return TRUE;
105 }
106 
107 static gboolean
gst_video_decoder_tester_stop(GstVideoDecoder * dec)108 gst_video_decoder_tester_stop (GstVideoDecoder * dec)
109 {
110   return TRUE;
111 }
112 
113 static gboolean
gst_video_decoder_tester_flush(GstVideoDecoder * dec)114 gst_video_decoder_tester_flush (GstVideoDecoder * dec)
115 {
116   GstVideoDecoderTester *dectester = (GstVideoDecoderTester *) dec;
117 
118   dectester->last_buf_num = -1;
119   dectester->last_kf_num = -1;
120 
121   return TRUE;
122 }
123 
124 static gboolean
gst_video_decoder_tester_set_format(GstVideoDecoder * dec,GstVideoCodecState * state)125 gst_video_decoder_tester_set_format (GstVideoDecoder * dec,
126     GstVideoCodecState * state)
127 {
128   GstVideoDecoderTester *dectester = (GstVideoDecoderTester *) dec;
129 
130   if (dectester->set_output_state) {
131     GstVideoCodecState *res = gst_video_decoder_set_output_state (dec,
132         GST_VIDEO_FORMAT_GRAY8, TEST_VIDEO_WIDTH, TEST_VIDEO_HEIGHT, NULL);
133     gst_video_codec_state_unref (res);
134   }
135 
136   return TRUE;
137 }
138 
139 static GstFlowReturn
gst_video_decoder_tester_handle_frame(GstVideoDecoder * dec,GstVideoCodecFrame * frame)140 gst_video_decoder_tester_handle_frame (GstVideoDecoder * dec,
141     GstVideoCodecFrame * frame)
142 {
143   GstVideoDecoderTester *dectester = (GstVideoDecoderTester *) dec;
144   guint64 input_num;
145   guint8 *data;
146   gint size;
147   GstMapInfo map;
148 
149   gst_buffer_map (frame->input_buffer, &map, GST_MAP_READ);
150 
151   input_num = *((guint64 *) map.data);
152 
153   if ((input_num == dectester->last_buf_num + 1
154           && dectester->last_buf_num != -1)
155       || !GST_BUFFER_FLAG_IS_SET (frame->input_buffer,
156           GST_BUFFER_FLAG_DELTA_UNIT)) {
157 
158     /* the output is gray8 */
159     size = TEST_VIDEO_WIDTH * TEST_VIDEO_HEIGHT;
160     data = g_malloc0 (size);
161 
162     memcpy (data, map.data, sizeof (guint64));
163 
164     frame->output_buffer = gst_buffer_new_wrapped (data, size);
165     frame->pts = GST_BUFFER_PTS (frame->input_buffer);
166     frame->duration = GST_BUFFER_DURATION (frame->input_buffer);
167     dectester->last_buf_num = input_num;
168     if (!GST_BUFFER_FLAG_IS_SET (frame->input_buffer,
169             GST_BUFFER_FLAG_DELTA_UNIT))
170       dectester->last_kf_num = input_num;
171   }
172 
173   gst_buffer_unmap (frame->input_buffer, &map);
174 
175   if (frame->output_buffer)
176     return gst_video_decoder_finish_frame (dec, frame);
177   gst_video_codec_frame_unref (frame);
178   return GST_FLOW_OK;
179 }
180 
181 static void
gst_video_decoder_tester_class_init(GstVideoDecoderTesterClass * klass)182 gst_video_decoder_tester_class_init (GstVideoDecoderTesterClass * klass)
183 {
184   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
185   GstVideoDecoderClass *videodecoder_class = GST_VIDEO_DECODER_CLASS (klass);
186 
187   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
188       GST_PAD_SINK, GST_PAD_ALWAYS,
189       GST_STATIC_CAPS ("video/x-test-custom"));
190 
191   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
192       GST_PAD_SRC, GST_PAD_ALWAYS,
193       GST_STATIC_CAPS ("video/x-raw"));
194 
195   gst_element_class_add_static_pad_template (element_class, &sink_templ);
196   gst_element_class_add_static_pad_template (element_class, &src_templ);
197 
198   gst_element_class_set_metadata (element_class,
199       "VideoDecoderTester", "Decoder/Video", "yep", "me");
200 
201   videodecoder_class->start = gst_video_decoder_tester_start;
202   videodecoder_class->stop = gst_video_decoder_tester_stop;
203   videodecoder_class->flush = gst_video_decoder_tester_flush;
204   videodecoder_class->handle_frame = gst_video_decoder_tester_handle_frame;
205   videodecoder_class->set_format = gst_video_decoder_tester_set_format;
206 }
207 
208 static void
gst_video_decoder_tester_init(GstVideoDecoderTester * tester)209 gst_video_decoder_tester_init (GstVideoDecoderTester * tester)
210 {
211 }
212 
213 static gboolean
_mysinkpad_event(GstPad * pad,GstObject * parent,GstEvent * event)214 _mysinkpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
215 {
216   events = g_list_append (events, event);
217   return TRUE;
218 }
219 
220 static void
setup_videodecodertester(GstStaticPadTemplate * sinktmpl,GstStaticPadTemplate * srctmpl)221 setup_videodecodertester (GstStaticPadTemplate * sinktmpl,
222     GstStaticPadTemplate * srctmpl)
223 {
224   if (sinktmpl == NULL)
225     sinktmpl = &sinktemplate;
226   if (srctmpl == NULL)
227     srctmpl = &srctemplate;
228 
229   dec = g_object_new (GST_VIDEO_DECODER_TESTER_TYPE, NULL);
230   mysrcpad = gst_check_setup_src_pad (dec, srctmpl);
231   mysinkpad = gst_check_setup_sink_pad (dec, sinktmpl);
232 
233   gst_pad_set_event_function (mysinkpad, _mysinkpad_event);
234 }
235 
236 static void
cleanup_videodecodertest(void)237 cleanup_videodecodertest (void)
238 {
239   gst_pad_set_active (mysrcpad, FALSE);
240   gst_pad_set_active (mysinkpad, FALSE);
241   gst_check_teardown_src_pad (dec);
242   gst_check_teardown_sink_pad (dec);
243   gst_check_teardown_element (dec);
244 
245   g_list_free_full (events, (GDestroyNotify) gst_event_unref);
246   events = NULL;
247 }
248 
249 static GstBuffer *
create_test_buffer(guint64 num)250 create_test_buffer (guint64 num)
251 {
252   GstBuffer *buffer;
253   guint64 *data = g_malloc (sizeof (guint64));
254 
255   *data = num;
256 
257   buffer = gst_buffer_new_wrapped (data, sizeof (guint64));
258 
259   GST_BUFFER_PTS (buffer) =
260       gst_util_uint64_scale_round (num, GST_SECOND * TEST_VIDEO_FPS_D,
261       TEST_VIDEO_FPS_N);
262   GST_BUFFER_DURATION (buffer) =
263       gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
264       TEST_VIDEO_FPS_N);
265 
266   return buffer;
267 }
268 
269 static void
send_startup_events(void)270 send_startup_events (void)
271 {
272   GstCaps *caps;
273 
274   fail_unless (gst_pad_push_event (mysrcpad,
275           gst_event_new_stream_start ("randomvalue")));
276 
277   /* push caps */
278   caps =
279       gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
280       TEST_VIDEO_WIDTH, "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, "framerate",
281       GST_TYPE_FRACTION, TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D, NULL);
282   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps)));
283   gst_caps_unref (caps);
284 }
285 
286 #define NUM_BUFFERS 1000
GST_START_TEST(videodecoder_playback)287 GST_START_TEST (videodecoder_playback)
288 {
289   GstSegment segment;
290   GstBuffer *buffer;
291   guint64 i;
292   GList *iter;
293 
294   setup_videodecodertester (NULL, NULL);
295 
296   gst_pad_set_active (mysrcpad, TRUE);
297   gst_element_set_state (dec, GST_STATE_PLAYING);
298   gst_pad_set_active (mysinkpad, TRUE);
299 
300   send_startup_events ();
301 
302   /* push a new segment */
303   gst_segment_init (&segment, GST_FORMAT_TIME);
304   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
305 
306   /* push buffers, the data is actually a number so we can track them */
307   for (i = 0; i < NUM_BUFFERS; i++) {
308     buffer = create_test_buffer (i);
309 
310     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
311   }
312 
313   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
314 
315   /* check that all buffers were received by our source pad */
316   fail_unless (g_list_length (buffers) == NUM_BUFFERS);
317   i = 0;
318   for (iter = buffers; iter; iter = g_list_next (iter)) {
319     GstMapInfo map;
320     guint64 num;
321 
322     buffer = iter->data;
323 
324     gst_buffer_map (buffer, &map, GST_MAP_READ);
325 
326 
327     num = *(guint64 *) map.data;
328     fail_unless (i == num);
329     fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
330             GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
331     fail_unless (GST_BUFFER_DURATION (buffer) ==
332         gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
333             TEST_VIDEO_FPS_N));
334 
335     gst_buffer_unmap (buffer, &map);
336     i++;
337   }
338 
339   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
340   buffers = NULL;
341 
342   cleanup_videodecodertest ();
343 }
344 
345 GST_END_TEST;
346 
347 
GST_START_TEST(videodecoder_playback_with_events)348 GST_START_TEST (videodecoder_playback_with_events)
349 {
350   GstSegment segment;
351   GstBuffer *buffer;
352   guint i;
353   GList *iter;
354   GList *events_iter;
355 
356   setup_videodecodertester (NULL, NULL);
357 
358   gst_pad_set_active (mysrcpad, TRUE);
359   gst_element_set_state (dec, GST_STATE_PLAYING);
360   gst_pad_set_active (mysinkpad, TRUE);
361 
362   send_startup_events ();
363 
364   /* push a new segment */
365   gst_segment_init (&segment, GST_FORMAT_TIME);
366   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
367 
368   /* push buffers, the data is actually a number so we can track them */
369   for (i = 0; i < NUM_BUFFERS; i++) {
370     if (i % 10 == 0) {
371       GstTagList *tags;
372 
373       tags = gst_tag_list_new (GST_TAG_TRACK_NUMBER, i, NULL);
374       fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_tag (tags)));
375     } else {
376       buffer = create_test_buffer (i);
377 
378       fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
379     }
380   }
381 
382   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
383 
384   events_iter = events;
385   /* make sure the usual events have been received */
386   {
387     GstEvent *sstart = events_iter->data;
388     fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
389     events_iter = g_list_next (events_iter);
390   }
391   {
392     GstEvent *caps_event = events_iter->data;
393     fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
394     events_iter = g_list_next (events_iter);
395   }
396   {
397     GstEvent *segment_event = events_iter->data;
398     fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
399     events_iter = g_list_next (events_iter);
400   }
401 
402   /* check that all buffers were received by our source pad */
403   iter = buffers;
404   for (i = 0; i < NUM_BUFFERS; i++) {
405     if (i % 10 == 0) {
406       guint tag_v;
407       GstEvent *tag_event = events_iter->data;
408       GstTagList *taglist = NULL;
409 
410       gst_event_parse_tag (tag_event, &taglist);
411 
412       fail_unless (gst_tag_list_get_uint (taglist, GST_TAG_TRACK_NUMBER,
413               &tag_v));
414       fail_unless (tag_v == i);
415 
416       events_iter = g_list_next (events_iter);
417     } else {
418       GstMapInfo map;
419       guint64 num;
420 
421       buffer = iter->data;
422 
423       gst_buffer_map (buffer, &map, GST_MAP_READ);
424 
425       num = *(guint64 *) map.data;
426       fail_unless (i == num);
427       fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
428               GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
429       fail_unless (GST_BUFFER_DURATION (buffer) ==
430           gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
431               TEST_VIDEO_FPS_N));
432 
433       gst_buffer_unmap (buffer, &map);
434       iter = g_list_next (iter);
435     }
436   }
437   fail_unless (iter == NULL);
438 
439   /* check that EOS was received */
440   {
441     GstEvent *eos = events_iter->data;
442 
443     fail_unless (GST_EVENT_TYPE (eos) == GST_EVENT_EOS);
444     events_iter = g_list_next (events_iter);
445   }
446 
447   fail_unless (events_iter == NULL);
448 
449   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
450   buffers = NULL;
451 
452   cleanup_videodecodertest ();
453 }
454 
455 GST_END_TEST;
456 
GST_START_TEST(videodecoder_flush_events)457 GST_START_TEST (videodecoder_flush_events)
458 {
459   GstSegment segment;
460   GstBuffer *buffer;
461   guint i;
462   GList *events_iter;
463 
464   setup_videodecodertester (NULL, NULL);
465 
466   gst_pad_set_active (mysrcpad, TRUE);
467   gst_element_set_state (dec, GST_STATE_PLAYING);
468   gst_pad_set_active (mysinkpad, TRUE);
469 
470   send_startup_events ();
471 
472   /* push a new segment */
473   gst_segment_init (&segment, GST_FORMAT_TIME);
474   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
475 
476   /* push buffers, the data is actually a number so we can track them */
477   for (i = 0; i < NUM_BUFFERS; i++) {
478     if (i % 10 == 0) {
479       GstTagList *tags;
480 
481       tags = gst_tag_list_new (GST_TAG_TRACK_NUMBER, i, NULL);
482       fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_tag (tags)));
483     } else {
484       buffer = create_test_buffer (i);
485 
486       fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
487     }
488   }
489 
490   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
491 
492   events_iter = events;
493   /* make sure the usual events have been received */
494   {
495     GstEvent *sstart = events_iter->data;
496     fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
497     events_iter = g_list_next (events_iter);
498   }
499   {
500     GstEvent *caps_event = events_iter->data;
501     fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
502     events_iter = g_list_next (events_iter);
503   }
504   {
505     GstEvent *segment_event = events_iter->data;
506     fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
507     events_iter = g_list_next (events_iter);
508   }
509 
510   /* check that EOS was received */
511   fail_unless (GST_PAD_IS_EOS (mysrcpad));
512   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_start ()));
513   fail_unless (GST_PAD_IS_EOS (mysrcpad));
514 
515   /* Check that we have tags */
516   {
517     GstEvent *tags = gst_pad_get_sticky_event (mysrcpad, GST_EVENT_TAG, 0);
518 
519     fail_unless (tags != NULL);
520     gst_event_unref (tags);
521   }
522 
523   /* Check that we still have a segment set */
524   {
525     GstEvent *segment =
526         gst_pad_get_sticky_event (mysrcpad, GST_EVENT_SEGMENT, 0);
527 
528     fail_unless (segment != NULL);
529     gst_event_unref (segment);
530   }
531 
532   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_stop (TRUE)));
533   fail_if (GST_PAD_IS_EOS (mysrcpad));
534 
535   /* Check that the segment was flushed on FLUSH_STOP */
536   {
537     GstEvent *segment =
538         gst_pad_get_sticky_event (mysrcpad, GST_EVENT_SEGMENT, 0);
539 
540     fail_unless (segment == NULL);
541   }
542 
543   /* Check the tags were not lost on FLUSH_STOP */
544   {
545     GstEvent *tags = gst_pad_get_sticky_event (mysrcpad, GST_EVENT_TAG, 0);
546 
547     fail_unless (tags != NULL);
548     gst_event_unref (tags);
549 
550   }
551 
552   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
553   buffers = NULL;
554 
555   cleanup_videodecodertest ();
556 }
557 
558 GST_END_TEST;
559 
560 
561 /* Check https://bugzilla.gnome.org/show_bug.cgi?id=721835 */
GST_START_TEST(videodecoder_playback_first_frames_not_decoded)562 GST_START_TEST (videodecoder_playback_first_frames_not_decoded)
563 {
564   GstSegment segment;
565   GstBuffer *buffer;
566   guint64 i = 0;
567 
568   setup_videodecodertester (NULL, NULL);
569 
570   gst_pad_set_active (mysrcpad, TRUE);
571   gst_element_set_state (dec, GST_STATE_PLAYING);
572   gst_pad_set_active (mysinkpad, TRUE);
573 
574   send_startup_events ();
575 
576   /* push a new segment */
577   gst_segment_init (&segment, GST_FORMAT_TIME);
578   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
579 
580   /* push a buffer, to have the segment attached to it.
581    * unfortunatelly this buffer can't be decoded as it isn't a keyframe */
582   buffer = create_test_buffer (i++);
583   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
584   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
585 
586   /* now be evil and ask this frame to be released
587    * this frame has the segment event attached to it, and the
588    * segment shouldn't disappear with it */
589   {
590     GList *l, *ol;
591 
592     ol = l = gst_video_decoder_get_frames (GST_VIDEO_DECODER (dec));
593     fail_unless (g_list_length (l) == 1);
594     while (l) {
595       GstVideoCodecFrame *tmp = l->data;
596 
597       gst_video_decoder_release_frame (GST_VIDEO_DECODER (dec), tmp);
598 
599       l = g_list_next (l);
600     }
601     g_list_free (ol);
602   }
603 
604   buffer = create_test_buffer (i++);
605   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
606 
607   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
608 
609   fail_unless (g_list_length (buffers) == 1);
610 
611   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
612   buffers = NULL;
613 
614   cleanup_videodecodertest ();
615 }
616 
617 GST_END_TEST;
618 
GST_START_TEST(videodecoder_buffer_after_segment)619 GST_START_TEST (videodecoder_buffer_after_segment)
620 {
621   GstSegment segment;
622   GstBuffer *buffer;
623   guint64 i;
624   GstClockTime pos;
625   GList *iter;
626 
627   setup_videodecodertester (NULL, NULL);
628 
629   gst_pad_set_active (mysrcpad, TRUE);
630   gst_element_set_state (dec, GST_STATE_PLAYING);
631   gst_pad_set_active (mysinkpad, TRUE);
632 
633   send_startup_events ();
634 
635   /* push a new segment */
636   gst_segment_init (&segment, GST_FORMAT_TIME);
637   segment.stop = GST_SECOND;
638   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
639 
640   /* push buffers until we fill our segment */
641   i = 0;
642   pos = 0;
643   while (pos < GST_SECOND) {
644     buffer = create_test_buffer (i++);
645 
646     pos = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
647     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
648   }
649 
650   /* pushing the next buffer should result in EOS */
651   buffer = create_test_buffer (i);
652   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_EOS);
653 
654   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
655 
656   /* check that all buffers were received by our source pad */
657   fail_unless (g_list_length (buffers) == i);
658   i = 0;
659   for (iter = buffers; iter; iter = g_list_next (iter)) {
660     GstMapInfo map;
661     guint64 num;
662 
663     buffer = iter->data;
664 
665     gst_buffer_map (buffer, &map, GST_MAP_READ);
666 
667 
668     num = *(guint64 *) map.data;
669     fail_unless (i == num);
670     fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
671             GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
672     fail_unless (GST_BUFFER_DURATION (buffer) ==
673         gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
674             TEST_VIDEO_FPS_N));
675 
676     gst_buffer_unmap (buffer, &map);
677     i++;
678   }
679 
680   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
681   buffers = NULL;
682 
683   cleanup_videodecodertest ();
684 }
685 
686 GST_END_TEST;
687 
688 /* make sure that the segment event is pushed before the gap */
GST_START_TEST(videodecoder_first_data_is_gap)689 GST_START_TEST (videodecoder_first_data_is_gap)
690 {
691   GstSegment segment;
692   GList *events_iter;
693 
694   setup_videodecodertester (NULL, NULL);
695 
696   gst_pad_set_active (mysrcpad, TRUE);
697   gst_element_set_state (dec, GST_STATE_PLAYING);
698   gst_pad_set_active (mysinkpad, TRUE);
699 
700   send_startup_events ();
701 
702   /* push a new segment */
703   gst_segment_init (&segment, GST_FORMAT_TIME);
704   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
705 
706   /* push a gap */
707   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_gap (0,
708               GST_SECOND)));
709   events_iter = events;
710   /* make sure the usual events have been received */
711   {
712     GstEvent *sstart = events_iter->data;
713     fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
714     events_iter = g_list_next (events_iter);
715   }
716   {
717     GstEvent *caps_event = events_iter->data;
718     fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
719     events_iter = g_list_next (events_iter);
720   }
721   {
722     GstEvent *segment_event = events_iter->data;
723     fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
724     events_iter = g_list_next (events_iter);
725   }
726 
727   /* Make sure the gap was pushed */
728   {
729     GstEvent *gap = events_iter->data;
730     fail_unless (GST_EVENT_TYPE (gap) == GST_EVENT_GAP);
731     events_iter = g_list_next (events_iter);
732   }
733   fail_unless (events_iter == NULL);
734 
735   cleanup_videodecodertest ();
736 }
737 
738 GST_END_TEST;
739 
GST_START_TEST(videodecoder_backwards_playback)740 GST_START_TEST (videodecoder_backwards_playback)
741 {
742   GstSegment segment;
743   GstBuffer *buffer;
744   guint64 i;
745   GList *iter;
746 
747   setup_videodecodertester (NULL, NULL);
748 
749   gst_pad_set_active (mysrcpad, TRUE);
750   gst_element_set_state (dec, GST_STATE_PLAYING);
751   gst_pad_set_active (mysinkpad, TRUE);
752 
753   send_startup_events ();
754 
755   /* push a new segment with -1 rate */
756   gst_segment_init (&segment, GST_FORMAT_TIME);
757   segment.rate = -1.0;
758   segment.stop = (NUM_BUFFERS + 1) * gst_util_uint64_scale_round (GST_SECOND,
759       TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N);
760   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
761 
762   /* push buffers, the data is actually a number so we can track them */
763   i = NUM_BUFFERS;
764   while (i > 0) {
765     gint target = i;
766     gint j;
767 
768     /* push groups of 10 buffers
769      * every number that is divisible by 10 is set as a discont,
770      * if it is divisible by 20 it is also a keyframe
771      *
772      * The logic here is that hte current i is the target, and then
773      * it pushes buffers from 'target - 10' up to target.
774      */
775     for (j = MAX (target - 10, 0); j < target; j++) {
776       GstBuffer *buffer = create_test_buffer (j);
777 
778       if (j % 10 == 0)
779         GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
780       if (j % 20 != 0)
781         GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
782 
783       fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
784       i--;
785     }
786   }
787 
788   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
789 
790   /* check that all buffers were received by our source pad */
791   fail_unless (g_list_length (buffers) == NUM_BUFFERS);
792   i = NUM_BUFFERS - 1;
793   for (iter = buffers; iter; iter = g_list_next (iter)) {
794     GstMapInfo map;
795     guint64 num;
796 
797     buffer = iter->data;
798 
799     gst_buffer_map (buffer, &map, GST_MAP_READ);
800 
801 
802     num = *(guint64 *) map.data;
803     fail_unless (i == num);
804     fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
805             GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
806     fail_unless (GST_BUFFER_DURATION (buffer) ==
807         gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
808             TEST_VIDEO_FPS_N));
809 
810     gst_buffer_unmap (buffer, &map);
811     i--;
812   }
813 
814   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
815   buffers = NULL;
816 
817   cleanup_videodecodertest ();
818 }
819 
820 GST_END_TEST;
821 
822 
GST_START_TEST(videodecoder_backwards_buffer_after_segment)823 GST_START_TEST (videodecoder_backwards_buffer_after_segment)
824 {
825   GstSegment segment;
826   GstBuffer *buffer;
827   guint64 i;
828   GstClockTime pos;
829 
830   setup_videodecodertester (NULL, NULL);
831 
832   gst_pad_set_active (mysrcpad, TRUE);
833   gst_element_set_state (dec, GST_STATE_PLAYING);
834   gst_pad_set_active (mysinkpad, TRUE);
835 
836   send_startup_events ();
837 
838   /* push a new segment with -1 rate */
839   gst_segment_init (&segment, GST_FORMAT_TIME);
840   segment.rate = -1.0;
841   segment.start = GST_SECOND;
842   segment.stop = (NUM_BUFFERS + 1) * gst_util_uint64_scale_round (GST_SECOND,
843       TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N);
844   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
845 
846   /* push buffers, the data is actually a number so we can track them */
847   i = NUM_BUFFERS;
848   pos = segment.stop;
849   while (pos >= GST_SECOND) {
850     gint target = i;
851     gint j;
852 
853     g_assert (i > 0);
854 
855     /* push groups of 10 buffers
856      * every number that is divisible by 10 is set as a discont,
857      * if it is divisible by 20 it is also a keyframe
858      *
859      * The logic here is that hte current i is the target, and then
860      * it pushes buffers from 'target - 10' up to target.
861      */
862     for (j = MAX (target - 10, 0); j < target; j++) {
863       buffer = create_test_buffer (j);
864 
865       pos = MIN (GST_BUFFER_TIMESTAMP (buffer), pos);
866       if (j % 10 == 0)
867         GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
868       if (j % 20 != 0)
869         GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
870 
871       fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
872       i--;
873     }
874   }
875 
876   /* push a discont buffer so it flushes the decoding */
877   buffer = create_test_buffer (i - 10);
878   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
879   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
880   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_EOS);
881 
882   /* check that the last received buffer doesn't contain a
883    * timestamp before the segment */
884   buffer = g_list_last (buffers)->data;
885   fail_unless (GST_BUFFER_TIMESTAMP (buffer) <= segment.start
886       && GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) >
887       segment.start);
888 
889   /* flush our decoded data queue */
890   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
891   buffers = NULL;
892 
893   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
894 
895   fail_unless (buffers == NULL);
896 
897   cleanup_videodecodertest ();
898 }
899 
900 GST_END_TEST;
901 
902 
GST_START_TEST(videodecoder_query_caps_with_fixed_caps_peer)903 GST_START_TEST (videodecoder_query_caps_with_fixed_caps_peer)
904 {
905   GstCaps *caps;
906   GstCaps *filter;
907   GstStructure *structure;
908   gint width, height, fps_n, fps_d;
909 
910   setup_videodecodertester (&sinktemplate_restricted, NULL);
911 
912   gst_pad_set_active (mysrcpad, TRUE);
913   gst_element_set_state (dec, GST_STATE_PLAYING);
914   gst_pad_set_active (mysinkpad, TRUE);
915 
916   caps = gst_pad_peer_query_caps (mysrcpad, NULL);
917   fail_unless (caps != NULL);
918 
919   structure = gst_caps_get_structure (caps, 0);
920   fail_unless (gst_structure_get_int (structure, "width", &width));
921   fail_unless (gst_structure_get_int (structure, "height", &height));
922   fail_unless (gst_structure_get_fraction (structure, "framerate", &fps_n,
923           &fps_d));
924   /* match our restricted caps values */
925   fail_unless (width == RESTRICTED_CAPS_WIDTH);
926   fail_unless (height == RESTRICTED_CAPS_HEIGHT);
927   fail_unless (fps_n == RESTRICTED_CAPS_FPS_N);
928   fail_unless (fps_d == RESTRICTED_CAPS_FPS_D);
929   gst_caps_unref (caps);
930 
931   filter = gst_caps_new_simple ("video/x-custom-test", "width", G_TYPE_INT,
932       1000, "height", G_TYPE_INT, 1000, "framerate", GST_TYPE_FRACTION,
933       1000, 1, NULL);
934   caps = gst_pad_peer_query_caps (mysrcpad, filter);
935   fail_unless (caps != NULL);
936   fail_unless (gst_caps_is_empty (caps));
937   gst_caps_unref (caps);
938   gst_caps_unref (filter);
939 
940   cleanup_videodecodertest ();
941 }
942 
943 GST_END_TEST;
944 
945 static void
_get_int_range(GstStructure * s,const gchar * field,gint * min_v,gint * max_v)946 _get_int_range (GstStructure * s, const gchar * field, gint * min_v,
947     gint * max_v)
948 {
949   const GValue *value;
950 
951   value = gst_structure_get_value (s, field);
952   fail_unless (value != NULL);
953   fail_unless (GST_VALUE_HOLDS_INT_RANGE (value));
954 
955   *min_v = gst_value_get_int_range_min (value);
956   *max_v = gst_value_get_int_range_max (value);
957 }
958 
959 static void
_get_fraction_range(GstStructure * s,const gchar * field,gint * fps_n_min,gint * fps_d_min,gint * fps_n_max,gint * fps_d_max)960 _get_fraction_range (GstStructure * s, const gchar * field, gint * fps_n_min,
961     gint * fps_d_min, gint * fps_n_max, gint * fps_d_max)
962 {
963   const GValue *value;
964   const GValue *min_v, *max_v;
965 
966   value = gst_structure_get_value (s, field);
967   fail_unless (value != NULL);
968   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (value));
969 
970   min_v = gst_value_get_fraction_range_min (value);
971   fail_unless (GST_VALUE_HOLDS_FRACTION (min_v));
972   *fps_n_min = gst_value_get_fraction_numerator (min_v);
973   *fps_d_min = gst_value_get_fraction_denominator (min_v);
974 
975   max_v = gst_value_get_fraction_range_max (value);
976   fail_unless (GST_VALUE_HOLDS_FRACTION (max_v));
977   *fps_n_max = gst_value_get_fraction_numerator (max_v);
978   *fps_d_max = gst_value_get_fraction_denominator (max_v);
979 }
980 
GST_START_TEST(videodecoder_query_caps_with_range_caps_peer)981 GST_START_TEST (videodecoder_query_caps_with_range_caps_peer)
982 {
983   GstCaps *caps;
984   GstCaps *filter;
985   GstStructure *structure;
986   gint width, height, fps_n, fps_d;
987   gint width_min, height_min, fps_n_min, fps_d_min;
988   gint width_max, height_max, fps_n_max, fps_d_max;
989 
990   setup_videodecodertester (&sinktemplate_with_range, NULL);
991 
992   gst_pad_set_active (mysrcpad, TRUE);
993   gst_element_set_state (dec, GST_STATE_PLAYING);
994   gst_pad_set_active (mysinkpad, TRUE);
995 
996   caps = gst_pad_peer_query_caps (mysrcpad, NULL);
997   fail_unless (caps != NULL);
998 
999   structure = gst_caps_get_structure (caps, 0);
1000   _get_int_range (structure, "width", &width_min, &width_max);
1001   _get_int_range (structure, "height", &height_min, &height_max);
1002   _get_fraction_range (structure, "framerate", &fps_n_min, &fps_d_min,
1003       &fps_n_max, &fps_d_max);
1004   fail_unless (width_min == 1);
1005   fail_unless (width_max == RESTRICTED_CAPS_WIDTH);
1006   fail_unless (height_min == 1);
1007   fail_unless (height_max == RESTRICTED_CAPS_HEIGHT);
1008   fail_unless (fps_n_min == 1);
1009   fail_unless (fps_d_min == 1);
1010   fail_unless (fps_n_max == RESTRICTED_CAPS_FPS_N);
1011   fail_unless (fps_d_max == RESTRICTED_CAPS_FPS_D);
1012   gst_caps_unref (caps);
1013 
1014   /* query with a fixed filter */
1015   filter = gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
1016       RESTRICTED_CAPS_WIDTH, "height", G_TYPE_INT, RESTRICTED_CAPS_HEIGHT,
1017       "framerate", GST_TYPE_FRACTION, RESTRICTED_CAPS_FPS_N,
1018       RESTRICTED_CAPS_FPS_D, NULL);
1019   caps = gst_pad_peer_query_caps (mysrcpad, filter);
1020   fail_unless (caps != NULL);
1021   structure = gst_caps_get_structure (caps, 0);
1022   fail_unless (gst_structure_get_int (structure, "width", &width));
1023   fail_unless (gst_structure_get_int (structure, "height", &height));
1024   fail_unless (gst_structure_get_fraction (structure, "framerate", &fps_n,
1025           &fps_d));
1026   fail_unless (width == RESTRICTED_CAPS_WIDTH);
1027   fail_unless (height == RESTRICTED_CAPS_HEIGHT);
1028   fail_unless (fps_n == RESTRICTED_CAPS_FPS_N);
1029   fail_unless (fps_d == RESTRICTED_CAPS_FPS_D);
1030   gst_caps_unref (caps);
1031   gst_caps_unref (filter);
1032 
1033   /* query with a fixed filter that will lead to empty result */
1034   filter = gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
1035       1000, "height", G_TYPE_INT, 1000, "framerate", GST_TYPE_FRACTION,
1036       1000, 1, NULL);
1037   caps = gst_pad_peer_query_caps (mysrcpad, filter);
1038   fail_unless (caps != NULL);
1039   fail_unless (gst_caps_is_empty (caps));
1040   gst_caps_unref (caps);
1041   gst_caps_unref (filter);
1042 
1043   cleanup_videodecodertest ();
1044 }
1045 
1046 GST_END_TEST;
1047 
1048 #define GETCAPS_CAPS_STR "video/x-test-custom, somefield=(string)getcaps"
1049 static GstCaps *
_custom_video_decoder_getcaps(GstVideoDecoder * dec,GstCaps * filter)1050 _custom_video_decoder_getcaps (GstVideoDecoder * dec, GstCaps * filter)
1051 {
1052   return gst_caps_from_string (GETCAPS_CAPS_STR);
1053 }
1054 
GST_START_TEST(videodecoder_query_caps_with_custom_getcaps)1055 GST_START_TEST (videodecoder_query_caps_with_custom_getcaps)
1056 {
1057   GstCaps *caps;
1058   GstVideoDecoderClass *klass;
1059   GstCaps *expected_caps;
1060 
1061   setup_videodecodertester (&sinktemplate_restricted, NULL);
1062 
1063   klass = GST_VIDEO_DECODER_CLASS (GST_VIDEO_DECODER_GET_CLASS (dec));
1064   klass->getcaps = _custom_video_decoder_getcaps;
1065 
1066   gst_pad_set_active (mysrcpad, TRUE);
1067   gst_element_set_state (dec, GST_STATE_PLAYING);
1068   gst_pad_set_active (mysinkpad, TRUE);
1069 
1070   caps = gst_pad_peer_query_caps (mysrcpad, NULL);
1071   fail_unless (caps != NULL);
1072 
1073   expected_caps = gst_caps_from_string (GETCAPS_CAPS_STR);
1074   fail_unless (gst_caps_is_equal (expected_caps, caps));
1075   gst_caps_unref (expected_caps);
1076   gst_caps_unref (caps);
1077 
1078   cleanup_videodecodertest ();
1079 }
1080 
1081 GST_END_TEST;
1082 
1083 static const gchar *test_default_caps[][2] = {
1084   {
1085         "video/x-test-custom",
1086       "video/x-raw, format=I420, width=1280, height=720, framerate=0/1, multiview-mode=mono"}, {
1087         "video/x-test-custom, width=1000",
1088       "video/x-raw, format=I420, width=1000, height=720, framerate=0/1, multiview-mode=mono"}, {
1089         "video/x-test-custom, height=500",
1090       "video/x-raw, format=I420, width=1280, height=500, framerate=0/1, multiview-mode=mono"}, {
1091         "video/x-test-custom, framerate=10/1",
1092       "video/x-raw, format=I420, width=1280, height=720, framerate=10/1, multiview-mode=mono"}, {
1093         "video/x-test-custom, pixel-aspect-ratio=2/1",
1094       "video/x-raw, format=I420, width=1280, height=720, framerate=0/1,"
1095         "pixel-aspect-ratio=2/1, multiview-mode=mono"}
1096 };
1097 
GST_START_TEST(videodecoder_default_caps_on_gap_before_buffer)1098 GST_START_TEST (videodecoder_default_caps_on_gap_before_buffer)
1099 {
1100   GstVideoDecoderTester *dec =
1101       g_object_new (GST_VIDEO_DECODER_TESTER_TYPE, NULL);
1102   GstHarness *h =
1103       gst_harness_new_with_element (GST_ELEMENT (dec), "sink", "src");
1104   GstEvent *event;
1105   GstCaps *caps1, *caps2;
1106   GstVideoInfo info1, info2;
1107 
1108   /* Don't set output state since we want trigger the default output caps */
1109   dec->set_output_state = FALSE;
1110   gst_harness_set_src_caps_str (h, test_default_caps[__i__][0]);
1111 
1112   fail_unless (gst_harness_push_event (h, gst_event_new_gap (0, GST_SECOND)));
1113 
1114   fail_unless_equals_int (gst_harness_events_received (h), 4);
1115 
1116   event = gst_harness_pull_event (h);
1117   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
1118   gst_event_unref (event);
1119 
1120   event = gst_harness_pull_event (h);
1121   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
1122   gst_event_unref (event);
1123 
1124   event = gst_harness_pull_event (h);
1125   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1126   gst_event_unref (event);
1127 
1128   event = gst_harness_pull_event (h);
1129   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_GAP);
1130   gst_event_unref (event);
1131 
1132   caps1 = gst_pad_get_current_caps (h->sinkpad);
1133   caps2 = gst_caps_from_string (test_default_caps[__i__][1]);
1134   gst_video_info_from_caps (&info1, caps1);
1135   gst_video_info_from_caps (&info2, caps2);
1136 
1137   gst_caps_unref (caps1);
1138   gst_caps_unref (caps2);
1139 
1140   fail_unless (gst_video_info_is_equal (&info1, &info2));
1141 
1142   gst_harness_teardown (h);
1143   gst_object_unref (dec);
1144 }
1145 
1146 GST_END_TEST;
1147 
GST_START_TEST(videodecoder_playback_event_order)1148 GST_START_TEST (videodecoder_playback_event_order)
1149 {
1150   GstSegment segment;
1151   GstBuffer *buffer;
1152   guint i = 0;
1153   GList *events_iter;
1154 
1155   setup_videodecodertester (NULL, NULL);
1156 
1157   gst_pad_set_active (mysrcpad, TRUE);
1158   gst_element_set_state (dec, GST_STATE_PLAYING);
1159   gst_pad_set_active (mysinkpad, TRUE);
1160 
1161   send_startup_events ();
1162 
1163   /* push a new segment */
1164   gst_segment_init (&segment, GST_FORMAT_TIME);
1165   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
1166 
1167   /* push 5 buffer with one event each. All buffers except the last
1168    * one are dropped in some way, so the events are collected in various
1169    * places. The order must be preserved.
1170    * With the first buffer the segment event is added to the pending event
1171    * list to ensure that incorrect ordering can be detected for later
1172    * events.
1173    */
1174   for (i = 0; i < 9; i++) {
1175     if (i % 2 == 0) {
1176       buffer = create_test_buffer (i);
1177       if (i < 8)
1178         GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
1179       fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
1180       if (i < 6) {
1181         GList *l, *ol;
1182 
1183         ol = l = gst_video_decoder_get_frames (GST_VIDEO_DECODER (dec));
1184         fail_unless (g_list_length (l) == 1);
1185         while (l) {
1186           GstVideoCodecFrame *tmp = l->data;
1187 
1188           if (i < 4)
1189             gst_video_decoder_release_frame (GST_VIDEO_DECODER (dec), tmp);
1190           else
1191             gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), tmp);
1192 
1193           l = g_list_next (l);
1194         }
1195         g_list_free (ol);
1196       }
1197     } else {
1198       GstTagList *tags;
1199       tags = gst_tag_list_new (GST_TAG_TRACK_NUMBER, i, NULL);
1200       fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_tag (tags)));
1201     }
1202   }
1203 
1204   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
1205 
1206   events_iter = events;
1207   /* make sure the usual events have been received */
1208   {
1209     GstEvent *sstart = events_iter->data;
1210     fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
1211     events_iter = g_list_next (events_iter);
1212   }
1213   {
1214     GstEvent *caps_event = events_iter->data;
1215     fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
1216     events_iter = g_list_next (events_iter);
1217   }
1218   {
1219     GstEvent *segment_event = events_iter->data;
1220     fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
1221     events_iter = g_list_next (events_iter);
1222   }
1223 
1224   /* Check the order of the tag events */
1225   for (i = 1; i < 9; i += 2) {
1226     guint tag_v;
1227     GstEvent *tag_event = events_iter->data;
1228     GstTagList *taglist = NULL;
1229 
1230     fail_unless (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG);
1231     gst_event_parse_tag (tag_event, &taglist);
1232 
1233     fail_unless (gst_tag_list_get_uint (taglist, GST_TAG_TRACK_NUMBER, &tag_v));
1234     fail_unless (tag_v == i);
1235 
1236     events_iter = g_list_next (events_iter);
1237   }
1238 
1239   /* check that EOS was received */
1240   {
1241     GstEvent *eos = events_iter->data;
1242 
1243     fail_unless (GST_EVENT_TYPE (eos) == GST_EVENT_EOS);
1244     events_iter = g_list_next (events_iter);
1245   }
1246 
1247   fail_unless (events_iter == NULL);
1248 
1249   g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
1250   buffers = NULL;
1251 
1252   cleanup_videodecodertest ();
1253 }
1254 
1255 GST_END_TEST;
1256 
1257 static Suite *
gst_videodecoder_suite(void)1258 gst_videodecoder_suite (void)
1259 {
1260   Suite *s = suite_create ("GstVideoDecoder");
1261   TCase *tc = tcase_create ("general");
1262 
1263   suite_add_tcase (s, tc);
1264 
1265   tcase_add_test (tc, videodecoder_query_caps_with_fixed_caps_peer);
1266   tcase_add_test (tc, videodecoder_query_caps_with_range_caps_peer);
1267   tcase_add_test (tc, videodecoder_query_caps_with_custom_getcaps);
1268 
1269   tcase_add_test (tc, videodecoder_playback);
1270   tcase_add_test (tc, videodecoder_playback_with_events);
1271   tcase_add_test (tc, videodecoder_playback_first_frames_not_decoded);
1272   tcase_add_test (tc, videodecoder_buffer_after_segment);
1273   tcase_add_test (tc, videodecoder_first_data_is_gap);
1274 
1275   tcase_add_test (tc, videodecoder_backwards_playback);
1276   tcase_add_test (tc, videodecoder_backwards_buffer_after_segment);
1277   tcase_add_test (tc, videodecoder_flush_events);
1278 
1279   tcase_add_loop_test (tc, videodecoder_default_caps_on_gap_before_buffer, 0,
1280       G_N_ELEMENTS (test_default_caps));
1281 
1282   tcase_add_test (tc, videodecoder_playback_event_order);
1283 
1284   return s;
1285 }
1286 
1287 GST_CHECK_MAIN (gst_videodecoder);
1288