vp8enc: improve unit tests
authorJohn-Mark Bell <jmb@pexip.com>
Tue, 31 Oct 2017 09:40:33 +0000 (09:40 +0000)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 8 Sep 2020 22:59:29 +0000 (22:59 +0000)
  - make test_encode_simple cope with libvpx built with
    CONFIG_REALTIME_ONLY. Sadly, there's no way to detect this at
    runtime beyond trying to set lag-in-frames to >0, pushing a
    buffer and catching the GST_FLOW_NOT_NEGOTIATED return.

  - fix bitrot in test_encode_simple_when_bitrate_set_to_zero.

  - port test_encode_simple to GstHarness and introduce a separate
    test for the lag-in-frames property.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/708>

tests/check/elements/vp8enc.c

index e9d8c07..6220413 100644 (file)
 #include <gst/check/gstcheck.h>
 #include <gst/video/video.h>
 
-static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-vp8, "
-        "width = (int) [1, MAX], "
-        "height = (int) [1, MAX], " "framerate = (fraction) [0, MAX]"));
-
-static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw, "
-        "format = (string) I420, "
-        "width = (int) [1, MAX], "
-        "height = (int) [1, MAX], " "framerate = (fraction) [0, MAX]"));
-
-static GstPad *sinkpad, *srcpad;
-
-static GstElement *
-setup_vp8enc (const gchar * src_caps_str)
-{
-  GstElement *vp8enc;
-  GstCaps *srccaps = NULL;
-  GstBus *bus;
-
-  if (src_caps_str) {
-    srccaps = gst_caps_from_string (src_caps_str);
-    fail_unless (srccaps != NULL);
-  }
-
-  vp8enc = gst_check_setup_element ("vp8enc");
-  fail_unless (vp8enc != NULL);
-  srcpad = gst_check_setup_src_pad (vp8enc, &srctemplate);
-  sinkpad = gst_check_setup_sink_pad (vp8enc, &sinktemplate);
-  gst_pad_set_active (srcpad, TRUE);
-  gst_pad_set_active (sinkpad, TRUE);
-  gst_check_setup_events (srcpad, vp8enc, srccaps, GST_FORMAT_TIME);
-
-  bus = gst_bus_new ();
-  gst_element_set_bus (vp8enc, bus);
-
-  fail_unless (gst_element_set_state (vp8enc,
-          GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE,
-      "could not set to playing");
-
-  if (srccaps)
-    gst_caps_unref (srccaps);
-
-  buffers = NULL;
-  return vp8enc;
-}
-
-static void
-cleanup_vp8enc (GstElement * vp8enc)
-{
-  GstBus *bus;
-
-  /* Free parsed buffers */
-  gst_check_drop_buffers ();
-
-  bus = GST_ELEMENT_BUS (vp8enc);
-  gst_bus_set_flushing (bus, TRUE);
-  gst_object_unref (bus);
-
-  gst_pad_set_active (srcpad, FALSE);
-  gst_pad_set_active (sinkpad, FALSE);
-  gst_check_teardown_src_pad (vp8enc);
-  gst_check_teardown_sink_pad (vp8enc);
-  gst_check_teardown_element (vp8enc);
-}
-
-
-GST_START_TEST (test_encode_simple)
-{
-  GstElement *vp8enc;
-  GstBuffer *buffer;
-  gint i;
-  GList *l;
-  GstCaps *outcaps;
-  GstSegment seg;
-
-  vp8enc =
-      setup_vp8enc
-      ("video/x-raw,format=(string)I420,width=(int)320,height=(int)240,framerate=(fraction)25/1");
-
-  g_object_set (vp8enc, "lag-in-frames", 5, NULL);
-
-  gst_segment_init (&seg, GST_FORMAT_TIME);
-  seg.stop = gst_util_uint64_scale (20, GST_SECOND, 25);
-  fail_unless (gst_pad_push_event (srcpad, gst_event_new_segment (&seg)));
-
-  buffer = gst_buffer_new_and_alloc (320 * 240 + 2 * 160 * 120);
-  gst_buffer_memset (buffer, 0, 0, -1);
-
-  for (i = 0; i < 20; i++) {
-    GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (i, GST_SECOND, 25);
-    GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (1, GST_SECOND, 25);
-    fail_unless (gst_pad_push (srcpad, gst_buffer_ref (buffer)) == GST_FLOW_OK);
-  }
-
-  gst_buffer_unref (buffer);
-
-  /* Only 5 buffers are allowed to be queued now */
-  fail_unless (g_list_length (buffers) > 15);
-
-  fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
-
-
-  /* All buffers must be there now */
-  fail_unless_equals_int (g_list_length (buffers), 20);
-
-  outcaps =
-      gst_caps_from_string
-      ("video/x-vp8,width=(int)320,height=(int)240,framerate=(fraction)25/1");
-
-  for (l = buffers, i = 0; l; l = l->next, i++) {
-    buffer = l->data;
-
-    if (i == 0)
-      fail_if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
-
-    fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
-        gst_util_uint64_scale (i, GST_SECOND, 25));
-    fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer),
-        gst_util_uint64_scale (1, GST_SECOND, 25));
-  }
-
-  gst_caps_unref (outcaps);
-
-  cleanup_vp8enc (vp8enc);
-}
-
-GST_END_TEST;
-
 #define gst_caps_new_i420(w, h) gst_caps_new_i420_full (w, h, 30, 1, 1, 1)
 static GstCaps *
 gst_caps_new_i420_full (gint width, gint height, gint fps_n, gint fps_d,
@@ -208,6 +75,95 @@ gst_harness_create_video_buffer_full (GstHarness * h, gint value,
       timestamp, duration);
 }
 
