From 2ef6e3d2ecbcde1a7bfcd27935bef3f90c4f7d5f Mon Sep 17 00:00:00 2001 From: Neil C Smith Date: Fri, 7 Jun 2019 15:40:35 +0100 Subject: [PATCH] Controller API support (#158) * Initial lowlevel controller API and timed value controller mappings / pointer types. * Add missing GstDirectControlBinding support to lowlevel. * Add Natives.objectFor and Natives.callerOwnsReturn variants that accept GPointer directly. * Add ControlSource and ControlBinding base classes; add GstObject support for control bindings; add DirectControlBinding, TimedValueControlSource (incomplete) and InterpolationControlSource. * Add GstTimedValue structure and Java equivalent; add bulk set and get support to TimedValueControlSource. * Add LFOControlSource * Add GTYPE_NAME and registration. * Return boolean from GstObject::syncValues as upstream - use with trigger control source is awkward otherwise. * Add some testing of interpolation control source. * Add TriggerControlSource with simple test. * Return this on property setting for easier method chaining. * Implement ARGBControlBinding mapping. * Add ProxyControlBinding mapping. --- .../freedesktop/gstreamer/ControlBinding.java | 126 +++++++++++ .../freedesktop/gstreamer/ControlSource.java | 160 +++++++++++++ src/org/freedesktop/gstreamer/Gst.java | 2 + src/org/freedesktop/gstreamer/GstObject.java | 111 ++++++++- .../controller/ARGBControlBinding.java | 92 ++++++++ .../gstreamer/controller/Controllers.java | 56 +++++ .../controller/DirectControlBinding.java | 92 ++++++++ .../InterpolationControlSource.java | 100 +++++++++ .../controller/InterpolationMode.java | 59 +++++ .../controller/LFOControlSource.java | 211 ++++++++++++++++++ .../gstreamer/controller/LFOWaveform.java | 66 ++++++ .../controller/ProxyControlBinding.java | 75 +++++++ .../controller/TimedValueControlSource.java | 156 +++++++++++++ .../controller/TriggerControlSource.java | 102 +++++++++ .../freedesktop/gstreamer/glib/Natives.java | 37 ++- .../lowlevel/GstARGBControlBindingPtr.java | 32 +++ .../lowlevel/GstControlBindingAPI.java | 54 +++++ .../lowlevel/GstControlBindingPtr.java | 32 +++ .../lowlevel/GstControlSourceAPI.java | 132 +++-------- .../lowlevel/GstControlSourcePtr.java | 32 +++ .../gstreamer/lowlevel/GstControllerAPI.java | 98 ++++++++ .../lowlevel/GstDirectControlBindingPtr.java | 32 +++ .../GstInterpolationControlSourcePtr.java | 32 +++ .../lowlevel/GstLFOControlSourceAPI.java | 81 ------- .../lowlevel/GstLFOControlSourcePtr.java | 32 +++ .../gstreamer/lowlevel/GstObjectAPI.java | 14 +- .../lowlevel/GstProxyControlBindingPtr.java | 32 +++ .../GstTimedValueControlSourcePtr.java | 32 +++ .../lowlevel/GstTriggerControlSourcePtr.java | 32 +++ .../InterpolationControlSourceTest.java | 145 ++++++++++++ .../controller/TriggerControlSourceTest.java | 95 ++++++++ 31 files changed, 2168 insertions(+), 184 deletions(-) create mode 100644 src/org/freedesktop/gstreamer/ControlBinding.java create mode 100644 src/org/freedesktop/gstreamer/ControlSource.java create mode 100644 src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java create mode 100644 src/org/freedesktop/gstreamer/controller/Controllers.java create mode 100644 src/org/freedesktop/gstreamer/controller/DirectControlBinding.java create mode 100644 src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java create mode 100644 src/org/freedesktop/gstreamer/controller/InterpolationMode.java create mode 100644 src/org/freedesktop/gstreamer/controller/LFOControlSource.java create mode 100644 src/org/freedesktop/gstreamer/controller/LFOWaveform.java create mode 100644 src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java create mode 100644 src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java create mode 100644 src/org/freedesktop/gstreamer/controller/TriggerControlSource.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java delete mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourceAPI.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java create mode 100644 src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java create mode 100644 test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java create mode 100644 test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java diff --git a/src/org/freedesktop/gstreamer/ControlBinding.java b/src/org/freedesktop/gstreamer/ControlBinding.java new file mode 100644 index 0000000..02e4ccd --- /dev/null +++ b/src/org/freedesktop/gstreamer/ControlBinding.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer; + +import org.freedesktop.gstreamer.lowlevel.GValueAPI; +import org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControlBindingAPI.GSTCONTROLBINDING_API; + +/** + * Attachment for control source sources. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlBinding.html + *

+ */ +public class ControlBinding extends GstObject { + + public static final String GTYPE_NAME = "GstControlBinding"; + + private final Handle handle; + + protected ControlBinding(Handle handle, boolean needRef) { + super(handle, needRef); + this.handle = handle; + } + + ControlBinding(Initializer init) { + this(new Handle( + init.ptr.as(GstControlBindingPtr.class, GstControlBindingPtr::new), + init.ownsHandle), + init.needRef); + } + + /** + * Gets the value for the given controlled property at the requested time. + * + * @param timestamp the time the control-change should be read from + * @return the value of the property at the given time, or NULL if the + * property isn't controlled + */ + public Object getValue(long timestamp) { + GValueAPI.GValue gValue = GSTCONTROLBINDING_API.gst_control_binding_get_value( + handle.getPointer(), timestamp); + return gValue == null ? null : gValue.getValue(); + } + + /** + * Gets a number of values for the given controlled property starting at + * the requested time. + *

+ * This function is useful if one wants to e.g. draw a graph of the control + * curve or apply a control curve sample by sample. + * + * @param timestamp the time that should be processed + * @param interval the time spacing between subsequent values + * @param values array to fill with control values + * @return false if the given array could not be filled + */ + public boolean getValueArray(long timestamp, long interval, Object[] values) { + GValueAPI.GValueArray gValues = new GValueAPI.GValueArray(values.length); + boolean ok = GSTCONTROLBINDING_API.gst_control_binding_get_g_value_array( + handle.getPointer(), + timestamp, + interval, + gValues.n_values, + gValues); + if (ok) { + for (int i = 0; i < values.length; i++) { + values[i] = gValues.getValue(i); + } + } + return ok; + } + + /** + * This function is used to disable a control binding for some time, i.e. + * GstObject.syncValues() will do nothing. + * + * @param disabled whether to disable the controller or not + */ + public void setDisabled(boolean disabled) { + GSTCONTROLBINDING_API.gst_control_binding_set_disabled(handle.getPointer(), disabled); + } + + /** + * Check if the control binding is disabled. + * + * @return TRUE if the binding is inactive + */ + public boolean isDisabled() { + return GSTCONTROLBINDING_API.gst_control_binding_is_disabled(handle.getPointer()); + + } + + + protected static class Handle extends GstObject.Handle { + + public Handle(GstControlBindingPtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + @Override + protected GstControlBindingPtr getPointer() { + return (GstControlBindingPtr) super.getPointer(); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/ControlSource.java b/src/org/freedesktop/gstreamer/ControlSource.java new file mode 100644 index 0000000..0375543 --- /dev/null +++ b/src/org/freedesktop/gstreamer/ControlSource.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer; + +import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControlSourceAPI.GSTCONTROLSOURCE_API; + +/** + * Base class for control source sources. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html + *

+ */ +public class ControlSource extends GstObject { + + public static final String GTYPE_NAME = "GstControlSource"; + + private final Handle handle; + + protected ControlSource(Handle handle, boolean needRef) { + super(handle, needRef); + this.handle = handle; + } + + ControlSource(Initializer init) { + this(new Handle( + init.ptr.as(GstControlSourcePtr.class, GstControlSourcePtr::new), + init.ownsHandle), + init.needRef); + } + + /** + * Gets the value for this ControlSource at a given timestamp. + * + * @param timestamp the time for which the value should be returned + * @return value + * @throws IllegalStateException if the value could not be calculated + */ + public double getValue(long timestamp) { + double[] out = new double[1]; + boolean ok = GSTCONTROLSOURCE_API.gst_control_source_get_value(handle.getPointer(), timestamp, out); + if (ok) { + return out[0]; + } else { + throw new IllegalStateException(); + } + } + + /** + * Gets an array of values for for this ControlSource. Values that are + * undefined contain NANs. + * + * @param timestamp the first timestamp + * @param interval the time steps + * @param values array to put control-values in + * @return true if the values were successfully calculated + */ + public boolean getValueArray(long timestamp, long interval, double[] values) { + return GSTCONTROLSOURCE_API.gst_control_source_get_value_array( + handle.getPointer(), + timestamp, + interval, + values.length, + values); + } + + /** + * A simple structure for saving a timestamp and a value. + *

+ * Equivalent to GstTimedValue. + *

+ * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html#GstTimedValue + * + */ + public static final class TimedValue { + + public final long timestamp; + public final double value; + + /** + * Create a TimedValue wrapping the timestamp (see {@link ClockTime}) + * and corresponding value. + * + * @param timestamp the timestamp (GstClockTime) of the value change + * @param value the corresponding value + */ + public TimedValue(long timestamp, double value) { + this.timestamp = timestamp; + this.value = value; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 37 * hash + (int) (this.timestamp ^ (this.timestamp >>> 32)); + hash = 37 * hash + (int) (Double.doubleToLongBits(this.value) ^ (Double.doubleToLongBits(this.value) >>> 32)); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TimedValue other = (TimedValue) obj; + if (this.timestamp != other.timestamp) { + return false; + } + if (Double.doubleToLongBits(this.value) != Double.doubleToLongBits(other.value)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "TimedValue{" + "timestamp=" + timestamp + ", value=" + value + '}'; + } + + } + + protected static class Handle extends GstObject.Handle { + + public Handle(GstControlSourcePtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + @Override + protected GstControlSourcePtr getPointer() { + return (GstControlSourcePtr) super.getPointer(); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/Gst.java b/src/org/freedesktop/gstreamer/Gst.java index c2e5108..8da744c 100644 --- a/src/org/freedesktop/gstreamer/Gst.java +++ b/src/org/freedesktop/gstreamer/Gst.java @@ -52,6 +52,7 @@ import java.util.ServiceLoader; import java.util.logging.Level; import java.util.stream.Stream; +import org.freedesktop.gstreamer.controller.Controllers; import org.freedesktop.gstreamer.elements.Elements; import org.freedesktop.gstreamer.glib.GLib; import org.freedesktop.gstreamer.glib.GMainContext; @@ -666,6 +667,7 @@ private static synchronized void loadAllClasses() { new Event.Types(), new Message.Types(), new Query.Types(), + new Controllers(), new Elements(), new WebRTC.Types()) .flatMap(NativeObject.TypeProvider::types) diff --git a/src/org/freedesktop/gstreamer/GstObject.java b/src/org/freedesktop/gstreamer/GstObject.java index 37f3b21..4442dd9 100644 --- a/src/org/freedesktop/gstreamer/GstObject.java +++ b/src/org/freedesktop/gstreamer/GstObject.java @@ -24,6 +24,8 @@ import java.util.logging.Logger; import org.freedesktop.gstreamer.glib.GObject; +import org.freedesktop.gstreamer.glib.Natives; +import org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; import static org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GSTOBJECT_API; @@ -44,6 +46,8 @@ public class GstObject extends GObject { private static Logger LOG = Logger.getLogger(GstObject.class.getName()); + private final Handle handle; + /** * Wraps an underlying C GstObject with a Java proxy * @@ -52,9 +56,10 @@ public class GstObject extends GObject { protected GstObject(Initializer init) { this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef); } - + protected GstObject(Handle handle, boolean needRef) { super(handle, needRef); + this.handle = handle; } /** @@ -96,6 +101,105 @@ public GstObject getParent() { return GSTOBJECT_API.gst_object_get_parent(this); } + /** + * Returns a suggestion for timestamps where buffers should be split to get + * best controller results. + * + * @return the suggested timestamp or {@link ClockTime#NONE} if no + * control-rate was set. + */ + public long suggestNextSync() { + return GSTOBJECT_API.gst_object_suggest_next_sync(handle.getPointer()); + } + + /** + * Sets the properties of the object, according to the {@link ControlSource} + * that (maybe) handle them and for the given timestamp. + *

+ * If this function fails, it is most likely the application developers + * fault. Most probably the control sources are not setup correctly. + * + * @param timestamp the time that should be processed + * @return true if the controller values have been applied to the object + * properties + */ + public boolean syncValues(long timestamp) { + return GSTOBJECT_API.gst_object_sync_values(handle.getPointer(), timestamp); + } + + /** + * Check if this object has active controlled properties. + * + * @return TRUE if the object has active controlled properties + */ + public boolean hasActiveControlBindings() { + return GSTOBJECT_API.gst_object_has_active_control_bindings(handle.getPointer()); + } + + /** + * This function is used to disable all controlled properties of the object + * for some time, i.e. {@link #syncValues(long) } will do nothing. + * + * @param disabled whether to disable the controllers or not + */ + public void setControlBindingsDisabled(boolean disabled) { + GSTOBJECT_API.gst_object_set_control_bindings_disabled(handle.getPointer(), disabled); + } + + /** + * This function is used to disable the control bindings on a property for + * some time, i.e. {@link #syncValues(long) } will do nothing for the + * property. + * + * @param propertyName property to disable + * @param disabled whether to disable the controller or not + */ + public void setControlBindingDisabled(String propertyName, boolean disabled) { + GSTOBJECT_API.gst_object_set_control_binding_disabled(handle.getPointer(), propertyName, disabled); + } + + /** + * Attach a {@link ControlBinding } to this object. If there was already a + * binding for this property it will be replaced. + * + * @param binding the ControlBinding that should be used + * @throws IllegalStateException if the binding has not been setup for this + * object + */ + public void addControlBinding(ControlBinding binding) { + GstControlBindingPtr bindingPtr = Natives.getPointer(binding) + .as(GstControlBindingPtr.class, GstControlBindingPtr::new); + boolean ok = GSTOBJECT_API.gst_object_add_control_binding(handle.getPointer(), bindingPtr); + if (!ok) { + throw new IllegalStateException(); + } + } + + /** + * Gets the corresponding {@link ControlBinding} for the property. + * + * @param propertyName name of the property + * @return control binding for the property or NULL if the property is not + * controlled + */ + public ControlBinding getControlBinding(String propertyName) { + GstControlBindingPtr ptr = GSTOBJECT_API.gst_object_get_control_binding( + handle.getPointer(), propertyName); + return ptr == null ? null : Natives.callerOwnsReturn(ptr, ControlBinding.class); + } + + /** + * Removes the corresponding {@link ControlBinding }. + * + * @param binding the binding to remove + * @return true if the binding could be removed + */ + public boolean removeControlBinding(ControlBinding binding) { + GstControlBindingPtr bindingPtr = Natives.getPointer(binding) + .as(GstControlBindingPtr.class, GstControlBindingPtr::new); + return GSTOBJECT_API.gst_object_remove_control_binding(handle.getPointer(), bindingPtr); + } + @Override public String toString() { return String.format("%s: [%s]", getClass().getSimpleName(), getName()); @@ -107,7 +211,7 @@ public String toString() { // protected static Initializer initializer(Pointer ptr, boolean needRef) { // return initializer(ptr, needRef, true); // } - + protected static class Handle extends GObject.Handle { public Handle(GstObjectPtr ptr, boolean ownsHandle) { @@ -128,13 +232,12 @@ protected void sink() { protected void unref() { GSTOBJECT_API.gst_object_unref(getPointer()); } - + @Override protected GstObjectPtr getPointer() { return (GstObjectPtr) super.getPointer(); } - } } diff --git a/src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java b/src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java new file mode 100644 index 0000000..8c77c67 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlBinding; +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.GstObject; +import org.freedesktop.gstreamer.glib.GObject; +import org.freedesktop.gstreamer.glib.Natives; +import org.freedesktop.gstreamer.lowlevel.GstARGBControlBindingPtr; +import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; +import org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; + +/** + * Attachment for control sources to ARGB properties + *

+ * A value mapping object that attaches multiple control sources to int GObject + * properties representing colors. A control value of 0.0 will turn the color + * component off and a value of 1.0 will be the color level. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstARGBControlBinding.html + *

+ */ +public class ARGBControlBinding extends ControlBinding { + + public static final String GTYPE_NAME = "GstARGBControlBinding"; + + ARGBControlBinding(Initializer init) { + this(new Handle( + init.ptr.as(GstARGBControlBindingPtr.class, GstARGBControlBindingPtr::new), + init.ownsHandle), + init.needRef); + } + + private ARGBControlBinding(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Create a new control-binding that attaches the given + * {@link ControlSource} to the {@link GObject} property. + * + * @param object the object of the property + * @param propertyName the property-name to attach the control source + * @param controlSourceA the control source for the alpha channel + * @param controlSourceR the control source for the red channel + * @param controlSourceG the control source for the green channel + * @param controlSourceB the control source for the blue channel + * @return new ARGBControlBinding + */ + public static ARGBControlBinding create(GstObject object, + String propertyName, + ControlSource controlSourceA, + ControlSource controlSourceR, + ControlSource controlSourceG, + ControlSource controlSourceB) { + GstARGBControlBindingPtr ptr = GSTCONTROLLER_API.gst_argb_control_binding_new( + Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), + propertyName, + controlSourcePtr(controlSourceA), + controlSourcePtr(controlSourceR), + controlSourcePtr(controlSourceG), + controlSourcePtr(controlSourceB)); + return new ARGBControlBinding(new Handle(ptr, true), false); + } + + private static GstControlSourcePtr controlSourcePtr(ControlSource cs) { + return cs == null ? null + : Natives.getPointer(cs).as(GstControlSourcePtr.class, GstControlSourcePtr::new); + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/Controllers.java b/src/org/freedesktop/gstreamer/controller/Controllers.java new file mode 100644 index 0000000..5d1c181 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/Controllers.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import java.util.stream.Stream; +import org.freedesktop.gstreamer.glib.NativeObject; +import static org.freedesktop.gstreamer.glib.Natives.registration; + +/** + * Controllers registration + */ +public class Controllers implements NativeObject.TypeProvider { + + @Override + public Stream> types() { + return Stream.of( + registration(ARGBControlBinding.class, + ARGBControlBinding.GTYPE_NAME, + ARGBControlBinding::new), + registration(DirectControlBinding.class, + DirectControlBinding.GTYPE_NAME, + DirectControlBinding::new), + registration(ProxyControlBinding.class, + ProxyControlBinding.GTYPE_NAME, + ProxyControlBinding::new), + registration(InterpolationControlSource.class, + InterpolationControlSource.GTYPE_NAME, + InterpolationControlSource::new), + registration(TriggerControlSource.class, + TriggerControlSource.GTYPE_NAME, + TriggerControlSource::new), + registration(LFOControlSource.class, + LFOControlSource.GTYPE_NAME, + LFOControlSource::new), + registration(TimedValueControlSource.class, + TimedValueControlSource.GTYPE_NAME, + TimedValueControlSource::new) + ); + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/DirectControlBinding.java b/src/org/freedesktop/gstreamer/controller/DirectControlBinding.java new file mode 100644 index 0000000..a36cda6 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/DirectControlBinding.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlBinding; +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.GstObject; +import org.freedesktop.gstreamer.glib.GObject; +import org.freedesktop.gstreamer.glib.Natives; +import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; +import org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; + +/** + * Direct attachment for control sources. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstDirectControlBinding.html + *

+ */ +public class DirectControlBinding extends ControlBinding { + + public static final String GTYPE_NAME = "GstDirectControlBinding"; + + DirectControlBinding(Initializer init) { + this(new Handle( + init.ptr.as(GstDirectControlBindingPtr.class, GstDirectControlBindingPtr::new), + init.ownsHandle), + init.needRef); + } + + private DirectControlBinding(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Create a new control-binding that attaches the {@link ControlSource } to + * the {@link GObject} property. It will map the control source range [0.0 + * ... 1.0] to the full target property range, and clip all values outside + * this range. + * + * @param object the object of the property + * @param propertyName the property-name to attach the control source + * @param controlSource the control source + * @return new DirectControlBinding + */ + public static DirectControlBinding create(GstObject object, String propertyName, ControlSource controlSource) { + GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new( + Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), + propertyName, + Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new)); + return new DirectControlBinding(new Handle(ptr, true), false); + } + + /** + * Create a new control-binding that attaches the {@link ControlSource } to + * the {@link GObject} property. It will directly map the control source + * values to the target property range without any transformations. + * + * @param object the object of the property + * @param propertyName the property-name to attach the control source + * @param controlSource the control source + * @return new DirectControlBinding + */ + public static DirectControlBinding createAbsolute(GstObject object, + String propertyName, ControlSource controlSource) { + GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new_absolute( + Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), + propertyName, + Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new)); + return new DirectControlBinding(new Handle(ptr, true), false); + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java b/src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java new file mode 100644 index 0000000..da808df --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.glib.NativeEnum; +import org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; + +/** + * Interpolation control source. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstInterpolationControlSource.html + *

+ * InterpolationControlSource is a {@link ControlSource}, that interpolates + * values between user-given control points. It supports several interpolation + * modes and property types. + *

+ * To use InterpolationControlSource create a new instance, bind it to a + * GParamSpec and set some control points by calling {@link TimedValueControlSource#set(long, double) + * }. + *

+ * All functions are MT-safe. + */ +public class InterpolationControlSource extends TimedValueControlSource { + + public static final String GTYPE_NAME = "GstInterpolationControlSource"; + + /** + * Create a new, unbound InterpolationControlSource. + */ + public InterpolationControlSource() { + this(new Handle(GSTCONTROLLER_API.gst_interpolation_control_source_new(), true), false); + } + + InterpolationControlSource(Initializer init) { + this(new Handle( + init.ptr.as(GstInterpolationControlSourcePtr.class, + GstInterpolationControlSourcePtr::new), + init.ownsHandle), + init.needRef); + } + + private InterpolationControlSource(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Interpolation mode to use. + * + * @param mode + * @return this + */ + public InterpolationControlSource setMode(InterpolationMode mode) { + set("mode", mode.intValue()); + return this; + } + + /** + * Current interpolation mode. + * + * @return mode + */ + public InterpolationMode getMode() { + Object val = get("mode"); + if (val instanceof Integer) { + int nativeInt = (Integer) val; + return NativeEnum.fromInt(InterpolationMode.class, nativeInt); + } + return InterpolationMode.NONE; + } + + + private static class Handle extends TimedValueControlSource.Handle { + + public Handle(GstInterpolationControlSourcePtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/InterpolationMode.java b/src/org/freedesktop/gstreamer/controller/InterpolationMode.java new file mode 100644 index 0000000..55c4008 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/InterpolationMode.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.glib.NativeEnum; + +/** + * The various interpolation modes available for use with + * {@link InterpolationControlSource}. + */ +// https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstinterpolationcontrolsource.h#L64 +public enum InterpolationMode implements NativeEnum { + + /** + * Steps-like interpolation, default. + */ + NONE(0), + /** + * Linear interpolation. + */ + LINEAR(1), + /** + * Cubic interpolation (natural), may overshoot the min or max values set by + * the control point, but is more 'curvy'. + */ + CUBIC(2), + /** + * Monotonic cubic interpolation, will not produce any values outside of the + * min-max range set by the control points. + */ + CUBIC_MONOTONIC(3); + + private final int value; + + private InterpolationMode(int value) { + this.value = value; + } + + @Override + public int intValue() { + return value; + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/LFOControlSource.java b/src/org/freedesktop/gstreamer/controller/LFOControlSource.java new file mode 100644 index 0000000..1464b83 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/LFOControlSource.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.glib.NativeEnum; +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstLFOControlSourcePtr; + +/** + * LFO control source. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstLFOControlSource.html + *

+ * LFOControlSource is a {@link ControlSource}, that provides several periodic + * waveforms as control values. + *

+ * To use InterpolationControlSource create a new instance, bind it to a + * GParamSpec and set the relevant properties. + *

+ * All functions are MT-safe. + */ +public class LFOControlSource extends ControlSource { + + public static final String GTYPE_NAME = "GstLFOControlSource"; + + /** + * Create a new, unbound LFOControlSource. + */ + public LFOControlSource() { + this(new Handle(GSTCONTROLLER_API.gst_lfo_control_source_new(), true), false); + } + + LFOControlSource(Initializer init) { + this(new Handle( + init.ptr.as(GstLFOControlSourcePtr.class, + GstLFOControlSourcePtr::new), + init.ownsHandle), + init.needRef); + } + + private LFOControlSource(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Specifies the amplitude for the waveform of this LFOControlSource. + *

+ * Allowed values: [0,1] + *

+ * Default value: 1 + * + * @param value amplitude between 0 and 1 + * @return this + */ + public LFOControlSource setAmplitude(double value) { + set("amplitude", value); + return this; + } + + /** + * Get the amplitude of the waveform. + * + * @return amplitude + */ + public double getAmplitude() { + Object val = get("amplitude"); + if (val instanceof Double) { + return (double) val; + } + return 1; + } + + /** + * Specifies the frequency that should be used for the waveform of this + * LFOControlSource. It should be large enough so that the period is longer + * than one nanosecond. + *

+ * Allowed values: >= {@link Double#MIN_VALUE } + *

+ * Default value: 1 + * + * @param value frequency >= {@link Double#MIN_VALUE } + * @return this + */ + public LFOControlSource setFrequency(double value) { + set("frequency", value); + return this; + } + + /** + * Get the frequency of the waveform. + * + * @return amplitude + */ + public double getFrequency() { + Object val = get("frequency"); + if (val instanceof Double) { + return (double) val; + } + return 1; + } + + /** + * Specifies the value offset for the waveform of this LFOControlSource. + *

+ * Allowed values: [0,1] + *

+ * Default value: 1 + * + * @param value offset between 0 and 1 + * @return this + */ + public LFOControlSource setOffset(double value) { + set("offset", value); + return this; + } + + /** + * Get the value offset of the waveform. + * + * @return offset + */ + public double getOffset() { + Object val = get("offset"); + if (val instanceof Double) { + return (double) val; + } + return 1; + } + + /** + * Specifies the timeshift to the right that should be used for the waveform + * of this LFOControlSource in nanoseconds. + *

+ * Default value: 0 + * + * @param value timeshift in nanoseconds + * @return this + */ + public LFOControlSource setTimeshift(long value) { + set("timeshift", value); + return this; + } + + /** + * Get the timeshift of the waveform. + * + * @return timeshift + */ + public long getTimeshift() { + Object val = get("timeshift"); + if (val instanceof Long) { + return (long) val; + } + return 1; + } + + /** + * Specifies the waveform that should be used for this LFOControlSource. + *

+ * Default value: {@link LFOWaveform#SINE } + * + * @param value waveform + * @return this + */ + public LFOControlSource setWaveform(LFOWaveform value) { + set("waveform", value.intValue()); + return this; + } + + /** + * Get the waveform. + * + * @return waveform + */ + public LFOWaveform getWaveform() { + Object val = get("waveform"); + if (val instanceof Integer) { + int nativeInt = (Integer) val; + return NativeEnum.fromInt(LFOWaveform.class, nativeInt); + } + return LFOWaveform.SINE; + } + + private static class Handle extends ControlSource.Handle { + + public Handle(GstLFOControlSourcePtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/LFOWaveform.java b/src/org/freedesktop/gstreamer/controller/LFOWaveform.java new file mode 100644 index 0000000..08bad64 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/LFOWaveform.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.glib.NativeEnum; + +/** + * The various waveform modes available for use with {@link LFOControlSource} + */ +// https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstlfocontrolsource.h#L60 +public enum LFOWaveform implements NativeEnum { + + /** + * Sine waveform. + */ + SINE(0), + + /** + * Square waveform. + */ + SQUARE(1), + + /** + * Saw waveform. + */ + SAW(2), + + /** + * Reverse saw waveform. + */ + REVERSE_SAW(3), + + /** + * Triangle waveform. + */ + TRIANGLE(4) + ; + + + private final int value; + + private LFOWaveform(int value) { + this.value = value; + } + + @Override + public int intValue() { + return value; + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java b/src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java new file mode 100644 index 0000000..76cc54b --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlBinding; +import org.freedesktop.gstreamer.Gst; +import org.freedesktop.gstreamer.GstObject; +import org.freedesktop.gstreamer.glib.Natives; + +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; +import org.freedesktop.gstreamer.lowlevel.GstProxyControlBindingPtr; + +/** + * Attachment for forwarding control sources + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html + *

+ */ +@Gst.Since(minor = 12) +public class ProxyControlBinding extends ControlBinding { + + public static final String GTYPE_NAME = "GstProxyControlBinding"; + + ProxyControlBinding(Initializer init) { + this(new Handle( + init.ptr.as(GstProxyControlBindingPtr.class, GstProxyControlBindingPtr::new), + init.ownsHandle), + init.needRef); + } + + private ProxyControlBinding(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Create a ProxyControlBinding that forwards all access to data or + * syncValues() requests from propertyName on object to the control + * binding at refPropertyName on refObject . + * + * @param object the object of the property + * @param propertyName the property-name to attach the control source + * @param refObject a GstObject to forward all ControlBinding requests to + * @param refPropertyName the property name in refObject to control + * @return new ProxyControlBinding + */ + @Gst.Since(minor = 12) + public static ProxyControlBinding create(GstObject object, String propertyName, + GstObject refObject, String refPropertyName) { + GstProxyControlBindingPtr ptr = GSTCONTROLLER_API.gst_proxy_control_binding_new( + Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), + propertyName, + Natives.getPointer(refObject).as(GstObjectPtr.class, GstObjectPtr::new), + refPropertyName); + return new ProxyControlBinding(new Handle(ptr, true), false); + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java b/src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java new file mode 100644 index 0000000..c425843 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import java.util.ArrayList; +import java.util.List; +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstTimedValueControlSourcePtr; + +/** + * Timed value control source base class. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTimedValueControlSource.html + *

+ * Base class for {@link ControlSource} that use time-stamped values. + *

+ * When overriding bind, chain up first to give this bind implementation a + * chance to setup things. + *

+ * All functions are MT-safe. + */ +public class TimedValueControlSource extends ControlSource { + + public static final String GTYPE_NAME = "GstTimedValueControlSource"; + + private final Handle handle; + + protected TimedValueControlSource(Handle handle, boolean needRef) { + super(handle, needRef); + this.handle = handle; + } + + TimedValueControlSource(Initializer init) { + this(new Handle( + init.ptr.as(GstTimedValueControlSourcePtr.class, + GstTimedValueControlSourcePtr::new), + init.ownsHandle), + init.needRef); + } + + /** + * Set the value of given controller-handled property at a certain time. + * + * @param timestamp the time the control-change is scheduled for + * @param value the control value + * @return false if the value could not be set + */ + public boolean set(long timestamp, double value) { + return GSTCONTROLLER_API.gst_timed_value_control_source_set( + handle.getPointer(), timestamp, value); + } + + /** + * Sets multiple timed values at once. + * + * @param timedValues a list of {@link TimedValue} + * @return false if the values could not be set + */ + public boolean setFromList(List timedValues) { + for (TimedValue timedvalue : timedValues) { + boolean ok = set(timedvalue.timestamp, timedvalue.value); + if (!ok) { + return false; + } + } + return true; + } + + /** + * Returns a copy of the list of {@link TimedValue} for the given property. + * + * @return a list of TimedValue + */ + public List getAll() { + GList next = + GSTCONTROLLER_API.gst_timed_value_control_source_get_all(handle.getPointer()); + List list = new ArrayList<>(); + while (next != null) { + if (next.data != null) { + list.add(new TimedValue(next.data.getLong(0), next.data.getDouble(Long.BYTES))); + } + next = next.next(); + } + return list; + } + + /** + * Used to remove the value of given controller-handled property at a + * certain time. + * + * @param timestamp the time the control-change should be removed from + * @return FALSE if the value couldn't be unset (i.e. not found) + */ + public boolean unset(long timestamp) { + return GSTCONTROLLER_API.gst_timed_value_control_source_unset( + handle.getPointer(), timestamp); + } + + /** + * Used to remove all time-stamped values of given controller-handled + * property. + */ + public void unsetAll() { + GSTCONTROLLER_API.gst_timed_value_control_source_unset_all(handle.getPointer()); + } + + /** + * Get the number of control points that are set. + * + * @return the number of control points that are set + */ + public int getCount() { + return GSTCONTROLLER_API.gst_timed_value_control_source_get_count(handle.getPointer()); + } + + /** + * Reset the controlled value cache. + */ + public void invalidateCache() { + GSTCONTROLLER_API.gst_timed_value_control_invalidate_cache(handle.getPointer()); + } + + + protected static class Handle extends ControlSource.Handle { + + public Handle(GstTimedValueControlSourcePtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + @Override + protected GstTimedValueControlSourcePtr getPointer() { + return (GstTimedValueControlSourcePtr) super.getPointer(); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/controller/TriggerControlSource.java b/src/org/freedesktop/gstreamer/controller/TriggerControlSource.java new file mode 100644 index 0000000..e5b8b32 --- /dev/null +++ b/src/org/freedesktop/gstreamer/controller/TriggerControlSource.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.controller; + +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.glib.NativeEnum; +import org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr; + +import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; +import org.freedesktop.gstreamer.lowlevel.GstTriggerControlSourcePtr; + +/** + * Trigger control source. + *

+ * See upstream documentation at + * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTriggerControlSource.html + *

+ * TriggerControlSource is a {@link ControlSource}, that returns values from + * user-given control points. It allows for a tolerance on time-stamps. + *

+ * To use TriggerControlSource create a new instance, bind it to a GParamSpec + * and set some control points by calling + * {@link TimedValueControlSource#set(long, double)}. + *

+ * All functions are MT-safe. + */ +public class TriggerControlSource extends TimedValueControlSource { + + public static final String GTYPE_NAME = "GstTriggerControlSource"; + + /** + * Create a new, unbound InterpolationControlSource. + */ + public TriggerControlSource() { + this(new Handle(GSTCONTROLLER_API.gst_trigger_control_source_new(), true), false); + } + + TriggerControlSource(Initializer init) { + this(new Handle( + init.ptr.as(GstTriggerControlSourcePtr.class, + GstTriggerControlSourcePtr::new), + init.ownsHandle), + init.needRef); + } + + private TriggerControlSource(Handle handle, boolean needRef) { + super(handle, needRef); + } + + /** + * Amount of nanoseconds a control time can be off to still trigger. + *

+ * Allowed values: >= 0 + *

+ * Default value: 0 + * + * @param tolerance in nanoseconds + * @return this + */ + public TriggerControlSource setTolerance(long tolerance) { + set("tolerance", tolerance); + return this; + } + + /** + * Current tolerance in nanoseconds. + * + * @return tolerance in nanoseconds + */ + public long getTolerance() { + Object val = get("tolerance"); + if (val instanceof Long) { + return (long) val; + } + return 0L; + } + + private static class Handle extends TimedValueControlSource.Handle { + + public Handle(GstTriggerControlSourcePtr ptr, boolean ownsHandle) { + super(ptr, ownsHandle); + } + + } + +} diff --git a/src/org/freedesktop/gstreamer/glib/Natives.java b/src/org/freedesktop/gstreamer/glib/Natives.java index e67e4d9..f69c18f 100644 --- a/src/org/freedesktop/gstreamer/glib/Natives.java +++ b/src/org/freedesktop/gstreamer/glib/Natives.java @@ -102,6 +102,23 @@ public static final NativeObject.Initializer initializer(Pointer ptr, boolean ne public static T objectFor(Pointer ptr, Class cls, boolean needRef, boolean ownsHandle) { return objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle); } + + /** + * Get a {@link NativeObject} instance of the requested type for the + * provided Pointer. Will return a cached instance if one already exists. + * + * @param NativeObject type to return + * @param ptr native Pointer + * @param cls Class of type T + * @param needRef whether to request a ref increase (only relevant if T is + * subclass of {@link RefCountedObject}) + * @param ownsHandle whether the NativeObject will own the handle, and + * should dispose of the native resource when GC'd or explicitly disposed. + * @return native object of type T + */ + public static T objectFor(GPointer ptr, Class cls, boolean needRef, boolean ownsHandle) { + return NativeObject.objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle); + } /** * Get a {@link NativeObject} instance of the requested type for the @@ -120,6 +137,24 @@ public static T objectFor(Pointer ptr, Class cls, bo public static T callerOwnsReturn(Pointer ptr, Class cls) { return objectFor(ptr, cls, -1, true); } + + /** + * Get a {@link NativeObject} instance of the requested type for the + * provided Pointer, for use with native functions returning + * {@code Transfer Full} or {@code Transfer Floating} results. + *

+ * This method will return a cached instance if one already exists. If the + * cached instance is a {@link RefCountedObject} this method will release a + * reference. + * + * @param NativeObject type to return + * @param ptr native Pointer + * @param cls Class of type T + * @return native object of type T + */ + public static T callerOwnsReturn(GPointer ptr, Class cls) { + return NativeObject.objectFor(ptr, cls, -1, true); + } private static T objectFor(Pointer ptr, Class cls, int refAdjust, boolean ownsHandle) { final GPointer gptr = GObject.class.isAssignableFrom(cls) ? new GObjectPtr(ptr) @@ -127,7 +162,7 @@ private static T objectFor(Pointer ptr, Class cls, i : new GPointer(ptr); return NativeObject.objectFor(gptr, cls, refAdjust, ownsHandle); } - + /** * Get the underlying raw native Pointer for a {@link NativeObject}. * diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java new file mode 100644 index 0000000..364588f --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstARGBControlBindingPtr extends GstControlBindingPtr { + + public GstARGBControlBindingPtr() { + } + + public GstARGBControlBindingPtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java b/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java new file mode 100644 index 0000000..f038bc3 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ + +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Library; + +/** + * GstControlBinding API + * + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html + * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller + */ + +public interface GstControlBindingAPI extends Library { + + GstControlBindingAPI GSTCONTROLBINDING_API = GstNative.load(GstControlBindingAPI.class); + + + boolean gst_control_binding_sync_values(GstControlBindingPtr binding, + GstObjectPtr object, + long timestamp, + long lastSync); + + GValueAPI.GValue gst_control_binding_get_value(GstControlBindingPtr binding, + long timestamp); + + boolean gst_control_binding_get_g_value_array(GstControlBindingPtr binding, + long timestamp, + long internal, + int n_values, + GValueAPI.GValueArray values); + + void gst_control_binding_set_disabled(GstControlBindingPtr binding, + boolean disabled); + + boolean gst_control_binding_is_disabled(GstControlBindingPtr binding); + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java new file mode 100644 index 0000000..f9517d3 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstControlBindingPtr extends GstObjectPtr { + + public GstControlBindingPtr() { + } + + public GstControlBindingPtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java b/src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java index db617c1..eacfb70 100644 --- a/src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java +++ b/src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Levente Farkas + * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * @@ -18,111 +18,51 @@ package org.freedesktop.gstreamer.lowlevel; -//import org.freedesktop.gstreamer.controller.ControlSource; -import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GParamSpec; -import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; - -import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Pointer; -import com.sun.jna.ptr.DoubleByReference; -import java.util.Arrays; -import java.util.List; -import org.freedesktop.gstreamer.GstObject; -import static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_PADDING; -import org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GstObjectClass; +import com.sun.jna.Structure; /** - * GstControlSource methods and structures - * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstcontrolsource.h?h=1.8 + * GstControlSource API + * + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html + * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller */ -// @TODO review in line with https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller - public interface GstControlSourceAPI extends Library { -// -// GstControlSourceAPI GSTCONTROLSOURCE_API = GstNative.load("gstcontroller", GstControlSourceAPI.class); -// -// /** -// * GstTimedValue: -// * @timestamp: timestamp of the value change -// * @value: the corresponding value -// * -// * Structure for saving a timestamp and a value. -// */ -// public static final class TimedValue extends com.sun.jna.Structure { -// public static final String GTYPE_NAME = "GstTimedValue"; -// -// public volatile long timestamp; -// public volatile double value; -// -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{ -// "timestamp", "value" -// }); -// } -// } -// -// public static interface GstControlSourceGetValue extends Callback { -// public boolean callback(ControlSource self, long timestamp, DoubleByReference value); -// } -// public static interface GstControlSourceGetValueArray extends Callback { -// public boolean callback(ControlSource self, long timestamp, long interval, int n_values, DoubleByReference values); -// } -// public static interface GstControlSourceBind extends Callback { -// public boolean callback(ControlSource self, GParamSpec pspec); -// } -// -// /** -// * GstControlSource: -// * @get_value: Function for returning a value for a given timestamp -// * @get_value_array: Function for returning a values array for a given timestamp -// * -// * The instance structure of #GstControlSource. -// */ -// public static final class GstControlSourceStruct extends com.sun.jna.Structure { -// public volatile GstObject parent; -// -// /*< public >*/ -// public volatile GstControlSourceGetValue get_value; /* Returns the value for a property at a given timestamp */ -// public volatile GstControlSourceGetValueArray get_value_array; /* Returns values for a property in a given timespan */ -// -// /*< private >*/ -// public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; + + GstControlSourceAPI GSTCONTROLSOURCE_API = GstNative.load(GstControlSourceAPI.class); + + + boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value); + boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values); + +// static class Direct implements GstControlSourceAPI { // // @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{ -// "parent", "get_value", "get_value_array", -// "_gst_reserved" -// }); -// } -// } -// -// /** -// * GstControlSourceClass: -// * @parent_class: Parent class -// * -// * The class structure of #GstControlSource. -// */ -// public static final class GstControlSourceClass extends com.sun.jna.Structure { -// public volatile GstObjectClass parent_class; -// -// /*< private >*/ -// public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; +// public native boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value); // // @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{ -// "parent_class", "_gst_reserved" -// }); -// } +// public native boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values); +// // } -// -// GType gst_control_source_get_type(); -// -// /* Functions */ -// boolean gst_control_source_get_value(ControlSource self, long timestamp, GValue value); -// boolean gst_control_source_get_value_array(ControlSource self, long timestamp, long interval, int n_values, DoubleByReference values); + + @Structure.FieldOrder({"timestamp", "value"}) + public static final class GstTimedValue extends Structure { + + public volatile long timestamp; + public volatile double value; + + public GstTimedValue() { + super(); + } + + public GstTimedValue(Pointer ptr) { + super(ptr); + } + + } + + + } diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java new file mode 100644 index 0000000..7bedfbd --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstControlSourcePtr extends GstObjectPtr { + + public GstControlSourcePtr() { + } + + public GstControlSourcePtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java b/src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java new file mode 100644 index 0000000..6f8ed29 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Library; +import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; + +/** + * GstController API functions + * + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTimedValueControlSource.html + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstInterpolationControlSource.html + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstLFOControlSource.html + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTriggerControlSource.html + * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstDirectControlBinding.html + * + */ +public interface GstControllerAPI extends Library { + + GstControllerAPI GSTCONTROLLER_API = GstNative.load("gstcontroller", GstControllerAPI.class); + + @CallerOwnsReturn GstTriggerControlSourcePtr gst_trigger_control_source_new(); + + @CallerOwnsReturn GstInterpolationControlSourcePtr gst_interpolation_control_source_new(); + + @CallerOwnsReturn GstLFOControlSourcePtr gst_lfo_control_source_new(); + + @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new( + GstObjectPtr object, + String property_name, + GstControlSourcePtr cs); + + @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new_absolute( + GstObjectPtr object, + String property_name, + GstControlSourcePtr cs); + + @CallerOwnsReturn GstARGBControlBindingPtr gst_argb_control_binding_new( + GstObjectPtr object, + String property_name, + GstControlSourcePtr cs_a, + GstControlSourcePtr cs_r, + GstControlSourcePtr cs_g, + GstControlSourcePtr cs_b); + + // since 1.12 + @CallerOwnsReturn GstProxyControlBindingPtr gst_proxy_control_binding_new( + GstObjectPtr object, + String property_name, + GstObjectPtr ref_object, + String ref_property_name); + + + // GSequenceIter gst_timed_value_control_source_find_control_point_iter( + // GstTimedValueControlSourcePtr self, + // long timestamp); + + boolean gst_timed_value_control_source_set(GstTimedValueControlSourcePtr self, + long timestamp, + double value); + + boolean gst_timed_value_control_source_set_from_list( + GstTimedValueControlSourcePtr self, + GlibAPI.GSList timedvalues); + + // transfer container + // caller owns list, not contained values! + @CallerOwnsReturn GlibAPI.GList gst_timed_value_control_source_get_all( + GstTimedValueControlSourcePtr self); + + boolean gst_timed_value_control_source_unset(GstTimedValueControlSourcePtr self, + long timestamp); + + void gst_timed_value_control_source_unset_all(GstTimedValueControlSourcePtr self); + + int gst_timed_value_control_source_get_count(GstTimedValueControlSourcePtr self); + + void gst_timed_value_control_invalidate_cache(GstTimedValueControlSourcePtr self); + + // gst_control_point_copy + // gst_control_point_free + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java new file mode 100644 index 0000000..5ac7d80 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstDirectControlBindingPtr extends GstControlBindingPtr { + + public GstDirectControlBindingPtr() { + } + + public GstDirectControlBindingPtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java new file mode 100644 index 0000000..3dc8bea --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstInterpolationControlSourcePtr extends GstTimedValueControlSourcePtr { + + public GstInterpolationControlSourcePtr() { + } + + public GstInterpolationControlSourcePtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourceAPI.java b/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourceAPI.java deleted file mode 100644 index ad9890d..0000000 --- a/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourceAPI.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009 Levente Farkas - * - * This file is part of gstreamer-java. - * - * This code is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License version 3 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * version 3 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with this work. If not, see . - */ - -package org.freedesktop.gstreamer.lowlevel; - -//import org.freedesktop.gstreamer.controller.LFOControlSource; -//import org.freedesktop.gstreamer.lowlevel.GstControlSourceAPI.GstControlSourceClass; -//import org.freedesktop.gstreamer.lowlevel.GstControlSourceAPI.GstControlSourceStruct; - -import com.sun.jna.Library; -import com.sun.jna.Pointer; -import java.util.Arrays; -import java.util.List; - -// @TODO review in line with https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstlfocontrolsource.h - -public interface GstLFOControlSourceAPI extends Library { -// GstLFOControlSourceAPI GSTLFOCONTROLSOURCE_API = GstNative.load("gstcontroller", GstLFOControlSourceAPI.class); -// int GST_PADDING = GstAPI.GST_PADDING; -// -// public enum Waveform -// { -// SINE, -// SQUARE, -// SAW, -// REVERSE_SAW, -// TRIANGLE; -// } -// -// public static final class GstLFOControlSourceStruct extends com.sun.jna.Structure { -// public volatile GstControlSourceStruct parent; -// -// /* */ -// public volatile Pointer /* GstLFOControlSourcePrivate */ priv; -// public volatile Pointer /* GMutex */ lock; -// public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; -// -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{ -// "parent", "priv", "lock", -// "_gst_reserved" -// }); -// } -// } -// -// public static final class GstLFOControlSourceClass extends com.sun.jna.Structure { -// public volatile GstControlSourceClass parent_class; -// -// /*< private >*/ -// public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; -// -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{ -// "parent_class", "_gst_reserved" -// }); -// } -// } -// -// GType gst_lfo_control_source_get_type(); -// GType gst_lfo_waveform_get_type(); -// -// /* Functions */ -// LFOControlSource gst_lfo_control_source_new(); -} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java new file mode 100644 index 0000000..23f857e --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstLFOControlSourcePtr extends GstControlSourcePtr { + + public GstLFOControlSourcePtr() { + } + + public GstLFOControlSourcePtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java b/src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java index bba263d..a90db11 100644 --- a/src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java +++ b/src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * @@ -28,8 +29,6 @@ import com.sun.jna.Pointer; import java.util.Arrays; import java.util.List; -import org.freedesktop.gstreamer.Caps; -import org.freedesktop.gstreamer.elements.BaseSrc; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; /** @@ -59,6 +58,17 @@ public interface GstObjectAPI extends com.sun.jna.Library { Pointer gst_implements_interface_cast(GstObject obj, NativeLong gtype); boolean gst_implements_interface_check(GstObject from, NativeLong type); + /* controller functions */ + long gst_object_suggest_next_sync(GstObjectPtr object); + boolean gst_object_sync_values(GstObjectPtr object, long timestamp); + boolean gst_object_has_active_control_bindings(GstObjectPtr object); + void gst_object_set_control_bindings_disabled(GstObjectPtr object, boolean disabled); + void gst_object_set_control_binding_disabled(GstObjectPtr object, String property_name, boolean disabled); + boolean gst_object_add_control_binding(GstObjectPtr object, GstControlBindingPtr binding); + GstControlBindingPtr gst_object_get_control_binding(GstObjectPtr object, String property_name); + boolean gst_object_remove_control_binding(GstObjectPtr object, GstControlBindingPtr binding); + + /** * GstObject: * @lock: object LOCK diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java new file mode 100644 index 0000000..ae11281 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstProxyControlBindingPtr extends GstControlBindingPtr { + + public GstProxyControlBindingPtr() { + } + + public GstProxyControlBindingPtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java new file mode 100644 index 0000000..3c423f3 --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstTimedValueControlSourcePtr extends GstControlSourcePtr { + + public GstTimedValueControlSourcePtr() { + } + + public GstTimedValueControlSourcePtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java b/src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java new file mode 100644 index 0000000..6547d0b --- /dev/null +++ b/src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Neil C Smith + * + * This file is part of gstreamer-java. + * + * This code is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License version 3 only, as published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License version 3 for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 along with + * this work. If not, see . + */ +package org.freedesktop.gstreamer.lowlevel; + +import com.sun.jna.Pointer; + +/** + * + */ +public class GstTriggerControlSourcePtr extends GstTimedValueControlSourcePtr { + + public GstTriggerControlSourcePtr() { + } + + public GstTriggerControlSourcePtr(Pointer ptr) { + super(ptr); + } + +} diff --git a/test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java b/test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java new file mode 100644 index 0000000..98d9359 --- /dev/null +++ b/test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java @@ -0,0 +1,145 @@ +package org.freedesktop.gstreamer.controller; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.freedesktop.gstreamer.ClockTime; +import org.freedesktop.gstreamer.ControlBinding; +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.Element; +import org.freedesktop.gstreamer.ElementFactory; +import org.freedesktop.gstreamer.GCTracker; +import org.freedesktop.gstreamer.Gst; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + */ +public class InterpolationControlSourceTest { + + public InterpolationControlSourceTest() { + } + + @BeforeClass + public static void setUpClass() { + Gst.init("InterpolationControlSourceTest"); + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of setMode method, of class InterpolationControlSource. + */ + @Test + public void testMode() { + InterpolationControlSource controller = new InterpolationControlSource(); + InterpolationMode[] modes = InterpolationMode.values(); + for (InterpolationMode mode : modes) { + controller.setMode(mode); + assertEquals(mode, controller.getMode()); + } + } + + @Test + public void testSetValue() { + List timedValue + = Collections.singletonList( + new ControlSource.TimedValue(ClockTime.fromSeconds(10), 0.5) + ); + InterpolationControlSource controller = new InterpolationControlSource(); + controller.set(timedValue.get(0).timestamp, timedValue.get(0).value); + assertEquals(timedValue, controller.getAll()); + } + + @Test + public void testSetValues() { + List timedValues + = Stream.of( + new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), + new ControlSource.TimedValue(ClockTime.fromSeconds(1), 0.5), + new ControlSource.TimedValue(ClockTime.fromSeconds(2), 0.2), + new ControlSource.TimedValue(ClockTime.fromSeconds(4), 0.8) + ).collect(Collectors.toList()); + InterpolationControlSource controller = new InterpolationControlSource(); + controller.setFromList(timedValues); + assertEquals(timedValues, controller.getAll()); + } + + @Test + public void testLinearInterpolation() { + List timedValues + = Stream.of( + new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), + new ControlSource.TimedValue(ClockTime.fromSeconds(1), 1.0) + ).collect(Collectors.toList()); + InterpolationControlSource controller = new InterpolationControlSource(); + controller.setMode(InterpolationMode.LINEAR); + controller.setFromList(timedValues); + + Element volume = ElementFactory.make("volume", "volume"); + volume.addControlBinding(DirectControlBinding.create(volume, "volume", controller)); + volume.syncValues(0); + assertEquals(0, ((Double) volume.get("volume")).doubleValue(), 0.001); + volume.syncValues(ClockTime.fromMillis(500)); + assertEquals(5, ((Double) volume.get("volume")).doubleValue(), 0.001); + volume.syncValues(ClockTime.fromSeconds(1)); + assertEquals(10, ((Double) volume.get("volume")).doubleValue(), 0.001); + + } + + @Test + public void testLinearInterpolationAbsolute() { + List timedValues + = Stream.of( + new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), + new ControlSource.TimedValue(ClockTime.fromSeconds(1), 5.0) + ).collect(Collectors.toList()); + InterpolationControlSource controller = new InterpolationControlSource(); + controller.setMode(InterpolationMode.LINEAR); + controller.setFromList(timedValues); + + Element volume = ElementFactory.make("volume", "volume"); + volume.addControlBinding(DirectControlBinding.createAbsolute(volume, "volume", controller)); + volume.syncValues(0); + assertEquals(0, ((Double) volume.get("volume")).doubleValue(), 0.001); + volume.syncValues(ClockTime.fromMillis(500)); + assertEquals(2.5, ((Double) volume.get("volume")).doubleValue(), 0.001); + volume.syncValues(ClockTime.fromSeconds(1)); + assertEquals(5, ((Double) volume.get("volume")).doubleValue(), 0.001); + + } + + @Test + public void testGC() { + InterpolationControlSource controller = new InterpolationControlSource(); + Element volume = ElementFactory.make("volume", "volume"); + ControlBinding binding = DirectControlBinding.create(volume, "volume", controller); + volume.addControlBinding(binding); + + GCTracker tracker = new GCTracker(controller); + controller = null; + binding = null; + volume = null; + + assertTrue("Controller not garbage collected", tracker.waitGC()); + assertTrue("Controller not destroyed", tracker.waitDestroyed()); + + } + +} diff --git a/test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java b/test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java new file mode 100644 index 0000000..f6e41ed --- /dev/null +++ b/test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java @@ -0,0 +1,95 @@ +package org.freedesktop.gstreamer.controller; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.freedesktop.gstreamer.ClockTime; +import org.freedesktop.gstreamer.ControlBinding; +import org.freedesktop.gstreamer.ControlSource; +import org.freedesktop.gstreamer.Element; +import org.freedesktop.gstreamer.ElementFactory; +import org.freedesktop.gstreamer.GCTracker; +import org.freedesktop.gstreamer.Gst; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + */ +public class TriggerControlSourceTest { + + public TriggerControlSourceTest() { + } + + @BeforeClass + public static void setUpClass() { + Gst.init("InterpolationControlSourceTest"); + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + + @Test + public void testTolerance() { + List timedValues + = Stream.of( + new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.5), + new ControlSource.TimedValue(ClockTime.fromSeconds(2), 1.0) + ).collect(Collectors.toList()); + TriggerControlSource controller = new TriggerControlSource(); + controller.setFromList(timedValues); + + Element volume = ElementFactory.make("volume", "volume"); + volume.addControlBinding(DirectControlBinding.create(volume, "volume", controller)); + volume.syncValues(0); + assertEquals(5, ((Double) volume.get("volume")), 0.001); + volume.set("volume", 0); + volume.syncValues(ClockTime.fromSeconds(1)); + assertEquals(0, ((Double) volume.get("volume")), 0.001); + volume.syncValues(ClockTime.fromSeconds(2)); + assertEquals(10, ((Double) volume.get("volume")), 0.001); + + controller.setTolerance(ClockTime.fromMillis(500)); + volume.syncValues(ClockTime.fromMillis(450)); + assertEquals(5, ((Double) volume.get("volume")), 0.001); + volume.set("volume", 0); + volume.syncValues(ClockTime.fromMillis(550)); + assertEquals(0, ((Double) volume.get("volume")), 0.001); + volume.syncValues(ClockTime.fromMillis(1650)); + assertEquals(10, ((Double) volume.get("volume")), 0.001); + + } + + @Test + public void testGC() { + TriggerControlSource controller = new TriggerControlSource(); + Element volume = ElementFactory.make("volume", "volume"); + ControlBinding binding = DirectControlBinding.create(volume, "volume", controller); + volume.addControlBinding(binding); + + GCTracker tracker = new GCTracker(controller); + controller = null; + binding = null; + volume = null; + + assertTrue("Controller not garbage collected", tracker.waitGC()); + assertTrue("Controller not destroyed", tracker.waitDestroyed()); + + } + +}