Make rganalysis and rglimiter elements GAP-flag aware.
authorRene Stadler <mail@renestadler.de>
Mon, 24 Mar 2008 12:32:59 +0000 (12:32 +0000)
committerRene Stadler <mail@renestadler.de>
Mon, 24 Mar 2008 12:32:59 +0000 (12:32 +0000)
Original commit message from CVS:
* gst/replaygain/gstrganalysis.c (gst_rg_analysis_init),
(gst_rg_analysis_transform_ip):
* gst/replaygain/gstrglimiter.c (gst_rg_limiter_init),
(gst_rg_limiter_transform_ip):
Make rganalysis and rglimiter elements GAP-flag aware.
* tests/check/elements/rganalysis.c: (test_gap_buffers),
(rganalysis_suite):
* tests/check/elements/rglimiter.c (test_gap), (rglimiter_suite):
Add tests to verify gap-awareness.

gst/replaygain/gstrganalysis.c
gst/replaygain/gstrglimiter.c
tests/check/elements/rganalysis.c
tests/check/elements/rglimiter.c

index 2436778..613c087 100644 (file)
@@ -288,6 +288,10 @@ gst_rg_analysis_class_init (GstRgAnalysisClass * klass)
 static void
 gst_rg_analysis_init (GstRgAnalysis * filter, GstRgAnalysisClass * gclass)
 {
+  GstBaseTransform *base = GST_BASE_TRANSFORM (filter);
+
+  gst_base_transform_set_gap_aware (base, TRUE);
+
   filter->num_tracks = 0;
   filter->forced = FORCED_DEFAULT;
   filter->reference_level = RG_REFERENCE_LEVEL;
@@ -452,6 +456,10 @@ gst_rg_analysis_transform_ip (GstBaseTransform * base, GstBuffer * buf)
   if (filter->skip)
     return GST_FLOW_OK;
 
+  /* Buffers made up of silence have no influence on the analysis: */
+  if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP))
+    return GST_FLOW_OK;
+
   GST_LOG_OBJECT (filter, "processing buffer of size %u",
       GST_BUFFER_SIZE (buf));
 
index 609db3d..d474b26 100644 (file)
@@ -129,8 +129,12 @@ gst_rg_limiter_class_init (GstRgLimiterClass * klass)
 static void
 gst_rg_limiter_init (GstRgLimiter * filter, GstRgLimiterClass * gclass)
 {
+  GstBaseTransform *base = GST_BASE_TRANSFORM (filter);
+
+  gst_base_transform_set_passthrough (base, FALSE);
+  gst_base_transform_set_gap_aware (base, TRUE);
+
   filter->enabled = TRUE;
-  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), FALSE);
 }
 
 static void
@@ -182,6 +186,9 @@ gst_rg_limiter_transform_ip (GstBaseTransform * base, GstBuffer * buf)
   if (!filter->enabled)
     return GST_FLOW_OK;
 
+  if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP))
+    return GST_FLOW_OK;
+
   input = (gfloat *) GST_BUFFER_DATA (buf);
   count = GST_BUFFER_SIZE (buf) / sizeof (gfloat);
 
index 96ea6da..1a44bd4 100644 (file)
@@ -741,6 +741,46 @@ GST_START_TEST (test_empty_buffers)
 
 GST_END_TEST;
 
+GST_START_TEST (test_gap_buffers)
+{
+  GstElement *element = setup_rganalysis ();
+  GstTagList *tag_list;
+  GstBuffer *buf;
+  gint accumulator = 0;
+  gint i;
+
+  set_playing_state (element);
+
+  for (i = 0; i < 60; i++) {
+    if (i % 3 == 0) {
+      /* We are cheating here; the element cannot know that these GAP buffers
+       * actually contain non-silence so it must skip them. */
+      buf = test_buffer_square_float_mono (&accumulator, 44100, 512, 0.25);
+      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
+      push_buffer (buf);
+
+      /* Verify that the base class does not lift the GAP flag: */
+      fail_if (g_list_length (buffers) == 0);
+      if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP))
+        fail_unless (GST_BUFFER_FLAG_IS_SET (buffers->data,
+                GST_BUFFER_FLAG_GAP));
+    } else {
+      push_buffer (test_buffer_const_float_mono (44100, 512, 0.0));
+    }
+  }
+
+  send_eos_event (element);
+  tag_list = poll_tags (element);
+  /* We pushed faked GAP buffers with non-silence and non-GAP buffers with
+   * silence, so the correct result is that the analysis only got silence: */
+  fail_unless_track_peak (tag_list, 0.0);
+  fail_unless_track_gain (tag_list, SILENCE_GAIN);
+
+  cleanup_rganalysis (element);
+}
+
+GST_END_TEST;
+
 /* Tests for correctness of the peak values. */
 
 /* Float peak test.  For stereo, one channel has the constant value of -1.369,
@@ -1778,6 +1818,7 @@ rganalysis_suite (void)
   tcase_add_test (tc_chain, test_no_buffer_album_1);
   tcase_add_test (tc_chain, test_no_buffer_album_2);
   tcase_add_test (tc_chain, test_empty_buffers);
+  tcase_add_test (tc_chain, test_gap_buffers);
 
   tcase_add_test (tc_chain, test_peak_float);
   tcase_add_test (tc_chain, test_peak_int16_16);
index 33b478d..9d83878 100644 (file)
@@ -204,6 +204,36 @@ GST_START_TEST (test_limiting)
 
 GST_END_TEST;
 
+GST_START_TEST (test_gap)
+{
+  GstElement *element = setup_rglimiter ();
+  GstBuffer *buf, *out_buf;
+
+  set_playing_state (element);
+
+  buf = create_test_buffer ();
+  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
+  fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
+  fail_unless (g_list_length (buffers) == 1);
+  out_buf = buffers->data;
+  fail_if (out_buf == NULL);
+  ASSERT_BUFFER_REFCOUNT (out_buf, "out_buf", 1);
+
+  /* Verify that the baseclass does not lift the GAP flag: */
+  fail_unless (GST_BUFFER_FLAG_IS_SET (out_buf, GST_BUFFER_FLAG_GAP));
+
+  g_assert (GST_BUFFER_SIZE (out_buf) == GST_BUFFER_SIZE (buf));
+  /* We cheated by passing an input buffer with non-silence that has the GAP
+   * flag set.  The element cannot know that however and must have skipped
+   * adjusting the buffer because of the flag, which we can easily verify: */
+  fail_if (memcmp (GST_BUFFER_DATA (out_buf),
+          GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (out_buf)) != 0);
+
+  cleanup_rglimiter (element);
+}
+
+GST_END_TEST;
+
 Suite *
 rglimiter_suite (void)
 {
@@ -215,6 +245,7 @@ rglimiter_suite (void)
   tcase_add_test (tc_chain, test_no_buffer);
   tcase_add_test (tc_chain, test_disabled);
   tcase_add_test (tc_chain, test_limiting);
+  tcase_add_test (tc_chain, test_gap);
 
   return s;
 }