volume: a return value of FALSE from the controller is not fatal
authorStefan Sauer <ensonic@users.sf.net>
Wed, 9 Jan 2013 22:15:06 +0000 (23:15 +0100)
committerStefan Sauer <ensonic@users.sf.net>
Wed, 9 Jan 2013 22:15:06 +0000 (23:15 +0100)
A return value of FALSE here indicates that we don't have control-values. In
0.10 we were returning the default value of the property. Now we don't fill an
array with defaults in the ControlBinding, but leave it up to the element to
handle this case.

gst/volume/gstvolume.c
tests/check/elements/volume.c

index 4ec82fd..c6be1ee 100644 (file)
@@ -739,7 +739,8 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
     guint nsamples = map.size / (width * channels);
     GstClockTime interval = gst_util_uint64_scale_int (1, GST_SECOND, rate);
     GstClockTime ts = GST_BUFFER_TIMESTAMP (outbuf);
-    gboolean use_mutes = FALSE;
+    gboolean have_mutes = FALSE;
+    gboolean have_volumes = FALSE;
 
     ts = gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, ts);
 
@@ -753,31 +754,27 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
       self->volumes_count = nsamples;
     }
 
-    if (mute_cb) {
-      if (!gst_control_binding_get_value_array (mute_cb, ts, interval,
-              nsamples, (gpointer) self->mutes))
-        goto controller_failure;
-
-      gst_object_replace ((GstObject **) & mute_cb, NULL);
-      use_mutes = TRUE;
-    } else {
-      g_free (self->mutes);
-      self->mutes = NULL;
-      self->mutes_count = 0;
-    }
-
     if (volume_cb) {
-      if (!gst_control_binding_get_value_array (volume_cb, ts, interval,
-              nsamples, (gpointer) self->volumes))
-        goto controller_failure;
-
+      have_volumes =
+          gst_control_binding_get_value_array (volume_cb, ts, interval,
+          nsamples, (gpointer) self->volumes);
       gst_object_replace ((GstObject **) & volume_cb, NULL);
-    } else {
+    }
+    if (!have_volumes) {
       volume_orc_memset_f64 (self->volumes, self->current_volume, nsamples);
     }
 
-    if (use_mutes) {
+    if (mute_cb) {
+      have_mutes = gst_control_binding_get_value_array (mute_cb, ts, interval,
+          nsamples, (gpointer) self->mutes);
+      gst_object_replace ((GstObject **) & mute_cb, NULL);
+    }
+    if (have_mutes) {
       volume_orc_prepare_volumes (self->volumes, self->mutes, nsamples);
+    } else {
+      g_free (self->mutes);
+      self->mutes = NULL;
+      self->mutes_count = 0;
     }
 
     self->process_controlled (self, map.data, self->volumes, channels,
@@ -807,18 +804,6 @@ not_negotiated:
         ("No format was negotiated"), (NULL));
     return GST_FLOW_NOT_NEGOTIATED;
   }
-controller_failure:
-  {
-    if (mute_cb)
-      gst_object_unref (mute_cb);
-    if (volume_cb)
-      gst_object_unref (volume_cb);
-
-    GST_ELEMENT_ERROR (self, CORE, FAILED,
-        ("Failed to get values from controller"), (NULL));
-    gst_buffer_unmap (outbuf, &map);
-    return GST_FLOW_ERROR;
-  }
 }
 
 static void
index 6ab7088..7bbee30 100644 (file)
@@ -1814,6 +1814,55 @@ GST_START_TEST (test_controller_processing)
 
 GST_END_TEST;
 
+GST_START_TEST (test_controller_defaults_at_ts0)
+{
+  GstControlSource *cs;
+  GstTimedValueControlSource *tvcs;
+  GstElement *volume;
+  GstBuffer *inbuffer;
+  GstCaps *caps;
+  GstSegment seg;
+
+  volume = setup_volume ();
+
+  cs = gst_interpolation_control_source_new ();
+  g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
+  gst_object_add_control_binding (GST_OBJECT_CAST (volume),
+      gst_direct_control_binding_new (GST_OBJECT_CAST (volume), "volume", cs));
+
+  /* make a control curve that does not start at ts=0, the element will use
+   * the current property value (default) until the control curve starts 
+   */
+  tvcs = (GstTimedValueControlSource *) cs;
+  gst_timed_value_control_source_set (tvcs, GST_SECOND / 100, 0.1);
+  gst_timed_value_control_source_set (tvcs, GST_SECOND, 1.0);
+
+  fail_unless (gst_element_set_state (volume,
+          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
+      "could not set to playing");
+
+  /* controller curve starts at sample: 441 */
+  inbuffer = gst_buffer_new_and_alloc (1000 * sizeof (gint16));
+  gst_buffer_memset (inbuffer, 0, 0, 1000 * sizeof (gint16));
+  caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
+  gst_pad_set_caps (mysrcpad, caps);
+  GST_BUFFER_TIMESTAMP (inbuffer) = 0;
+  gst_caps_unref (caps);
+
+  gst_segment_init (&seg, GST_FORMAT_TIME);
+  fail_unless (gst_pad_push_event (mysrcpad,
+          gst_event_new_segment (&seg)) == TRUE);
+
+  /* pushing gives away my reference ... */
+  fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
+
+  gst_object_unref (cs);
+  cleanup_volume (volume);
+}
+
+GST_END_TEST;
+
+
 static Suite *
 volume_suite (void)
 {
@@ -1856,6 +1905,7 @@ volume_suite (void)
   tcase_add_test (tc_chain, test_passthrough);
   tcase_add_test (tc_chain, test_controller_usability);
   tcase_add_test (tc_chain, test_controller_processing);
+  tcase_add_test (tc_chain, test_controller_defaults_at_ts0);
 
   return s;
 }