GST_END_TEST;
+GST_START_TEST (audiodecoder_buffer_after_segment)
+{
+ GstSegment segment;
+ GstBuffer *buffer;
+ guint64 i;
+ GstClockTime pos;
+
+ setup_audiodecodertester ();
+
+ gst_pad_set_active (mysrcpad, TRUE);
+ gst_element_set_state (dec, GST_STATE_PLAYING);
+ gst_pad_set_active (mysinkpad, TRUE);
+
+ send_startup_events ();
+
+ /* push a new segment */
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ segment.stop = GST_SECOND;
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+ /* push buffers, the data is actually a number so we can track them */
+ i = 0;
+ pos = 0;
+ while (pos < GST_SECOND) {
+ GstMapInfo map;
+ guint64 num;
+
+ buffer = create_test_buffer (i);
+ pos = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
+
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+
+ /* check that buffer was received by our source pad */
+ buffer = buffers->data;
+
+ gst_buffer_map (buffer, &map, GST_MAP_READ);
+
+ num = *(guint64 *) map.data;
+ fail_unless_equals_uint64 (i, num);
+ fail_unless_equals_uint64 (GST_BUFFER_PTS (buffer),
+ gst_util_uint64_scale_round (i, GST_SECOND, TEST_MSECS_PER_SAMPLE));
+ fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer),
+ gst_util_uint64_scale_round (1, GST_SECOND, TEST_MSECS_PER_SAMPLE));
+
+ gst_buffer_unmap (buffer, &map);
+
+ gst_buffer_unref (buffer);
+ buffers = g_list_delete_link (buffers, buffers);
+ i++;
+ }
+
+ /* this buffer is after the segment */
+ buffer = create_test_buffer (i++);
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_EOS);
+
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
+
+ fail_unless (buffers == NULL);
+
+ cleanup_audiodecodertest ();
+}
+
+GST_END_TEST;
static Suite *
gst_audiodecoder_suite (void)
{
tcase_add_test (tc, audiodecoder_negotiation_with_buffer);
tcase_add_test (tc, audiodecoder_negotiation_with_gap_event);
tcase_add_test (tc, audiodecoder_delayed_negotiation_with_gap_event);
+ tcase_add_test (tc, audiodecoder_buffer_after_segment);
return s;
}
GST_END_TEST;
+GST_START_TEST (videodecoder_buffer_after_segment)
+{
+ GstSegment segment;
+ GstBuffer *buffer;
+ guint64 i;
+ GstClockTime pos;
+ GList *iter;
+
+ setup_videodecodertester ();
+
+ gst_pad_set_active (mysrcpad, TRUE);
+ gst_element_set_state (dec, GST_STATE_PLAYING);
+ gst_pad_set_active (mysinkpad, TRUE);
+
+ send_startup_events ();
+
+ /* push a new segment */
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ segment.stop = GST_SECOND;
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+ /* push buffers until we fill our segment */
+ i = 0;
+ while (pos < GST_SECOND) {
+ buffer = create_test_buffer (i++);
+
+ pos = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+ }
+
+ /* pushing the next buffer should result in EOS */
+ buffer = create_test_buffer (i);
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_EOS);
+
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
+
+ /* check that all buffers were received by our source pad */
+ fail_unless (g_list_length (buffers) == i);
+ i = 0;
+ for (iter = buffers; iter; iter = g_list_next (iter)) {
+ GstMapInfo map;
+ guint64 num;
+
+ buffer = iter->data;
+
+ gst_buffer_map (buffer, &map, GST_MAP_READ);
+
+
+ num = *(guint64 *) map.data;
+ fail_unless (i == num);
+ fail_unless (GST_BUFFER_PTS (buffer) == gst_util_uint64_scale_round (i,
+ GST_SECOND * TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N));
+ fail_unless (GST_BUFFER_DURATION (buffer) ==
+ gst_util_uint64_scale_round (GST_SECOND, TEST_VIDEO_FPS_D,
+ TEST_VIDEO_FPS_N));
+
+ gst_buffer_unmap (buffer, &map);
+ i++;
+ }
+
+ g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
+ buffers = NULL;
+
+ cleanup_videodecodertest ();
+}
+
+GST_END_TEST;
+
GST_START_TEST (videodecoder_backwards_playback)
{
}
GST_END_TEST;
+
+
+GST_START_TEST (videodecoder_backwards_buffer_after_segment)
+{
+ GstSegment segment;
+ GstBuffer *buffer;
+ guint64 i;
+ GstClockTime pos;
+
+ setup_videodecodertester ();
+
+ gst_pad_set_active (mysrcpad, TRUE);
+ gst_element_set_state (dec, GST_STATE_PLAYING);
+ gst_pad_set_active (mysinkpad, TRUE);
+
+ send_startup_events ();
+
+ /* push a new segment with -1 rate */
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ segment.rate = -1.0;
+ segment.start = GST_SECOND;
+ segment.stop = (NUM_BUFFERS + 1) * gst_util_uint64_scale_round (GST_SECOND,
+ TEST_VIDEO_FPS_D, TEST_VIDEO_FPS_N);
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+ /* push buffers, the data is actually a number so we can track them */
+ i = NUM_BUFFERS;
+ pos = segment.stop;
+ while (pos >= GST_SECOND) {
+ gint target = i;
+ gint j;
+
+ g_assert (i > 0);
+
+ /* push groups of 10 buffers
+ * every number that is divisible by 10 is set as a discont,
+ * if it is divisible by 20 it is also a keyframe
+ *
+ * The logic here is that hte current i is the target, and then
+ * it pushes buffers from 'target - 10' up to target.
+ */
+ for (j = MAX (target - 10, 0); j < target; j++) {
+ buffer = create_test_buffer (j);
+
+ pos = MIN (GST_BUFFER_TIMESTAMP (buffer), pos);
+ if (j % 10 == 0)
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
+ if (j % 20 != 0)
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+ i--;
+ }
+ }
+
+ /* push a discont buffer so it flushes the decoding */
+ buffer = create_test_buffer (i - 10);
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_EOS);
+
+ /* check that the last received buffer doesn't contain a
+ * timestamp before the segment */
+ buffer = g_list_last (buffers)->data;
+ fail_unless (GST_BUFFER_TIMESTAMP (buffer) <= segment.start
+ && GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) >
+ segment.start);
+
+ /* flush our decoded data queue */
+ g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
+ buffers = NULL;
+
+ fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
+
+ fail_unless (buffers == NULL);
+
+ cleanup_videodecodertest ();
+}
+
+GST_END_TEST;
+
+
static Suite *
gst_videodecoder_suite (void)
{
tcase_add_test (tc, videodecoder_playback);
tcase_add_test (tc, videodecoder_playback_with_events);
tcase_add_test (tc, videodecoder_playback_first_frames_not_decoded);
+ tcase_add_test (tc, videodecoder_buffer_after_segment);
tcase_add_test (tc, videodecoder_backwards_playback);
+ tcase_add_test (tc, videodecoder_backwards_buffer_after_segment);
return s;
}