tests: videodecoder: audiodecoder: add tests for eos after segment
authorThiago Santos <ts.santos@sisa.samsung.com>
Mon, 26 May 2014 23:57:30 +0000 (20:57 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Tue, 27 May 2014 02:24:56 +0000 (23:24 -0300)
Tests that pushing a buffer after the segment returns EOS

tests/check/libs/audiodecoder.c
tests/check/libs/videodecoder.c

index 5d2e182..52b6b12 100644 (file)
@@ -416,6 +416,69 @@ GST_START_TEST (audiodecoder_delayed_negotiation_with_gap_event)
 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)
 {
@@ -427,6 +490,7 @@ 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;
 }
index 628a48b..b8a2c49 100644 (file)
@@ -481,6 +481,74 @@ GST_START_TEST (videodecoder_playback_first_frames_not_decoded)
 
 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)
 {
@@ -563,6 +631,88 @@ 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)
 {
@@ -573,8 +723,10 @@ 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;
 }