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