tests: videodecoder: check that segment events are not dropped
authorThiago Santos <ts.santos@sisa.samsung.com>
Sat, 11 Jan 2014 04:14:19 +0000 (01:14 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Mon, 13 Jan 2014 09:11:09 +0000 (06:11 -0300)
Adds a test that simulates a scenario where the first buffers after
a segment can't be decoded and the decoder asks for those frames
to be released. The videodecoder base class should make sure that
the events attached to those first buffers are pushed even if the
buffers aren't going to be.

https://bugzilla.gnome.org/show_bug.cgi?id=721835

tests/check/libs/videodecoder.c

index 6838529c81cccdc6c5909d6975fa15a10764f933..7f6bb98ec25bf416e591e1e64d8580e472fed359 100644 (file)
@@ -111,7 +111,8 @@ gst_video_decoder_tester_handle_frame (GstVideoDecoder * dec,
 
   input_num = *((guint64 *) map.data);
 
-  if (input_num == dectester->last_buf_num + 1
+  if ((input_num == dectester->last_buf_num + 1
+          && dectester->last_buf_num != -1)
       || !GST_BUFFER_FLAG_IS_SET (frame->input_buffer,
           GST_BUFFER_FLAG_DELTA_UNIT)) {
 
@@ -134,6 +135,7 @@ gst_video_decoder_tester_handle_frame (GstVideoDecoder * dec,
 
   if (frame->output_buffer)
     return gst_video_decoder_finish_frame (dec, frame);
+  gst_video_codec_frame_unref (frame);
   return GST_FLOW_OK;
 }
 
@@ -420,6 +422,65 @@ GST_START_TEST (videodecoder_playback_with_events)
 GST_END_TEST;
 
 
+/* Check https://bugzilla.gnome.org/show_bug.cgi?id=721835 */
+GST_START_TEST (videodecoder_playback_first_frames_not_decoded)
+{
+  GstSegment segment;
+  GstBuffer *buffer;
+  guint64 i = 0;
+
+  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);
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+  /* push a buffer, to have the segment attached to it.
+   * unfortunatelly this buffer can't be decoded as it isn't a keyframe */
+  buffer = create_test_buffer (i++);
+  GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+
+  /* now be evil and ask this frame to be released
+   * this frame has the segment event attached to it, and the
+   * segment shouldn't disappear with it */
+  {
+    GList *l, *ol;
+
+    ol = l = gst_video_decoder_get_frames (GST_VIDEO_DECODER (dec));
+    fail_unless (g_list_length (l) == 1);
+    while (l) {
+      GstVideoCodecFrame *tmp = l->data;
+
+      gst_video_decoder_release_frame (GST_VIDEO_DECODER (dec), tmp);
+
+      l = g_list_next (l);
+    }
+    g_list_free (ol);
+  }
+
+  buffer = create_test_buffer (i++);
+  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
+
+  fail_unless (g_list_length (buffers) == 1);
+
+  g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
+  buffers = NULL;
+
+  cleanup_videodecodertest ();
+}
+
+GST_END_TEST;
+
+
 GST_START_TEST (videodecoder_backwards_playback)
 {
   GstSegment segment;
@@ -510,6 +571,7 @@ gst_videodecoder_suite (void)
   suite_add_tcase (s, tc);
   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_backwards_playback);