+GST_START_TEST (test_encode_simple)
+{
+  gint i;
+  GstHarness *h = gst_harness_new ("vp8enc");
+  gst_harness_set_src_caps (h, gst_caps_new_i420_full (320, 240, 25, 1, 1, 1));
+
+  for (i = 0; i < 20; i++) {
+    GstBuffer *buffer = gst_harness_create_video_buffer_full (h, 0x0,
+        320, 240, gst_util_uint64_scale (i, GST_SECOND, 25),
+        gst_util_uint64_scale (1, GST_SECOND, 25));
+    fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer));
+  }
+
+  for (i = 0; i < 20; i++) {
+    GstBuffer *buffer = gst_harness_pull (h);
+
+    if (i == 0)
+      fail_if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
+
+    fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
+        gst_util_uint64_scale (i, GST_SECOND, 25));
+    fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer),
+        gst_util_uint64_scale (1, GST_SECOND, 25));
+
+    gst_buffer_unref (buffer);
+  }
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_encode_lag_in_frames)
+{
+  GstFlowReturn ret;
+  GstBuffer *buffer;
+  GstSegment seg;
+  GstHarness *h = gst_harness_new ("vp8enc");
+  g_object_set (h->element, "lag-in-frames", 5, NULL);
+  gst_harness_set_src_caps (h, gst_caps_new_i420_full (320, 240, 25, 1, 1, 1));
+
+  gst_segment_init (&seg, GST_FORMAT_TIME);
+  seg.stop = gst_util_uint64_scale (20, GST_SECOND, 25);
+  fail_unless (gst_harness_push_event (h, gst_event_new_segment (&seg)));
+
+  buffer = gst_harness_create_video_buffer_full (h, 0x0,
+      320, 240, gst_util_uint64_scale (0, GST_SECOND, 25),
+      gst_util_uint64_scale (1, GST_SECOND, 25));
+
+  ret = gst_harness_push (h, gst_buffer_ref (buffer));
+  /* If libvpx was built with CONFIG_REALTIME_ONLY, then we'll receive
+   * GST_FLOW_NOT_NEGOTIATED. Accept this, and skip the rest of this test
+   * in that case. */
+  fail_unless (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_NEGOTIATED);
+
+  if (ret == GST_FLOW_OK) {
+    gint i;
+
+    for (i = 1; i < 20; i++) {
+      GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (i, GST_SECOND, 25);
+      GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (1, GST_SECOND, 25);
+      fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
+              gst_buffer_ref (buffer)));
+    }
+
+    fail_unless_equals_int (20, gst_harness_buffers_received (h));
+
+    for (i = 0; i < 20; i++) {
+      GstBuffer *outbuf = gst_harness_pull (h);
+
+      if (i == 0)
+        fail_if (GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT));
+
+      fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuf),
+          gst_util_uint64_scale (i, GST_SECOND, 25));
+      fail_unless_equals_uint64 (GST_BUFFER_DURATION (outbuf),
+          gst_util_uint64_scale (1, GST_SECOND, 25));
+
+      gst_buffer_unref (outbuf);
+    }
+  }
+
+  gst_buffer_unref (buffer);
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
 GST_START_TEST (test_encode_simple_when_bitrate_set_to_zero)
 {
   GstHarness *h = gst_harness_new_parse ("vp8enc target-bitrate=0");
@@ -263,6 +219,7 @@ vp8enc_suite (void)
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_encode_simple);
+  tcase_add_test (tc_chain, test_encode_lag_in_frames);
   tcase_add_test (tc_chain, test_encode_simple_when_bitrate_set_to_zero);
   tcase_add_test (tc_chain, test_autobitrate_changes_with_caps);