* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBin.html *
* Bin is an element that can contain other {@link Element}s, allowing them to * be managed as a group. *
* Pads from the child elements can be ghosted to the bin, see {@link GhostPad}. * This makes the bin look like any other elements and enables creation of * higher-level abstraction elements. *
* A new {@link Bin} is created with {@link Bin#Bin(String)}. Use a * {@link Pipeline} instead if you want to create a toplevel bin because a * normal bin doesn't have a bus or handle clock distribution of its own. *
* After the bin has been created you will typically add elements to it with * {@link Bin#add(Element)}. Elements can be removed with * {@link Bin#remove(Element)} *
* An element can be retrieved from a bin with * {@link Bin#getElementByName(String)}. *
* A list of elements contained in a bin can be retrieved with * {@link Bin#getElements} * * The {@link ELEMENT_ADDED} signal is fired whenever a new element is added to * the bin. Likewise the {@link ELEMENT_REMOVED} signal is fired whenever an * element is removed from the bin. * */ public class Bin extends Element { public static final String GST_NAME = "bin"; public static final String GTYPE_NAME = "GstBin"; protected Bin(Initializer init) { super(init); } Bin(Handle handle, boolean needRef) { super(handle, needRef); } /** * Creates a new Bin with a unique name. */ public Bin() { this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(null), false, true)); } /** * Creates a new Bin with the given name. * * @param name The Name to assign to the new Bin */ public Bin(String name) { this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(name), false, true)); } /** * Adds an Element to this Bin. *
* Sets the element's parent, and thus takes ownership of the element. An * element can only be added to one bin. *
* If the element's pads are linked to other pads, the pads will be unlinked * before the element is added to the bin. * * @param element The {@link Element} to add to this Bin. * @return true if the element was successfully added, false if the Bin will * not accept the element. */ public boolean add(Element element) { return GSTBIN_API.gst_bin_add(this, element); } /** * Adds an array of Element objects to this Bin * * @param elements The array of {@link Element} to add to this Bin * @see Bin#add(Element) */ public void addMany(Element... elements) { GSTBIN_API.gst_bin_add_many(this, elements); } /** * Removes a Element from this Bin *
* Removes the element from the bin, unparenting it as well.
*
* If the element's pads are linked to other pads, the pads will be unlinked
* before the element is removed from the bin.
*
* @param element The {@link Element} to remove
* @return true if the element was successfully removed
*/
public boolean remove(Element element) {
return GSTBIN_API.gst_bin_remove(this, element);
}
/**
* Removes an array of {@link Element} objects from this Bin
*
* @param elements The list {@link Element} to remove
*/
public void removeMany(Element... elements) {
GSTBIN_API.gst_bin_remove_many(this, elements);
}
private List
* The function is only active if gstreamer is configured with
* "--gst-enable-gst-debug" and the environment variable
* GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp).
*
* @param details to show in the graph
* @param fileName output base filename (e.g. "myplayer")
*/
public void debugToDotFile(EnumSet
* The function is only active if gstreamer is configured with
* "--gst-enable-gst-debug" and the environment variable
* GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp).
*
* Unlike {@link #debugToDotFile(java.util.EnumSet, java.lang.String)} this
* method adds the current timestamp to the filename, so that it can be
* used to take multiple snapshots.
*
* @param details to show in the graph
* @param fileName output base filename (e.g. "myplayer")
*/
public void debugToDotFileWithTS(EnumSet
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBuffer.html
*/
public class Buffer extends MiniObject {
public static final String GTYPE_NAME = "GstBuffer";
private final MapInfoStruct mapInfo;
private final BufferStruct struct;
/**
* Creates a newly allocated buffer without any data.
*/
public Buffer() {
this(Natives.initializer(GSTBUFFER_API.ptr_gst_buffer_new()));
}
/**
* Creates a newly allocated buffer with data of the given size. The buffer
* memory is not cleared. If the requested amount of memory cannot be
* allocated, an exception will be thrown.
*
* Note that when size == 0, the buffer data pointer will be NULL.
*
* @param size
*/
public Buffer(int size) {
this(Natives.initializer(allocBuffer(size)));
}
Buffer(Initializer init) {
super(init);
mapInfo = new MapInfoStruct();
struct = new BufferStruct(getRawPointer());
}
private static Pointer allocBuffer(int size) {
Pointer ptr = GSTBUFFER_API.ptr_gst_buffer_new_allocate(null, size, null);
if (ptr == null) {
throw new OutOfMemoryError("Could not allocate Buffer of size " + size);
}
return ptr;
}
/**
* Gets a {@link java.nio.ByteBuffer} that can access the native memory
* associated with this Buffer, with the option of ensuring the memory is
* writable.
*
* When requesting a writable buffer, if the buffer is writable but the
* underlying memory isn't, a writable copy will automatically be created
* and returned. The readonly copy of the buffer memory will then also be
* replaced with this writable copy.
*
* The Buffer should be unmapped with {@link #unmap()} after usage.
*
* @param writable
* @return A {@link java.nio.ByteBuffer} that can access this Buffer's data.
*/
public ByteBuffer map(boolean writable) {
final boolean ok = GSTBUFFER_API.gst_buffer_map(this, mapInfo,
writable ? GstBufferAPI.GST_MAP_WRITE : GstBufferAPI.GST_MAP_READ);
if (ok && mapInfo.data != null) {
return mapInfo.data.getByteBuffer(0, mapInfo.size.intValue());
}
return null;
}
/**
* Release the memory previously mapped with {@link #map(boolean)}
*/
public void unmap() {
GSTBUFFER_API.gst_buffer_unmap(this, mapInfo);
}
/**
* Get the amount of memory blocks that this buffer has. This amount is never
* larger than what {@code gst_buffer_get_max_memory()} returns.
*
* @return the number of memory blocks this buffer is made of.
*/
public int getMemoryCount() {
return GSTBUFFER_API.gst_buffer_n_memory(this);
}
/**
* Gets the timestamps of this buffer. The buffer DTS refers to the
* timestamp when the buffer should be decoded and is usually monotonically
* increasing.
*
* @return a long representing the timestamp or {@link ClockTime#NONE}
* when the timestamp is not known or relevant.
*/
public long getDecodeTimestamp() {
return (long) this.struct.readField("dts");
}
/**
* Set the decode timestamp of the Buffer
*
* @param val a long representing the timestamp or
* {@link ClockTime#NONE} when the timestamp is not known or relevant.
*/
public void setDecodeTimestamp(long val) {
this.struct.writeField("dts", val);
}
/**
* Gets the timestamps of this buffer. The buffer PTS refers to the
* timestamp when the buffer content should be presented to the user and is
* not always monotonically increasing.
*
* @return a long representing the timestamp or {@link ClockTime#NONE}
* when the timestamp is not known or relevant.
*/
public long getPresentationTimestamp() {
return (long) this.struct.readField("pts");
}
/**
* Set the presentation timestamp of the Buffer
*
* @param val a long representing the timestamp or
* {@link ClockTime#NONE} when the timestamp is not known or relevant.
*/
public void setPresentationTimestamp(long val) {
this.struct.writeField("pts", val);
}
/**
* Gets the duration of this buffer.
*
* @return a ClockTime representing the timestamp or {@link ClockTime#NONE}
* when the timestamp is not known or relevant.
*/
public long getDuration() {
return (long) this.struct.readField("duration");
}
/**
* Set the duration of this buffer.
*
* @param val a long representing the duration or
* {@link ClockTime#NONE} when the timestamp is not known or relevant.
*/
public void setDuration(long val) {
this.struct.writeField("duration", val);
}
/**
* Get the offset (media-specific) of this buffer
*
* @return a media specific offset for the buffer data. For video frames,
* this is the frame number of this buffer. For audio samples, this is the
* offset of the first sample in this buffer. For file data or compressed
* data this is the byte offset of the first byte in this buffer.
*/
public long getOffset() {
return (Long) this.struct.readField("offset");
}
/**
* Set the offset (media-specific) of this buffer
*
* @param val a media specific offset for the buffer data. For video frames,
* this is the frame number of this buffer. For audio samples, this is the
* offset of the first sample in this buffer. For file data or compressed
* data this is the byte offset of the first byte in this buffer.
*/
public void setOffset(long val) {
this.struct.writeField("offset", val);
}
/**
* Get the offset (media-specific) of this buffer
*
* @return a media specific offset for the buffer data. For video frames,
* this is the frame number of this buffer. For audio samples, this is the
* offset of the first sample in this buffer. For file data or compressed
* data this is the byte offset of the first byte in this buffer.
*/
public long getOffsetEnd() {
return (Long) this.struct.readField("offset_end");
}
/**
* Set the offset (media-specific) of this buffer
*
* @param val a media specific offset for the buffer data. For video frames,
* this is the frame number of this buffer. For audio samples, this is the
* offset of the first sample in this buffer. For file data or compressed
* data this is the byte offset of the first byte in this buffer.
*/
public void setOffsetEnd(long val) {
this.struct.writeField("offset_end", val);
}
/**
* Get the GstBufferFlags describing this buffer.
*
* Since GStreamer 1.10
*
* @return an EnumSet of {@link BufferFlags}
*/
@Gst.Since(minor = 10)
public EnumSet
* Since GStreamer 1.14
*
* @param
* Since GStreamer 1.14
*
* @param
* Since GStreamer 1.10
*
* @param flags an EnumSet of {@link BufferFlags} to be set on the buffer.
* @return true if flags were successfully set on this buffer
*/
@Gst.Since(minor = 10)
public boolean setFlags(EnumSet
* Since GStreamer 1.10
*
* @param flags an EnumSet of {@link BufferFlags} to be cleared on the buffer.
* @return true if flags were successfully cleared on this buffer
*
*/
@Gst.Since(minor = 10)
public boolean unsetFlags(EnumSet
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBufferPool.html
*/
public class BufferPool extends GstObject {
public static final String GTYPE_NAME = "GstBufferPool";
/**
* Creates a new instance of BufferPool
*/
public BufferPool() {
this(Natives.initializer(GstBufferPoolAPI.GSTBUFFERPOOL_API.ptr_gst_buffer_pool_new()));
}
/**
* This constructor is for internal use only.
* @param init initialization data.
*/
BufferPool(final Initializer init) {
super(init);
}
/**
* Configure the BufferPool with the given parameters.
*
* @param caps the {@link Caps} for the buffers
* @param size the size of each buffer, not including prefix and padding
* @param min_buffers the minimum amount of buffers to allocate
* @param max_buffers the maximum amount of buffers to allocate or 0 for unlimited
*/
public void setParams(Caps caps, int size, int min_buffers, int max_buffers) {
Structure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this);
GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers);
}
/**
* Query the {@link Caps} configured on the BufferPool.
*
* @return Caps configured on the BufferPool
*/
public Caps getCaps() {
Structure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this);
Pointer[] ptr = new Pointer[1];
GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_get_params(config, ptr, null, null, null);
return new Caps(Natives.initializer(ptr[0], false, true));
}
}
================================================
FILE: src/org/freedesktop/gstreamer/Bus.java
================================================
/*
* Copyright (c) 2025 Neil C Smith
* Copyright (C) 2014 Tom Greenwood
* See upstream documentation at
* https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html
*
* Since the application typically only wants to deal with delivery of these
* messages from one thread, the Bus will marshal the messages between different
* threads. This is important since the actual streaming of media is done in
* another thread than the application.
*
* It is also possible to get messages from the bus without any thread
* marshalling with the {@link #setSyncHandler} method. This makes it possible
* to react to a message in the same thread that posted the message on the bus.
* This should only be used if the application is able to deal with messages
* from different threads.
*
* Every {@link Pipeline} has one bus.
*
* Note that a Pipeline will set its bus into flushing state when changing from
* READY to NULL state.
*/
public class Bus extends GstObject {
public static final String GTYPE_NAME = "GstBus";
private static final Logger LOG = Logger.getLogger(Bus.class.getName());
private static final SyncCallback SYNC_CALLBACK = new SyncCallback();
private volatile BusSyncHandler syncHandler = null;
private final Object lock = new Object();
private final List
* Only one handler may be attached to the bus at any one time. An attached
* sync handler forces creation of {@link Message} objects for all messages
* on the bus, so the handler should be removed if no longer required.
*
* A single native sync handler is used at all times, with synchronous and
* asynchronous dispatch handled on the Java side, so the bindings do not
* inherit issues in clearing or replacing the sync handler with versions of
* GStreamer prior to 1.16.3.
*
* @param handler bus sync handler, or null to remove
*/
public void setSyncHandler(BusSyncHandler handler) {
syncHandler = handler;
}
/**
* Clear the synchronous handler.
*
* This is a convenience method equivalent to {@code setSyncHandler(null)}
*/
public void clearSyncHandler() {
setSyncHandler(null);
}
/**
* Get the current synchronous handler.
*
* @return current sync handler, or null
*/
public BusSyncHandler getSyncHandler() {
return syncHandler;
}
/**
* Connects to a signal.
*
* The signal name is deduced from the listenerClass name.
*
* @param listenerClass the class of the listener.
* @param listener the listener to associate with the {@code callback}
* @param callback The callback to call when the signal is emitted.
*/
private
* This differs to {@link GObject#connect} in that it hooks up Bus signals
* to the sync callback, not the generic GObject signal mechanism.
*
* @param
* We do this here from a sync callback, because the default gstbus dispatch
* uses the default main context to signal that there are messages waiting
* on the bus. Since that is used by the GTK L&F under swing, we never get
* those notifications, and the messages just queue up.
*
*/
private void dispatchMessage(GstBusPtr busPtr, GstMessagePtr msgPtr) {
messageProxies.forEach(p -> {
try {
p.busMessage(busPtr, msgPtr);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Exception thrown by bus message handler", t);
}
});
GSTMINIOBJECT_API.gst_mini_object_unref(msgPtr);
}
@Override
public void dispose() {
removeWatch();
super.dispose();
}
/**
* Adds the bus signal watch. This will reference the bus until the signal
* watch is removed and so will stop the Bus being GC'd and disposed.
*/
private void addWatch() {
synchronized (lock) {
if (!watchAdded) {
LOG.fine("Add watch");
GSTBUS_API.gst_bus_add_signal_watch(this);
watchAdded = true;
}
}
}
/**
* Removes the bus signal watch (which will remove the bus reference held by
* the signal watch).
*/
private void removeWatch() {
synchronized (lock) {
if (watchAdded) {
LOG.fine("Remove watch");
GSTBUS_API.gst_bus_remove_signal_watch(this);
watchAdded = false;
}
}
}
/**
* Signal emitted when end-of-stream is reached in a pipeline.
*
* The application will only receive this message in the PLAYING state and
* every time it sets a pipeline to PLAYING that is in the EOS state. The
* application can perform a flushing seek in the pipeline, which will undo
* the EOS state again.
*
* @see #connect(EOS)
* @see #disconnect(EOS)
*/
public static interface EOS {
/**
* Called when a {@link Pipeline} element posts a end-of-stream message.
*
* @param source the element which posted the message.
*/
public void endOfStream(GstObject source);
}
/**
* Signal emitted when an error occurs.
*
* When the application receives an error message it should stop playback of
* the pipeline and not assume that more data will be played.
*
* @see #connect(ERROR)
* @see #disconnect(ERROR)
*/
public static interface ERROR {
/**
* Called when a {@link Pipeline} element posts an error message.
*
* @param source the element which posted the message.
* @param code a numeric code representing the error.
* @param message a string representation of the error.
*/
public void errorMessage(GstObject source, int code, String message);
}
/**
* Signal emitted when a warning message is delivered.
*
* @see #connect(WARNING)
* @see #disconnect(WARNING)
*/
public static interface WARNING {
/**
* Called when a {@link Pipeline} element posts an warning message.
*
* @param source the element which posted the message.
* @param code a numeric code representing the warning.
* @param message a string representation of the warning.
*/
public void warningMessage(GstObject source, int code, String message);
}
/**
* Signal emitted when an informational message is delivered.
*
* @see #connect(INFO)
* @see #disconnect(INFO)
*/
public static interface INFO {
/**
* Called when a {@link Pipeline} element posts an informational
* message.
*
* @param source the element which posted the message.
* @param code a numeric code representing the informational message.
* @param message a string representation of the informational message.
*/
public void infoMessage(GstObject source, int code, String message);
}
/**
* Signal emitted when a new tag is identified on the stream.
*
* @see #connect(TAG)
* @see #disconnect(TAG)
*/
public static interface TAG {
/**
* Called when a {@link Pipeline} element finds media meta-data.
*
* @param source the element which posted the message.
* @param tagList a list of media meta-data.
*/
public void tagsFound(GstObject source, TagList tagList);
}
/**
* Signal emitted when a state change happens.
*
* @see #connect(STATE_CHANGED)
* @see #disconnect(STATE_CHANGED)
*/
public static interface STATE_CHANGED {
/**
* Called when a {@link Pipeline} element executes a {@link State}
* change.
*
* @param source the element which posted the message.
* @param old the old state that the element is changing from.
* @param current the new (current) state the element is changing to.
* @param pending the pending (target) state.
*/
public void stateChanged(GstObject source, State old, State current, State pending);
}
/**
* Signal emitted when the pipeline is buffering data.
*
* @see #connect(BUFFERING)
* @see #disconnect(BUFFERING)
*/
public static interface BUFFERING {
/**
* Called when a {@link Pipeline} element needs to buffer data before it
* can continue processing.
*
* {@code percent} is a value between 0 and 100. A value of 100 means
* that the buffering completed.
*
* When {@code percent} is less than 100 the application should PAUSE a
* PLAYING pipeline. When {@code percent} is 100, the application can
* set the pipeline (back) to PLAYING.
*
* The application must be prepared to receive BUFFERING messages in the
* PREROLLING state and may only set the pipeline to PLAYING after
* receiving a message with {@code percent} set to 100, which can happen
* after the pipeline completed prerolling.
*
* @param source the element which posted the message.
* @param percent the percentage of buffering that has completed.
*/
public void bufferingData(GstObject source, int percent);
}
/**
* Signal sent when a new duration message is posted by an element that know
* the duration of a stream in a specific format.
*
* This message is received by bins and is used to calculate the total
* duration of a pipeline.
*
* Elements may post a duration message with a duration of
* {@link ClockTime#NONE} to indicate that the duration has changed and the
* cached duration should be discarded. The new duration can then be
* retrieved via a query. The application can get the new duration with a
* duration query.
*
* @see #connect(DURATION)
* @see #disconnect(DURATION)
*/
public static interface DURATION_CHANGED {
/**
* Called when a new duration message is posted on the Bus.
*
* @param source the element which posted the message.
*/
public void durationChanged(GstObject source);
}
/**
* This message is posted by elements that start playback of a segment as a
* result of a segment seek.
*
* This message is not received by the application but is used for
* maintenance reasons in container elements.
*/
public static interface SEGMENT_START {
public void segmentStart(GstObject source, Format format, long position);
}
/**
* Signal emitted when the pipeline has completed playback of a segment.
*
* This message is posted by elements that finish playback of a segment as a
* result of a segment seek. This message is received by the application
* after all elements that posted a {@link SEGMENT_START} have posted
* segment-done.
*
* @see #connect(SEGMENT_DONE)
* @see #disconnect(SEGMENT_DONE)
*/
public static interface SEGMENT_DONE {
/**
* Called when a segment-done message has been posted.
*
* @param source the element which posted the message.
* @param format the format of the position being done.
* @param position the position of the segment being done.
*/
public void segmentDone(GstObject source, Format format, long position);
}
/**
* Signal emitted by elements when they complete an ASYNC state change.
*
* Applications will only receive this message from the top level pipeline.
*
* The signal handler will be called asynchronously from the thread that
* posted the message on the Bus.
*
* @see #connect(MESSAGE)
* @see #disconnect(MESSAGE)
*/
public static interface MESSAGE {
/**
* Called when a {@link Element} posts a {@link Message} on the Bus.
*
* @param bus the Bus the message was posted on.
* @param message the message that was posted.
*/
public void busMessage(Bus bus, Message message);
}
private static class MessageProxy
* Caps (capabilities) are lightweight objects describing media types. They are
* composed of an array of {@link Structure}.
*
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstCaps.html
*
* Caps are exposed on {@link PadTemplate} to describe all possible types a
* given pad can handle. They are also stored in the {@link Registry} along with
* a description of the {@link Element}.
*
* Caps are exposed on the element pads using the {@link Pad#getAllowedCaps() }
* method. This method describes the possible types that the pad can handle or
* produce at runtime.
*
* Caps are also attached to buffers to describe the content of the data pointed
* to by the buffer with {@link Sample#setCaps}. Caps attached to a
* {@link Buffer} allow for format negotiation upstream and downstream.
*
* A Caps can be constructed with the following code fragment:
*
*
* A Caps is fixed when it has no properties with ranges or lists. Use
* {@link #isFixed} to test for fixed caps. Only fixed caps can be set on a
* {@link Pad} or {@link Buffer}.
*
* Various methods exist to work with the media types such as subtracting or
* intersecting.
*
* @see Structure
*/
public class Caps extends MiniObject {
public static final String GTYPE_NAME = "GstCaps";
/**
* Creates a new Caps that is empty. That is, the returned Caps contains no
* media formats.
*
* @see #emptyCaps
*/
public Caps() {
this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_empty()));
}
/**
* Construct a new Caps from a string representation.
*
* @param caps The string representation of the caps.
* @see #fromString
*/
public Caps(String caps) {
this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps)));
}
/**
* Create a caps that is a copy of another caps.
*
* @param caps The caps to copy.
* @see #copy
*/
public Caps(Caps caps) {
this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_copy(caps)));
}
Caps(Initializer init) {
super(init);
}
/**
* Append the structures contained in caps to this caps object. The
* structures in caps are not copied -- they are transferred to this caps.
*
* If either caps is ANY, the resulting caps will be ANY.
*
* @param caps The Caps to append
*/
public void append(Caps caps) {
GSTCAPS_API.gst_caps_append(this, caps);
}
/**
* Append structure to this caps. The structure is not copied; this caps
* takes ownership, so do not use struct after calling this method.
*
* @param struct The structure to append.
*/
public void append(Structure struct) {
GSTCAPS_API.gst_caps_append_structure(this, struct);
}
/**
* Create a new Caps as a copy of the this caps.
*
* The new Caps will be a copy of this caps, with all the internal
* structures copied as well.
*
* @return The new Caps.
*/
public Caps copy() {
return GSTCAPS_API.gst_caps_copy(this);
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof Caps)) {
return false;
}
return other == this || isEqual((Caps) other);
}
/**
* Get a {@link Structure} contained in this caps.
*
* Finds the structure in @caps that has the index @index, and returns it.
*
* @param index The index of the structure to get.
* @return The Structure corresponding to index.
*/
public Structure getStructure(int index) {
/*
* WARNING: This function takes a const GstCaps *, but returns a
* non-const GstStructure *. This is for programming convenience --
* the caller should be aware that structures inside a constant
* #GstCaps should not be modified.
*/
// The above means we return a Structure proxy which does not own the pointer.
// gst_caps_get_structure is not marked as CallerOwnsReturn, so it should work
return GSTCAPS_API.gst_caps_get_structure(this, index);
}
/**
* Creates a new {@link Caps} that contains all the formats that are common
* to both this Caps and the other Caps.
*
* @param other The {@link Caps} to intersect with this one.
*
* @return The new {@link Caps}
*/
public Caps intersect(Caps other) {
return GSTCAPS_API.gst_caps_intersect(this, other);
}
/**
* Check if this caps is always compatible with another caps.
*
* A given Caps structure is always compatible with another if every media
* format that is in the first is also contained in the second. That is,
* this caps1 is a subset of other.
*
* @param other The caps to test against.
* @return true if other is always compatible with this caps.
*/
public boolean isAlwaysCompatible(Caps other) {
return GSTCAPS_API.gst_caps_is_always_compatible(this, other);
}
/**
* Determine if this caps represents any media format.
*
* @return true if this caps represents any format.
*/
public boolean isAny() {
return GSTCAPS_API.gst_caps_is_any(this);
}
/**
* Determine if this caps represents no media formats.
*
* @return true if this caps represents no formats.
*/
public boolean isEmpty() {
return GSTCAPS_API.gst_caps_is_empty(this);
}
/**
* Checks if the given caps represent the same set of caps.
*
* This function does not work reliably if optional properties for caps are
* included on one caps and omitted on the other.
*
* @param other The caps to compare this caps to.
* @return true if other caps equals this one.
*/
public boolean isEqual(Caps other) {
return GSTCAPS_API.gst_caps_is_equal(this, other);
}
/**
* Tests if two Caps are equal. This function only works on fixed Caps.
*
* @param other The other caps to test against.
* @return true if the other caps is equal to this one.
*/
public boolean isEqualFixed(Caps other) {
return GSTCAPS_API.gst_caps_is_equal_fixed(this, other);
}
/**
* Determine if this caps is fixed.
*
* Fixed Caps describe exactly one format, that is, they have exactly one
* structure, and each field in the structure describes a fixed type.
* Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
*
* @return true if this caps is fixed
*/
public boolean isFixed() {
return GSTCAPS_API.gst_caps_is_fixed(this);
}
/**
* Checks if all caps represented by this caps are also represented by
* superset.
*
* This function does not work reliably if optional properties for caps are
* included on one caps and omitted on the other.
*
* @param superset The potentially greater Caps
* @return true if this caps is a subset of superset
*/
public boolean isSubset(Caps superset) {
return GSTCAPS_API.gst_caps_is_subset(this, superset);
}
/**
*
* Returns a writable copy of this caps.
*
* This method will invalidate the native side of this caps object, so it
* should not be used after calling this method, and only the returned Caps
* object should be used.
*
*
* @return A writable version of this caps object.
*/
// @TODO should this take a ref ?
public Caps makeWritable() {
return GSTCAPS_API.gst_caps_make_writable(this);
}
/**
* Normalize the Caps.
*
* Creates a new {@link Caps} that represents the same set of formats as
* this Caps, but contains no lists. Each list is expanded into separate
* {@link Structure}s
*
* @return The new {@link Caps}
* @see Structure
*/
public Caps normalize() {
// this.ref(); // gst_caps_normalize copies "this" and drops one reference
Natives.ref(this);
return GSTCAPS_API.gst_caps_normalize(this);
}
/**
* Remove a structure from the caps. Removes the structure with the given
* index from the list of structures contained in this caps.
*
* @param index Index of the structure to remove.
*/
public void removeStructure(int index) {
GSTCAPS_API.gst_caps_remove_structure(this, index);
}
public void setInteger(String field, Integer value) {
GSTCAPS_API.gst_caps_set_simple(this, field, value, null);
}
/**
* Modifies this caps inplace into a representation that represents the same
* set of formats, but in a simpler form. Component structures that are
* identical are merged. Component structures that have values that can be
* merged are also merged.
*
* @return The new {@link Caps}
*/
public Caps simplify() {
// this.ref(); // gst_caps_simplify copies "this" and drops one reference
Natives.ref(this);
return GSTCAPS_API.gst_caps_simplify(this);
}
/**
* Get the number of structures contained in this caps.
*
* @return the number of structures that this caps contains
*/
public int size() {
return GSTCAPS_API.gst_caps_get_size(this);
}
/**
* Subtracts the subtrahend Caps from this Caps.
*
*
*
* Appends the structures contained in caps2 to caps1 if they are not yet
* expressed by caps1 . The structures in caps2 are not copied -- they are
* transferred to a writable copy of caps1 , and then caps2 is freed. If
* either caps is ANY, the resulting caps will be ANY.
*
* GStreamer uses a global clock to synchronize the plugins in a pipeline.
* Different clock implementations are possible by implementing this abstract
* base class.
*
* The {@link Clock} returns a monotonically increasing time with the method
* gst_clock_get_time(). Its accuracy and base time depend on the specific
* clock implementation but time is always expressed in nanoseconds. Since the
* baseline of the clock is undefined, the clock time returned is not
* meaningful in itself, what matters are the deltas between two clock times.
* The time returned by a clock is called the absolute time.
*
* The pipeline uses the clock to calculate the stream time. Usually all
* renderers synchronize to the global clock using the buffer timestamps, the
* newsegment events and the element's base time, see #GstPipeline.
*
* A clock implementation can support periodic and single shot clock
* notifications both synchronous and asynchronous.
*
* One first needs to create a {@link ClockID} for the periodic or single shot
* notification using {@link #newSingleShotID} or {@link #newPeriodicID}.
*
* To perform a blocking wait for the specific time of the {@link ClockID} use the
* gst_clock_id_wait(). To receive a callback when the specific time is reached
* in the clock use gst_clock_id_wait_async(). Both these calls can be
* interrupted with the gst_clock_id_unschedule() call. If the blocking wait is
* unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned.
*
* Periodic callbacks scheduled async will be repeatedly called automatically
* until it is unscheduled. To schedule a sync periodic callback,
* gst_clock_id_wait() should be called repeatedly.
*
* The async callbacks can happen from any thread, either provided by the core
* or from a streaming thread. The application should be prepared for this.
*
* A {@link ClockID} that has been unscheduled cannot be used again for any wait
* operation, a new ClockID should be created.
*
* It is possible to perform a blocking wait on the same ClockID from
* multiple threads. However, registering the same ClockID for multiple
* async notifications is not possible, the callback will only be called for
* the thread registering the entry last.
*
* These clock operations do not operate on the stream time, so the callbacks
* will also occur when not in {@link State#PLAYING} state as if the clock just keeps on
* running. Some clocks however do not progress when the element that provided
* the clock is not {@link State#PLAYING}.
*
* When a clock has the GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be
* slaved to another #GstClock with the gst_clock_set_master(). The clock will
* then automatically be synchronized to this master clock by repeatedly
* sampling the master clock and the slave clock and recalibrating the slave
* clock with {@link #setCalibration}. This feature is mostly useful for
* plugins that have an internal clock but must operate with another clock
* selected by the {@link Pipeline}. They can track the offset and rate difference
* of their internal clock relative to the master clock by using the
* gst_clock_get_calibration() function.
*
* The master/slave synchronisation can be tuned with the "timeout", "window-size"
* and "window-threshold" properties. The "timeout" property defines the interval
* to sample the master clock and run the calibration functions.
* "window-size" defines the number of samples to use when calibrating and
* "window-threshold" defines the minimum number of samples before the
* calibration is performed.
*/
public class Clock extends GstObject {
public static final String GTYPE_NAME = "GstClock";
@Deprecated // should be package private
public Clock(Initializer init) {
super(init);
}
/**
* Sets the accuracy of the clock.
*
* Some clocks have the possibility to operate with different accuracy at
* the expense of more resource usage. There is normally no need to change
* the default resolution of a clock. The resolution of a clock can only be
* changed if the clock has the GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
*
* @param resolution the new resolution of the clock.
* @return the new resolution of the clock.
*/
public long setResolution(long resolution) {
return GSTCLOCK_API.gst_clock_set_resolution(this, resolution);
}
/**
* Gets the accuracy of the clock. The accuracy of the clock is the granularity
* of the values returned by {@link #getTime}.
*
* @return the resolution of the clock in nanoseconds.
*/
public long getResolution() {
return GSTCLOCK_API.gst_clock_get_resolution(this);
}
/**
* Gets the current time of the given clock. The time is always
* monotonically increasing and adjusted according to the current
* offset and rate.
*
* Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
* giving wrong input.
* @return the time of the clock. Or {@link ClockTime#NONE} when
* given incorrect input.
*/
public long getTime() {
return GSTCLOCK_API.gst_clock_get_time(this);
}
/**
* Gets the current internal time of this clock. The time is returned
* unadjusted for the offset and the rate.
*
* Thread safe.
*
* @return the internal time of the clock. Or {@link ClockTime#NONE} when given wrong input.
*/
public long getInternalTime() {
return GSTCLOCK_API.gst_clock_get_internal_time(this);
}
/**
* Gets the master clock that this clock is slaved to or null when the clock is
* not slaved to any master clock.
*
* @return A master Clock or null when this clock is not slaved to a master
* clock.
*/
public Clock getMaster() {
return GSTCLOCK_API.gst_clock_get_master(this);
}
/**
* Set master as the master clock for this clock. This clock will be automatically
* calibrated so that {@link #getTime} reports the same time as the
* master clock.
*
* A clock provider that slaves its clock to a master can get the current
* calibration values with {@link #getCalibration}.
*
* master can be null in which case clock will not be slaved anymore. It will
* however keep reporting its time adjusted with the last configured rate
* and time offsets.
*
* @param master a master Clock
* @return true if the clock is capable of being slaved to a master clock.
* Trying to set a master on a clock without the CAN_SET_MASTER flag will make
* this function return false.
*/
public boolean setMaster(Clock master) {
return GSTCLOCK_API.gst_clock_set_master(this, master);
}
/**
* Gets the internal rate and reference time of clock. See {@link #setCalibration} for more information.
*
* internal, external, rate_num, and rate_denom can be left NULL if the caller is not interested in the values.
*
* Thread safe.
* @param internal a reference internal time
* @param external a reference external time
* @param rateNumerator the numerator of the rate of the clock relative to its internal time
* @param rateDenominator the denominator of the rate of the clock
*/
@Deprecated
public void getCalibration(long internal, long external, long rateNumerator, long rateDenominator) {
GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator);
}
/**
* Gets the internal rate and reference time of clock. See
* {@link #setCalibration} for more information.
*
* @return calibration
*/
public Calibration getCalibration() {
long[] internalPtr = new long[1];
long[] externalPtr = new long[1];
long[] rateNumPtr = new long[1];
long[] rateDenomPtr = new long[1];
GSTCLOCK_API.gst_clock_get_calibration(this, internalPtr,
externalPtr, rateNumPtr, rateDenomPtr);
return new Calibration(internalPtr[0], externalPtr[0],
rateNumPtr[0], rateDenomPtr[0]);
}
/**
* Adjusts the rate and time of this clock. A rate of 1/1 is the normal speed of
* the clock. Values bigger than 1/1 make the clock go faster.
*
* internal and external are calibration parameters that arrange that
* {@link #getTime} should have been external at internal time internal.
* This internal time should not be in the future; that is, it should be less
* than the value of {@link #getInternalTime} when this function is called.
*
* Subsequent calls to gst_clock_get_time() will return clock times computed as
* follows:
*
*
* This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
* tries to do the integer arithmetic as precisely as possible.
*
* Note that {@link #getTime} always returns increasing values so when you
* move the clock backwards, getTime() will report the previous value
* until the clock catches up.
*
* Thread safe.
* @param internal a reference internal time
* @param external a reference external time
* @param rateNumerator the numerator of the rate of the clock relative to its internal time
* @param rateDenominator the denominator of the rate of the clock
*/
public void setCalibration(long internal, long external, long rateNumerator, long rateDenominator) {
GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator);
}
/**
* Gets a {@link ClockID} from this clock to trigger a single shot
* notification at the requested time.
*
* Thread safe.
*
* @param time The requested time
* @return A {@link ClockID} that can be used to request the time notification.
*/
public ClockID newSingleShotID(long time) {
return GSTCLOCK_API.gst_clock_new_single_shot_id(this, time);
}
/**
* Gets an ID from this clock to trigger a periodic notification.
* The periodeic notifications will be start at time start_time and
* will then be fired with the given interval.
*
* Thread safe.
*
* @param startTime The requested start time.
* @param interval The requested interval.
* @return A {@link ClockID} that can be used to request the time notification.
*/
public ClockID newPeriodicID(long startTime, long interval) {
return GSTCLOCK_API.gst_clock_new_periodic_id(this, startTime, interval);
}
/**
* Data storage for clock calibration.
*/
public static final class Calibration {
private final long internal;
private final long external;
private final long rateNum;
private final long rateDenom;
private Calibration(long internal, long external, long rateNum, long rateDenom) {
this.internal = internal;
this.external = external;
this.rateNum = rateNum;
this.rateDenom = rateDenom;
}
/**
* The internal time.
*
* @return internal time
*/
public long internal() {
return internal;
}
/**
* The external time.
*
* @return external time
*/
public long external() {
return external;
}
/**
* The rate numerator.
*
* @return rate numerator
*/
public long rateNum() {
return rateNum;
}
/**
* The rate denominator.
*
* @return rate denominator
*/
public long rateDenom() {
return rateDenom;
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (int) (this.internal ^ (this.internal >>> 32));
hash = 59 * hash + (int) (this.external ^ (this.external >>> 32));
hash = 59 * hash + (int) (this.rateNum ^ (this.rateNum >>> 32));
hash = 59 * hash + (int) (this.rateDenom ^ (this.rateDenom >>> 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 Calibration other = (Calibration) obj;
if (this.internal != other.internal) {
return false;
}
if (this.external != other.external) {
return false;
}
if (this.rateNum != other.rateNum) {
return false;
}
if (this.rateDenom != other.rateDenom) {
return false;
}
return true;
}
@Override
public String toString() {
return "Calibration{" + "internal=" + internal + ", external=" + external
+ ", rateNum=" + rateNum + ", rateDenom=" + rateDenom + '}';
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/ClockID.java
================================================
/*
* Copyright (c) 2025 Neil C Smith
* Copyright (c) 2007 Wayne Meissner
*
* 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
* Thread safe.
*
* @return The time of this clock id.
*/
public long getTime() {
return GSTCLOCK_API.gst_clock_id_get_time(this);
}
/**
* Compares this ClockID to another.
*
* @param other The other ClockID to compare to
* @return negative value if
* {@code a < b; zero if a = b; positive value if a > b}
*/
@Override
public int compareTo(ClockID other) {
return GSTCLOCK_API.gst_clock_id_compare_func(this, other);
}
private static final class Handle extends RefCountedObject.Handle {
public Handle(GPointer ptr, boolean ownsHandle) {
super(ptr, ownsHandle);
}
@Override
protected void disposeNativeHandle(GPointer ptr) {
GSTCLOCK_API.gst_clock_id_unref(ptr);
}
@Override
protected void ref() {
GSTCLOCK_API.gst_clock_id_ref(getPointer());
}
@Override
protected void unref() {
GSTCLOCK_API.gst_clock_id_unref(getPointer());
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/ClockReturn.java
================================================
/*
* Copyright (C) 2019 Neil C Smith
* Copyright (C) 2008 Wayne Meissner
* Copyright (C) 1999,2000 Erik Walthinsen
* See upstream documentation at https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html
*
* Context is a container object used to store contexts like a device context, a
* display server connection and similar concepts that should be shared between
* multiple elements.
*
* Applications can set a context on a complete pipeline by using
* {@link Element#setContext(Context)}, which will then be propagated to all
* child elements. Elements can handle these in
* {@link Element#setContext(Context)} and merge them with the context
* information they already have.
*
* When an element needs a context it will do the following actions in this
* order until one step succeeds:
*
* Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously
* known context on the element that asks for it if possible. Otherwise the
* application should provide one if it can.
*
* Contexts can be persistent. A persistent context is kept in elements when
* they reach {@link State#NULL}, non-persistent ones will be removed. Also, a
* non-persistent context won't override a previous persistent context set to an
* element.
*/
public class Context extends MiniObject {
public static final String GTYPE_NAME = "GstContext";
private final Handle handle;
public Context(String contextType) {
this(contextType, true);
}
/**
* Create a new context.
*/
public Context(String context_type, boolean persistent) {
this(new Handle(GstContextAPI.GSTCONTEXT_API.gst_context_new(context_type, persistent), true), false);
}
Context(Handle handle, boolean needRef) {
super(handle, needRef);
this.handle = handle;
}
Context(Initializer init) {
this(new Handle(init.ptr.as(GstContextPtr.class, GstContextPtr::new), init.ownsHandle), init.needRef);
}
/**
* Access the structure of the context.
*
* @return The structure of this context. The structure is still owned by this
* context, which means that you should not modify it and not dispose of
* it.
*/
public Structure getStructure() {
return GstContextAPI.GSTCONTEXT_API.gst_context_get_structure(handle.getPointer());
}
/**
* Get a writable version of the structure.
*
* @return The structure of this context. The structure is still owned by the
* context, which means that you should not dispose of it.
*/
public Structure getWritableStructure() {
return GstContextAPI.GSTCONTEXT_API.gst_context_writable_structure(handle.getPointer());
}
/**
* Get the type of this context.
*
* @return The type of this context.
*/
public String getContextType() {
return GstContextAPI.GSTCONTEXT_API.gst_context_get_context_type(handle.getPointer());
}
protected static class Handle extends MiniObject.Handle {
public Handle(GstContextPtr ptr, boolean ownsHandle) {
super(ptr, ownsHandle);
}
@Override
protected GstContextPtr getPointer() {
return (GstContextPtr) super.getPointer();
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/ControlBinding.java
================================================
/*
* 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
* 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.GValue[] gValues = new GValueAPI.GValue[values.length];
boolean ok = GSTCONTROLBINDING_API.gst_control_binding_get_g_value_array(
handle.getPointer(),
timestamp,
interval,
gValues.length,
gValues);
if (ok) {
for (int i = 0; i < values.length; i++) {
values[i] = gValues[i].getValue();
}
}
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();
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/ControlSource.java
================================================
/*
* 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
* 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();
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/DateTime.java
================================================
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2016 Christophe Lafolet
* Copyright (c) 2010 Levente Farkas
*
* 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
* See upstream documentation at
* https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html
*
* Element is the abstract base class needed to construct an element that can be
* used in a GStreamer pipeline. Please refer to the plugin writers guide for
* more information on creating Element subclasses.
*
* The name of a Element can be retrieved with {@link #getName} and set with
* {@link #setName}.
*
* All elements have pads (of the type {@link Pad}). These pads link to pads on
* other elements. {@link Buffer}s flow between these linked pads. An Element
* has a list of {@link Pad} structures for all their input (or sink) and output
* (or source) pads. Core and plug-in writers can add and remove pads with
* {@link #addPad} and {@link #removePad}.
*
* Elements can be linked through their pads. If the link is straightforward,
* use the {@link #link} convenience function to link two elements, or
* {@link #linkMany} for more elements in a row.
*
* For finer control, use {@link #linkPads} and {@link #linkPadsFiltered} to
* specify the pads to link on each element by name.
*
* Each element has a state (see {@link State}). You can get and set the state
* of an element with {@link #getState} and {@link #setState}.
*
*/
public class Element extends GstObject {
public static final String GTYPE_NAME = "GstElement";
/**
* Creates a new instance of Element. This constructor is used internally.
*
* @param init internal initialization data.
*/
protected Element(Initializer init) {
super(init);
}
Element(Handle handle, boolean needRef) {
super(handle, needRef);
}
/**
* Creates an instance of the required element type, but does not wrap it in
* a proxy.
*
* @param factoryName The name of the factory to use to produce the Element
* @param elementName The name to assign to the created Element
* @return a raw element.
*/
protected static Initializer makeRawElement(String factoryName, String elementName) {
return Natives.initializer(ElementFactory.makeRawElement(factoryName, elementName));
}
/**
* Links this element to another element. The link must be from source to
* destination; the other direction will not be tried.
*
* The function looks for existing pads that aren't linked yet. It will
* request new pads if necessary. Such pads need to be released manually
* when unlinking. If multiple links are possible, only one is established.
*
* Make sure you have added your elements to a bin or pipeline with
* {@link Bin#add} or {@link Bin#addMany} before trying to link them.
*
* See {@link #linkPadsFiltered} if you need more control about which pads
* are selected for linking.
*
* @param dest The element containing the destination pad.
* @return true if the elements could be linked, false otherwise.
*/
public boolean link(Element dest) {
return GSTELEMENT_API.gst_element_link(this, dest);
}
/**
* Links this element to another element using the given caps as filtercaps.
* The link must be from source to destination; the other direction will not
* be tried.
*
* The function looks for existing pads that aren't linked yet. It will
* request new pads if necessary. Such pads need to be released manually
* when unlinking. If multiple links are possible, only one is established.
*
* Make sure you have added your elements to a bin or pipeline with
* {@link Bin#add} or {@link Bin#addMany} before trying to link them.
*
* See {@link #linkPadsFiltered} if you need more control about which pads
* are selected for linking.
*
* @param dest The element containing the destination pad.
* @param filter The {@link Caps} to filter the link, or Null for no filter.
* @return true if the elements could be linked, false otherwise.
*/
public boolean linkFiltered(Element dest, Caps filter) {
return GSTELEMENT_API.gst_element_link_filtered(this, dest, filter);
}
/**
* Unlinks all source pads of this source element with all sink pads of the
* sink element to which they are linked.
*
* If the link has been made using {@link #link}, it could have created an
* requestpad, which has to be released using
* gst_element_release_request_pad().
*
* @param dest The sink Element to unlink.
*/
public void unlink(Element dest) {
GSTELEMENT_API.gst_element_unlink(this, dest);
}
/**
* Tests if the Element is currently playing.
*
* @return true if the Element is currently playing
*/
public boolean isPlaying() {
return getState() == State.PLAYING;
}
/**
* Tells the Element to start playing the media stream. Equivalent to
* calling {@link #setState(org.freedesktop.gstreamer.State)} with
* {@link State#PLAYING}.
*
* @return the status of the element's state change.
*/
public StateChangeReturn play() {
return setState(State.PLAYING);
}
/**
* Tells the Element to set ready the media stream. Equivalent to calling
* {@link #setState(org.freedesktop.gstreamer.State)} with
* {@link State#READY}.
*
* @return the status of the element's state change.
*/
public StateChangeReturn ready() {
return setState(State.READY);
}
/**
* Tells the Element to pause playing the media stream. Equivalent to
* calling {@link #setState(org.freedesktop.gstreamer.State)} with
* {@link State#PAUSED}.
*
* @return the status of the element's state change.
*/
public StateChangeReturn pause() {
return setState(State.PAUSED);
}
/**
* Tells the Element to stop playing the media stream. Equivalent to calling
* {@link #setState(org.freedesktop.gstreamer.State)} with
* {@link State#NULL}.
*
* @return the status of the element's state change.
*/
public StateChangeReturn stop() {
return setState(State.NULL);
}
/**
* Sets the state of the element.
*
* This method will try to set the requested state by going through all the
* intermediary states.
*
* This function can return {@link StateChangeReturn#ASYNC}, in which case
* the element will perform the remainder of the state change asynchronously
* in another thread.
*
* An application can use {@link #getState} to wait for the completion of
* the state change or it can wait for a state change message on the bus.
*
* @param state the element's new {@link State}.
* @return the status of the element's state change.
*/
public StateChangeReturn setState(State state) {
return GSTELEMENT_API.gst_element_set_state(this, state);
}
/**
* Locks the state of an element, so state changes of the parent don't
* affect this element anymore.
*
* @param locked_state true to lock the element's {@link State}.
* @return true if the state was changed, false if bad parameters were given
* or the elements state-locking needed no change.
*/
public boolean setLockedState(boolean locked_state) {
return GSTELEMENT_API.gst_element_set_locked_state(this, locked_state);
}
/**
* Gets the state of the element.
*
* This method will wait until any async state change has completed.
*
* @return The {@link State} the Element is currently in.
*/
public State getState() {
return getState(-1);
}
/**
* Gets the state of the element.
*
* For elements that performed an ASYNC state change, as reported by
* {@link #setState(org.freedesktop.gstreamer.State)}, this function will
* block up to the specified timeout value for the state change to complete.
*
* @param timeout the amount of time to wait.
* @param units the units of the timeout.
* @return The {@link State} the Element is currently in.
*
*/
public State getState(long timeout, TimeUnit units) {
State[] state = new State[1];
GSTELEMENT_API.gst_element_get_state(this, state, null, units.toNanos(timeout));
return state[0];
}
/**
* Gets the state of the element.
*
* For elements that performed an ASYNC state change, as reported by
* {@link #setState(org.freedesktop.gstreamer.State)}, this function will
* block up to the specified timeout value for the state change to complete.
*
* @param timeout The amount of time in nanoseconds to wait.
* @return The {@link State} the Element is currently in.
*
*/
public State getState(long timeout) {
State[] state = new State[1];
GSTELEMENT_API.gst_element_get_state(this, state, null, timeout);
return state[0];
}
/**
* Gets the state of the element.
*
* For elements that performed an ASYNC state change, as reported by
* {@link #setState(org.freedesktop.gstreamer.State)}, this function will
* block up to the specified timeout value for the state change to complete.
*
* @param timeout The amount of time in nanoseconds to wait.
* @param states an array to store the states in. Must be of sufficient size
* to hold two elements.
*/
public void getState(long timeout, State[] states) {
State[] state = new State[1];
State[] pending = new State[1];
GSTELEMENT_API.gst_element_get_state(this, state, pending, timeout);
states[0] = state[0];
states[1] = pending[0];
}
/**
* Tries to change the state of the element to the same as its parent. If
* this function returns false, the state of element is undefined.
*
* @return true, if the element's state could be synced to the parent's
* state. MT safe.
*/
public boolean syncStateWithParent() {
return GSTELEMENT_API.gst_element_sync_state_with_parent(this);
}
/**
* Sets the {@link Caps} on this Element.
*
* @param caps the new Caps to set.
*/
public void setCaps(Caps caps) {
GOBJECT_API.g_object_set(this, "caps", caps);
}
/**
* Retrieves a pad from the element by name. This version only retrieves
* already-existing (i.e. 'static') pads.
*
* @param padname The name of the {@link Pad} to get.
* @return The requested {@link Pad} if found, otherwise null.
*/
public Pad getStaticPad(String padname) {
return GSTELEMENT_API.gst_element_get_static_pad(this, padname);
}
/**
* Retrieves a list of the element's pads.
*
* @return the List of {@link Pad}s.
*/
public List
* Pads are not automatically activated so elements should perform the
* needed steps to activate the pad in case this pad is added in the PAUSED
* or PLAYING state. See {@link Pad#setActive} for more information about
* activating pads.
*
* This function will emit the {@link PAD_ADDED} signal on the element.
*
* @param pad The {@link Pad} to add.
* @return true if the pad could be added. This function can fail when a pad
* with the same name already existed or the pad already had another parent.
*/
public boolean addPad(Pad pad) {
return GSTELEMENT_API.gst_element_add_pad(this, pad);
}
/**
* Retrieves a pad from the element by name. This version only retrieves
* request pads. The pad must be released with {@link #releaseRequestPad}.
*
* @param name the name of the request {@link Pad} to retrieve.
* @return the requested Pad if found, otherwise null. Release
* using {@link #releaseRequestPad} after usage.
*/
public Pad getRequestPad(String name) {
return GSTELEMENT_API.gst_element_get_request_pad(this, name);
}
/**
* Frees the previously requested pad obtained via {@link #getRequestPad}.
*
* @param pad the pad to release.
*/
public void releaseRequestPad(Pad pad) {
GSTELEMENT_API.gst_element_release_request_pad(this, pad);
}
/**
* Remove a {@link Pad} from the element.
*
* This method is used by plugin developers and should not be used by
* applications. Pads that were dynamically requested from elements with
* {@link #getRequestPad} should be released with the
* {@link #releaseRequestPad} function instead.
*
* Pads are not automatically deactivated so elements should perform the
* needed steps to deactivate the pad in case this pad is removed in the
* PAUSED or PLAYING state. See {@link Pad#setActive} for more information
* about deactivating pads.
*
* This function will emit the {@link PAD_REMOVED} signal on the element.
*
* @param pad The {@link Pad} to remove.
* @return true if the pad could be removed. Can return false if the pad
* does not belong to the provided element.
*/
public boolean removePad(Pad pad) {
return GSTELEMENT_API.gst_element_remove_pad(this, pad);
}
/**
* Retrieves the factory that was used to create this element.
*
* @return the {@link ElementFactory} used for creating this element.
*/
public ElementFactory getFactory() {
return GSTELEMENT_API.gst_element_get_factory(this);
}
/**
* Get the bus of the element. Note that only a {@link Pipeline} will
* provide a bus for the application.
*
* @return the element's {@link Bus}
*/
public Bus getBus() {
return GSTELEMENT_API.gst_element_get_bus(this);
}
/**
* Sends an event to an element.
*
* If the element doesn't implement an event handler, the event will be
* pushed on a random linked sink pad for upstream events or a random linked
* source pad for downstream events.
*
* @param ev The {@link Event} to send.
* @return true if the event was handled.
*/
public boolean sendEvent(Event ev) {
return GSTELEMENT_API.gst_element_send_event(this, ev);
}
/**
* Signal emitted when an {@link Pad} is added to this element.
*
* @see #connect(PAD_ADDED)
* @see #disconnect(PAD_ADDED)
*/
public static interface PAD_ADDED {
/**
* Called when a new {@link Pad} is added to an Element.
*
* @param element the element the pad was added to.
* @param pad the pad which was added.
*/
public void padAdded(Element element, Pad pad);
}
/**
* Signal emitted when an {@link Pad} is removed from this element.
*
* @see #connect(PAD_REMOVED)
* @see #disconnect(PAD_REMOVED)
*/
public static interface PAD_REMOVED {
/**
* Called when a new {@link Pad} is removed from an Element.
*
* @param element the element the pad was removed from.
* @param pad the pad which was removed.
*/
public void padRemoved(Element element, Pad pad);
}
/**
* Signal emitted when this element ceases to generated dynamic pads.
*
* @see #connect(NO_MORE_PADS)
* @see #disconnect(NO_MORE_PADS)
*/
public static interface NO_MORE_PADS {
/**
* Called when an element ceases to generated dynamic pads.
*
* @param element the element which posted this message.
*/
public void noMorePads(Element element);
}
/**
* Add a listener for the
* Make sure you have added your elements to a bin or pipeline with
* {@link Bin#add} or {@link Bin#addMany} before trying to link them.
*
* @param elements The list of elements to link together.
* @return true if all elements successfully linked.
*/
public static boolean linkMany(Element... elements) {
return GSTELEMENT_API.gst_element_link_many(elements);
}
/**
* Unlink a list of elements.
*
* @param elements The list of elements to link together
*
*/
public static void unlinkMany(Element... elements) {
GSTELEMENT_API.gst_element_unlink_many(elements);
}
/**
* Link together source and destination pads of two elements.
*
* A side effect is that if one of the pads has no parent, it becomes a
* child of the parent of the other element. If they have different parents,
* the link fails.
*
* @param src The element containing the source {@link Pad}.
* @param srcPadName The name of the source {@link Pad}. Can be null for any
* pad.
* @param dest The element containing the destination {@link Pad}.
* @param destPadName The name of the destination {@link Pad}. Can be null
* for any pad.
*
* @return true if the pads were successfully linked.
*/
public static boolean linkPads(Element src, String srcPadName, Element dest, String destPadName) {
return GSTELEMENT_API.gst_element_link_pads(src, srcPadName, dest, destPadName);
}
/**
* Link together source and destination pads of two elements. A side effect
* is that if one of the pads has no parent, it becomes a child of the
* parent of the other element. If they have different parents, the link
* fails. If caps is not null, makes sure that the caps of the link is a
* subset of caps.
*
* @param src The element containing the source {@link Pad}.
* @param srcPadName The name of the source {@link Pad}. Can be null for any
* pad.
* @param dest The element containing the destination {@link Pad}.
* @param destPadName The name of the destination {@link Pad}. Can be null
* for any pad.
* @param caps The {@link Caps} to use to filter the link.
*
* @return true if the pads were successfully linked.
*/
public static boolean linkPadsFiltered(Element src, String srcPadName,
Element dest, String destPadName, Caps caps) {
return GSTELEMENT_API.gst_element_link_pads_filtered(src, srcPadName, dest, destPadName, caps);
}
/**
* Unlink source and destination pads of two elements.
*
* @param src The element containing the source {@link Pad}.
* @param srcPadName The name of the source {@link Pad}.
* @param dest The element containing the destination {@link Pad}.
* @param destPadName The name of the destination {@link Pad}.
*
*/
public static void unlinkPads(Element src, String srcPadName, Element dest, String destPadName) {
GSTELEMENT_API.gst_element_unlink_pads(src, srcPadName, dest, destPadName);
}
/**
* Posts a {@link Message} on the element's {@link Bus}.
*
* @param message the Message to post.
* @return true if the message was posted, false if the
* element does not have a {@link Bus}.
*/
public boolean postMessage(Message message) {
return GSTELEMENT_API.gst_element_post_message(this, message);
}
/**
* Gets the currently configured clock of the element.
*
* @return the clock of the element.
*/
public Clock getClock() {
return GSTELEMENT_API.gst_element_get_clock(this);
}
/**
* Returns the base time of the element. The base time is the absolute time
* of the clock when this element was last put to PLAYING. Subtracting the
* base time from the clock time gives the stream time of the element.
*
* @return the base time of the element
*/
public long getBaseTime() {
return GSTELEMENT_API.gst_element_get_base_time(this);
}
/**
* Set the base time of an element.
*
* @param time the base time to set
* @see #getBaseTime()
*/
public void setBaseTime(long time) {
GSTELEMENT_API.gst_element_set_base_time(this, time);
}
/**
* Returns the start time of this element.
*
* The start time is the running time of the clock when this element was
* last put to {@link State#PAUSED}. Usually the start_time is managed by a
* toplevel element such as {@link Pipeline}.
*
* MT safe.
*
* @return the start time of this element.
*/
public long getStartTime() {
return GSTELEMENT_API.gst_element_get_start_time(this);
}
/**
* Set the start time of an element. The start time of the element is the
* running time of the element when it last went to the {@link State#PAUSED}
* state. In {@link State#READY} or after a flushing seek, it is set to 0.
*
* Toplevel elements like GstPipeline will manage the start_time and
* base_time on its children. Setting the start_time to
* {@link ClockTime#NONE} on such a toplevel element will disable the
* distribution of the base_time to the children and can be useful if the
* application manages the base_time itself, for example if you want to
* synchronize capture from multiple pipelines, and you can also ensure that
* the pipelines have the same clock.
*
* MT safe.
*
* @param time the start time to set
* @see #getStartTime()
*/
public void setStartTime(long time) {
GSTELEMENT_API.gst_element_set_start_time(this, time);
}
/**
* Performs a query on the element.
*
* For elements that don't implement a query handler, this function forwards
* the query to a random srcpad or to the peer of a random linked sinkpad of
* this element.
*
* Please note that some queries might need a running pipeline to work.
*
* @param query the Query to perform
* @return true if the query could be performed
*/
public boolean query(Query query) {
return GSTELEMENT_API.gst_element_query(this, query);
}
/**
* Sets the context of the element.
*
* @param context the Context to set.
*/
public void setContext(Context context) {
GstContextPtr gstContextPtr = Natives.getPointer(context).as(GstContextPtr.class, GstContextPtr::new);
GSTELEMENT_API.gst_element_set_context(this, gstContextPtr);
}
/**
* Gets the context with the context_type set on the element or NULL.
*
* @param context_type
* @return a context or NULL
*/
public Context getContext(String context_type) {
GstContextPtr gstContextPtr = GSTELEMENT_API.gst_element_get_context(this, context_type);
return gstContextPtr != null ? Natives.callerOwnsReturn(gstContextPtr, Context.class) : null;
}
/**
* Queries an element (usually top-level pipeline or playbin element) for
* the total stream duration in nanoseconds. This query will only work once
* the pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The
* application will receive an ASYNC_DONE message on the pipeline bus when
* that is the case.
*
* If the duration changes for some reason, you will get a DURATION_CHANGED
* message on the pipeline bus, in which case you should re-query the
* duration using this function.
*
* @param format the {@code Format} to return the duration in
* @return the total duration of the current media stream, or -1 if the
* query failed
*/
public long queryDuration(Format format) {
long[] dur = {0};
return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L;
}
/**
* Queries an element (usually top-level pipeline or playbin element) for
* the stream position in nanoseconds. This will be a value between 0 and
* the stream duration (if the stream duration is known). This query will
* usually only work once the pipeline is prerolled (i.e. reached PAUSED or
* PLAYING state). The application will receive an ASYNC_DONE message on the
* pipeline bus when that is the case.
*
* @param format The {@link Format} to return the position in
* @return the current position or -1 if the query failed.
*/
public long queryPosition(Format format) {
long[] pos = {0};
return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L;
}
/**
* Sends a seek event to an element. See {@link SeekEvent} for the details
* of the parameters. The seek event is sent to the element using the native
* equivalent of {@link #sendEvent(org.freedesktop.gstreamer.event.Event)}.
*
* @param rate the new playback rate
* @param format the format of the seek values
* @param seekFlags the seek flags
* @param startType the type and flags for the new start position
* @param start the value of the new start position
* @param stopType the type and flags for the new stop position
* @param stop the value of the new stop position
* @return true if seek operation succeeded. Flushing seeks will trigger a
* preroll, which will emit an ASYNC_DONE message
*/
public boolean seek(double rate, Format format, Set
* In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
* guaranteed to return TRUE on a seekable media type or FALSE when the
* media type is certainly not seekable (such as a live stream).
*
* Some elements allow for seeking in the READY state, in this case they
* will store the seek event and execute it when they are put to PAUSED. If
* the element supports seek in READY, it will always return TRUE when it
* receives the event in the READY state.
*
* @param format a {@link Format} to seek in, such as {@link Format#TIME}
* @param seekFlags seek options; playback applications will usually want to
* use {@link SeekFlags#FLUSH} and {@link SeekFlags#KEY_UNIT} here
* @param seekPosition position to seek to (relative to the start); if you
* are doing a seek in format TIME this value is in nanoseconds
* @return true if seek operation succeeded. Flushing seeks will trigger a
* preroll, which will emit an ASYNC_DONE message
*/
public boolean seekSimple(Format format, Set
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElementFactory.html
*
* Use the {@link #find} and {@link #create} methods to create element instances
* or use {@link #make} as a convenient shortcut.
*
*/
public class ElementFactory extends PluginFeature {
public static final String GTYPE_NAME = "GstElementFactory";
private static final Level DEBUG = Level.FINE;
private static final Logger LOG = Logger.getLogger(ElementFactory.class.getName());
/**
* Creates a new instance of ElementFactory
*
* @param init internal initialization data.
*/
ElementFactory(Initializer init) {
super(init);
if (LOG.isLoggable(Level.FINER)) {
LOG.entering("ElementFactory", "
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html#GstFlowReturn
*
*/
public enum FlowReturn implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstFormat.html#GstFormat
*
*/
// @TODO this won't handle custom registered formats - do we need to?
public enum Format implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstGhostPad.html
*
* GhostPads are useful when organizing pipelines with {@link Bin} like
* elements. The idea here is to create hierarchical element graphs. The bin
* element contains a sub-graph. Now one would like to treat the bin-element
* like any other {@link Element}. This is where GhostPads come into play. A
* GhostPad acts as a proxy for another pad. Thus the bin can have sink and
* source ghost-pads that are associated with sink and source pads of the child
* elements.
*
* If the target pad is known at creation time, {@link #GhostPad(String, Pad)}
* is the function to use to get a ghost-pad. Otherwise one can use
* {@link #GhostPad(String, PadDirection)} to create the ghost-pad and use
* {@link #setTarget} to establish the association later on.
*
* Note that GhostPads add overhead to the data processing of a pipeline.
*
* @see Pad
*/
public class GhostPad extends Pad {
public static final String GTYPE_NAME = "GstGhostPad";
/**
* Creates a new instance of GhostPad
*/
GhostPad(Initializer init) {
super(init);
}
/**
* Create a new ghostpad with target as the target. The direction will be
* taken from the target pad. The target pad must be unlinked.
*
* @param name The name of the new pad, or null to assign a default name.
* @param target The {@link Pad} to ghost.
*/
public GhostPad(String name, Pad target) {
this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new(name, target)));
}
/**
* Create a new ghostpad with target as the target. The direction will be
* taken from the target pad. The template used on the ghostpad will be
* template.
*
* @param name The name of the new pad, or null to assign a default name.
* @param target The {@link Pad} to ghost.
* @param template The {@link PadTemplate} to use on the ghostpad.
*/
public GhostPad(String name, Pad target, PadTemplate template) {
this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_from_template(name, target, template)));
}
/**
* Create a new ghostpad without a target with the given direction. A target
* can be set on the ghostpad later with the {@link #setTarget} method.
*
* The created ghostpad will not have a padtemplate.
*
* @param name The name of the new pad, or null to assign a default name.
* @param direction The direction of the ghostpad.
*/
public GhostPad(String name, PadDirection direction) {
this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target(name, direction.ordinal())));
}
/**
* Create a new ghostpad based on template, without setting a target. The
* direction will be taken from the template.
*
* @param name The name of the new pad, or null to assign a default name.
* @param template The {@link PadTemplate} to use on the ghostpad.
*/
public GhostPad(String name, PadTemplate template) {
this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target_from_template(name, template)));
}
/**
* Get the target pad of this ghostpad.
*
* @return the target {@link Pad}, can be null if the ghostpad has no target
* set
*/
public Pad getTarget() {
return GSTGHOSTPAD_API.gst_ghost_pad_get_target(this);
}
/**
* Set the new target of the ghostpad. Any existing target is unlinked and
* links to the new target are established.
*
* @param pad The new pad target.
* @return true if the new target could be set. This function can return
* false when the internal pads could not be linked.
*/
public boolean setTarget(Pad pad) {
return GSTGHOSTPAD_API.gst_ghost_pad_set_target(this, pad);
}
}
================================================
FILE: src/org/freedesktop/gstreamer/Gst.java
================================================
/*
* Copyright (c) 2025 Neil C Smith
* Copyright (c) 2018 Antonio Morales
* Copyright (c) 2007 Wayne Meissner
*
* 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
* Applications might want to disable this behaviour with the
* {@link #setSegTrap(boolean) } function. This is typically done if the
* application wants to install its own handler without GStreamer
* interfering.
*
* @return Segmentation Trap status.
*/
public static boolean isSegTrapEnabled() {
return GST_API.gst_segtrap_is_enabled();
}
/**
* Applications might want to disable/enable the SIGSEGV handling of the
* GStreamer core. See {@link #isSegTrapEnabled() } for more information.
*
* @param enabled
*/
public static void setSegTrap(boolean enabled) {
GST_API.gst_segtrap_set_enabled(enabled);
}
/**
* Test whether the GStreamer library already initialized.
*
* @return true if the GStreamer library already initialized.
*/
public static synchronized final boolean isInitialized() {
return INIT_COUNT.get() > 0;
}
/**
* Gets the common {@link ScheduledExecutorService} used to execute
* background tasks and schedule timeouts.
*
* @return an executor that can be used for background tasks.
*/
public static ScheduledExecutorService getExecutor() {
return executorService;
}
/**
* Signals the thread that called {@link #init} to return.
*/
public static void quit() {
quit.countDown();
}
/**
* Create a new pipeline based on command line syntax.
*
* Please note that you might get a return value that is not NULL even
* though the error is set. In this case there was a recoverable parsing
* error and you can try to play the pipeline.
*
* @param pipelineDescription the command line describing the pipeline
* @param errors a list that any errors will be added to
* @return a new element on success. If more than one top-level element is
* specified by the pipeline_description , all elements are put into a
* Pipeline, which then is returned.
* @throws GstException if the pipeline / element could not be created
*/
public static Element parseLaunch(String pipelineDescription, List
* For most gui programs, this is of little use. However, it can be a
* convenient way of keeping the main thread alive whilst gstreamer
* processing on other threads continues.
*/
public static void main() {
try {
CountDownLatch latch = quit;
if (latch != null) {
latch.await();
}
} catch (InterruptedException ex) {
} finally {
quit = new CountDownLatch(1);
}
}
/**
* Schedules a task for execution on the gstreamer background
* {@link java.util.concurrent.Executor}.
*
* @param task the task to execute.
*/
public static void invokeLater(final Runnable task) {
getExecutor().execute(task);
}
/**
* Gets the current main context used (if any).
*
* @return a main context.
*/
// @TODO leaking lowlevel
public static GMainContext getMainContext() {
return mainContext;
}
/**
* Initializes the GStreamer library.
*
* This is a shortcut if no arguments are to be passed to gstreamer.
*
* This is equivalent to calling
* {@link #init(org.freedesktop.gstreamer.Version) } with
* {@link Version#BASELINE}, currently GStreamer 1.8. If you require
* features from a later version of GStreamer you should specify the
* required version.
*
* @throws org.freedesktop.gstreamer.GstException
*/
public static final void init() throws GstException {
init(Version.BASELINE, "gst1-java-core");
}
/**
* Initializes the GStreamer library.
*
* This is a shortcut if no arguments are to be passed to gstreamer.
*
* @param requiredVersion
* @throws org.freedesktop.gstreamer.GstException
*/
public static final void init(Version requiredVersion) throws GstException {
init(requiredVersion, "gst1-java-core");
}
/**
* Initializes the GStreamer library.
*
* This sets up internal path lists, registers built-in elements, and loads
* standard plugins.
*
* This is equivalent to calling
* {@link #init(org.freedesktop.gstreamer.Version, java.lang.String, java.lang.String...) }
* with {@link Version#BASELINE}, currently GStreamer 1.8. If you
* require features from a later version of GStreamer you should specify the
* required version.
*
* @param progname the java program name.
* @param args the java argument list.
* @return the list of arguments with any gstreamer specific options
* stripped out.
* @throws org.freedesktop.gstreamer.GstException
*/
public static synchronized final String[] init(String progname, String... args) throws GstException {
return init(Version.BASELINE, progname, args);
}
/**
* Initializes the GStreamer library.
*
* This sets up internal path lists, registers built-in elements, and loads
* standard plugins.
*
* @param requestedVersion the minimum requested GStreamer version.
* @param progname the java program name.
* @param args the java argument list.
* @return the list of arguments with any gstreamer specific options
* stripped out.
* @throws org.freedesktop.gstreamer.GstException
*/
public static synchronized final String[] init(Version requestedVersion,
String progname, String... args) throws GstException {
if (CHECK_VERSIONS) {
Version availableVersion = getVersion();
if (requestedVersion.getMajor() != 1 || availableVersion.getMajor() != 1) {
throw new GstException("gst1-java-core only supports GStreamer 1.x");
}
if (requestedVersion.getMinor() < 8) {
requestedVersion = new Version(1, 8);
}
if (!availableVersion.checkSatisfies(requestedVersion)) {
throw new GstException(String.format(
"The requested version of GStreamer is not available\nRequested : %s\nAvailable : %s\n",
requestedVersion, availableVersion));
}
}
//
// Only do real init the first time through
//
if (INIT_COUNT.getAndIncrement() > 0) {
if (CHECK_VERSIONS) {
if (requestedVersion.getMinor() > minorVersion) {
minorVersion = (int) requestedVersion.getMinor();
}
}
return args;
}
NativeArgs argv = new NativeArgs(progname, args);
Pointer[] error = {null};
if (!GST_API.gst_init_check(argv.argcRef, argv.argvRef, error)) {
INIT_COUNT.decrementAndGet();
throw new GstException(extractError(error[0]));
}
LOG.fine("after gst_init, argc=" + argv.argcRef.getValue());
Version runningVersion = getVersion();
if (runningVersion.getMajor() != 1) {
LOG.warning("gst1-java-core only supports GStreamer 1.x");
}
if (useDefaultContext) {
mainContext = GMainContext.getDefaultContext();
executorService = new MainContextExecutorService(mainContext);
} else {
mainContext = new GMainContext();
executorService = Executors.newSingleThreadScheduledExecutor(threadFactory);
}
quit = new CountDownLatch(1);
loadAllClasses();
if (CHECK_VERSIONS) {
minorVersion = requestedVersion.getMinor();
}
return argv.toStringArray();
}
/**
* Clean up any resources created by GStreamer in
* {@link #init(org.freedesktop.gstreamer.Version)}.
*
* It is normally not needed to call this function in a normal
* application as the resources will automatically be freed when the program
* terminates. This function is therefore mostly used by testsuites and
* other memory profiling tools.
*
* After this call GStreamer (including this method) should not be used
* anymore.
*/
public static synchronized final void deinit() {
//
// Only perform real shutdown if called as many times as Gst.init() is
//
if (INIT_COUNT.decrementAndGet() > 0) {
return;
}
// Perform any cleanup tasks
for (Object task : shutdownTasks.toArray()) {
((Runnable) task).run();
}
// Stop any more tasks/timers from being scheduled
executorService.shutdown();
// Wake up the run thread.
quit();
// Wait for tasks to complete.
try {
if (!executorService.awaitTermination(100, TimeUnit.MILLISECONDS)) {
// Force-kill everything
executorService.shutdownNow();
}
} catch (InterruptedException ex) {
}
mainContext = null;
System.gc(); // Make sure any dangling objects are unreffed before calling deinit().
GST_API.gst_deinit();
}
/**
* Adds a task to be called when {@link Gst#deinit} is called.
*
* This is used internally, and is not recommended for other uses.
*
* @param task the task to execute.
*/
static void addStaticShutdownTask(Runnable task) {
shutdownTasks.add(task);
}
/**
* Instructs gstreamer-java to use the default main context.
*
* This may be useful if integration with the GTK main loop is desirable, as
* all {@link Bus} signals and timers will be executed in the context of the
* GTK main loop.
*
* For the majority of programs though, it is better to wrap the individual
* listeners in a proxy which executes the listener in the appropriate
* context.
*
* @param useDefault if true, use the default glib main context.
*/
public static void setUseDefaultContext(boolean useDefault) {
useDefaultContext = useDefault;
}
/**
* Checks that the version of GStreamer requested in init() satisfies the
* given version or throws an exception.
*
* @param major major version, only 1 is supported
* @param minor minor version required
* @throws GstException if the requested version support was not requested
*/
public static void checkVersion(int major, int minor) {
if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) {
throw new GstException("Not supported by requested GStreamer version");
}
}
/**
* Tests that the version of GStreamer requested in init() satisfies the
* given version.
*
* @param major major version, only 1 is supported
* @param minor minor version required
* @return boolean whether the version requirement can be satisfied
*/
public static boolean testVersion(int major, int minor) {
if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) {
return false;
}
return true;
}
// Make the gstreamer executor threads daemon, so they don't stop the main
// program from exiting
private static final ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable task) {
final String name = "gstreamer service thread " + counter.incrementAndGet();
Thread t = new Thread(task, name);
t.setDaemon(true);
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
};
private static synchronized void loadAllClasses() {
Stream.of(new GLib.Types(),
new Types(),
new Event.Types(),
new Message.Types(),
new Query.Types(),
new Controllers(),
new Elements(),
new WebRTC.Types(),
new Video.Types())
.flatMap(NativeObject.TypeProvider::types)
.forEachOrdered(GstTypes::register);
if (!DISABLE_EXTERNAL) {
try {
ServiceLoader
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstObject.html
*
* GstObject provides a root for the object hierarchy tree filed in by the
* GStreamer library. It is currently a thin wrapper on top of {@link GObject}.
* It is an abstract class that is not very usable on its own.
*
*/
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
*
* @param init Initialization data
*/
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;
}
/**
* Set the value of a GstObject property from a String representation.
*
* The data value is deserialized using
* The data value is serialized using
* 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());
}
// protected static Initializer initializer(Pointer ptr) {
// return initializer(ptr, true, true);
// }
//
// 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) {
super(ptr, ownsHandle);
}
@Override
protected void ref() {
GSTOBJECT_API.gst_object_ref(getPointer());
}
@Override
protected void sink() {
GSTOBJECT_API.gst_object_ref_sink(getPointer());
}
@Override
protected void unref() {
GSTOBJECT_API.gst_object_unref(getPointer());
}
@Override
protected GstObjectPtr getPointer() {
return (GstObjectPtr) super.getPointer();
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/Meta.java
================================================
/*
* Copyright (c) 2020 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
* See upstream documentation at
* https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html
*
*/
public class Meta extends NativeObject {
/**
* Create Meta from Initializer.
*
* @param init initializer.
*/
protected Meta(Initializer init) {
this(new Handle(init.ptr.as(GstMetaPtr.class, GstMetaPtr::new),
init.ownsHandle));
}
/**
* Create Meta from Handle.
*
* @param handle native object handle.
*/
protected Meta(Handle handle) {
super(handle);
}
@Override
public String toString() {
GstMetaPtr pointer = (GstMetaPtr)this.getPointer();
return "[meta : gType=" + pointer.getGType() + "]";
}
/**
* NativeObject.Handle implementation.
*/
protected static class Handle extends NativeObject.Handle {
/**
* Create Handle.
*
* @param ptr pointer to underlying native GstMeta.
* @param ownsHandle
*/
public Handle(GstMetaPtr ptr, boolean ownsHandle) {
super(ptr, ownsHandle);
}
@Override
protected void disposeNativeHandle(GPointer ptr) {
}
}
/**
* API for Meta subclass. Used for querying from Buffer.
*
* The relevant API will usually be available as a public static final field
* on the implementation class.
*
* The API type reflects two distinct types (api and implementation) used in
* the underlying GStreamer GstMetaInfo.
*
* See upstream documentation at
* https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaInfo
*
*
* @param
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstMiniObject.html
*
* MiniObject is a simple structure that can be used to implement refcounted
* types.
*/
public abstract class MiniObject extends RefCountedObject {
/**
* Creates a new instance of MiniObject
*/
protected MiniObject(Initializer init) {
this(new Handle(init.ptr.as(GstMiniObjectPtr.class, GstMiniObjectPtr::new),
init.ownsHandle), init.needRef);
}
protected MiniObject(Handle handle, boolean needRef) {
super(handle, needRef);
}
/**
* If mini_object has the LOCKABLE flag set, check if the current EXCLUSIVE
* lock on object is the only one, this means that changes to the object
* will not be visible to any other object.
*
*
*
*
* The result is cast to subclass.
*
* @return a writable version (possibly a duplicate) of this MiniObject.
*/
protected
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html
*
* An {@link Element} is linked to other elements via "pads", which are extremely
* light-weight generic link points. After two pads are retrieved from an
* element with {@link Element#getPad}, the pads can be link with {@link #link}.
* (For quick links, you can also use {@link Element#link}, which will make the
* obvious link for you if it's straightforward.)
*
* Pads are typically created from a {@link PadTemplate} with
* {@link #Pad(PadTemplate, String)}.
*
* Pads have {@link Caps} attached to it to describe the media type they are
* capable of dealing with. {@link #queryCaps} and {@link #setCaps} are used to
* manipulate the caps of the pads. Pads created from a pad template cannot set
* capabilities that are incompatible with the pad template capabilities.
*
* Pads without pad templates can be created with gst_pad_new(), which takes a
* direction and a name as an argument. If the name is NULL, then a guaranteed
* unique name will be assigned to it.
*
* {@link #getParentElement} will retrieve the Element that owns the pad.
*
* An Element creating a pad will typically use the various
* gst_pad_set_*_function() calls to register callbacks for various events on
* the pads.
*
* GstElements will use gst_pad_push() and gst_pad_pull_range() to push out or
* pull in a buffer.
*
* To send an Event on a pad, use {@link #sendEvent} and {@link #pushEvent}.
*
* @see PadTemplate
* @see Element
* @see Event
*/
public class Pad extends GstObject {
public static final String GTYPE_NAME = "GstPad";
private static final int EVENT_HAS_INFO_MASK = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
private final Handle handle;
/**
* Creates a new instance of Pad
*/
Pad(Initializer init) {
this(new Handle(init.ptr.as(GstPadPtr.class, GstPadPtr::new), init.ownsHandle), init.needRef);
}
private Pad(Handle handle, boolean needRef) {
super(handle, needRef);
this.handle = handle;
}
/**
* Creates a new pad with the given name in the given direction. If name is
* null, a guaranteed unique name (across all pads) will be assigned.
*
* @param name The name of the new pad.
* @param direction The direction of the new pad.
*/
public Pad(String name, PadDirection direction) {
this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new(name, direction), false));
}
/**
* Creates a new pad with the given name from the given template.
*
* If name is null, a guaranteed unique name (across all pads) will be
* assigned.
*
* @param template The pad template to use.
* @param name The name of the new pad.
*/
public Pad(PadTemplate template, String name) {
this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new_from_template(template, name), false));
}
/**
* Gets the capabilities this pad can produce or consume. Note that this
* method doesn't necessarily return the caps set by sending a
* gst_event_new_caps() - use {@link #getCurrentCaps() } for that instead.
* queryCaps returns all possible caps a pad can operate with,
* using the pad's CAPS query function, If the query fails, this function
* will return filter, if not NULL, otherwise ANY.
*
* When called on sinkpads filter contains the caps that upstream could
* produce in the order preferred by upstream. When called on srcpads filter
* contains the caps accepted by downstream in the preferred order. filter
* might be NULL but if it is not NULL the returned caps will be a subset of
* filter .
*
* Note that this function does not return writable Caps.
*
* @param filter suggested Caps or null
* @return a newly allocated copy of the {@link Caps} of this pad.
*/
public Caps queryCaps(Caps filter) {
return GSTPAD_API.gst_pad_query_caps(this, filter);
}
/**
* Gets the capabilities of the allowed media types that can flow through
* this pad and its peer.
*
* The allowed capabilities is calculated as the intersection of the results
* of calling {@link #queryCaps} on this pad and its peer.
*
* MT safe.
*
* @return The allowed {@link Caps} of the pad link, or null if this pad has
* no peer.
*/
public Caps getAllowedCaps() {
return GSTPAD_API.gst_pad_get_allowed_caps(this);
}
/**
* Gets the capabilities currently configured on pad with the last
* GST_EVENT_CAPS event.
*
* @return the negotiated #GstCaps or null if this pad has
* no current caps
*
*/
public Caps getCurrentCaps() {
return GSTPAD_API.gst_pad_get_current_caps(this);
}
/**
* Get the peer of this pad.
*
* MT safe.
*
* @return The peer Pad of this Pad.
*/
public Pad getPeer() {
return GSTPAD_API.gst_pad_get_peer(this);
}
/**
* Get the capabilities of the peer connected to this pad.
*
* When called on srcpads filter contains the caps that upstream could
* produce in the order preferred by upstream. When called on sinkpads
* filter contains the caps accepted by downstream in the preferred order.
* filter might be NULL but if it is not NULL the returned caps will be a
* subset of filter .
*
* @param filter Caps to filter by, or null
* @return the {@link Caps} of the peer pad, or null if there is no peer
* pad.
*/
public Caps peerQueryCaps(Caps filter) {
return GSTPAD_API.gst_pad_peer_query_caps(this, filter);
}
/**
* Check if the pad accepts the given caps.
*
* @param caps a {@link Caps} to check on the pad.
* @return true if the pad can accept the caps.
*/
public boolean queryAcceptCaps(Caps caps) {
return GSTPAD_API.gst_pad_query_accept_caps(this, caps);
}
/**
* Check if the peer of this pad accepts the caps. If this pad has no peer,
* this method returns true.
*
* @param caps {@link Caps} to check on the pad
* @return true if the peer pad can accept the caps or this pad no peer.
*/
public boolean peerQueryAcceptCaps(Caps caps) {
return GSTPAD_API.gst_pad_peer_query_accept_caps(this, caps);
}
/**
* Links this source pad and a sink pad.
*
* MT Safe.
*
* @param sink the sink Pad to link.
* @throws PadLinkException if pads cannot be linked.
*/
public void link(Pad sink) throws PadLinkException {
PadLinkReturn result = GSTPAD_API.gst_pad_link(this, sink);
if (result != PadLinkReturn.OK) {
throw new PadLinkException(result);
}
}
/**
*
* Unlinks the source pad from the sink pad. Will emit the "unlinked" signal
* on both pads.
*
* MT safe.
*
* @param pad the sink Pad to unlink.
* @return true if the pads were unlinked. This function returns false if
* the pads were not linked together.
*/
public boolean unlink(Pad pad) {
return GSTPAD_API.gst_pad_unlink(this, pad);
}
/**
* Check if this pad is linked to another pad or not.
*
* @return true if the pad is linked, else false.
*/
public boolean isLinked() {
return GSTPAD_API.gst_pad_is_linked(this);
}
/**
* Get the direction of the pad. The direction of the pad is decided at
* construction time so this function does not take the LOCK.
*
* @return The {@link PadDirection} of the pad.
*/
public PadDirection getDirection() {
return GSTPAD_API.gst_pad_get_direction(this);
}
/**
* Get the parent of this pad, cast to an {@link Element}. If this pad has no
* parent or its parent is not an element, returns null.
*
* @return The parent of the pad.
*/
public Element getParentElement() {
return GSTPAD_API.gst_pad_get_parent_element(this);
}
/**
* Activates or deactivates the given pad. Normally called from within core
* state change functions.
*
* If active is true, makes sure the pad is active. If it is already active,
* either in push or pull mode, just return. Otherwise dispatches to the
* pad's activate function to perform the actual activation.
*
* If not @active, checks the pad's current mode and calls
* gst_pad_activate_push() or gst_pad_activate_pull(), as appropriate, with
* a FALSE argument.
*
* @param active whether or not the pad should be active.
* @return true if the operation was successful.
*/
public boolean setActive(boolean active) {
return GSTPAD_API.gst_pad_set_active(this, active);
}
/**
* Checks if the pad is blocked or not. This function returns the last
* requested state of the pad. It is not certain that the pad is actually
* blocking at this point (see {@link #isBlocking}).
*
* @return true if the pad is blocked.
*/
public boolean isBlocked() {
return GSTPAD_API.gst_pad_is_blocked(this);
}
/**
* Run a runnable under a blocked state
*
* @param callback The code to run when pad is blocked
*/
public void block(final Runnable callback) {
addEventProbe(new EVENT_PROBE() {
public PadProbeReturn eventReceived(Pad pad, Event event) {
callback.run();
pad.removeCallback(EVENT_PROBE.class, this);
return PadProbeReturn.REMOVE;
}
}, GstPadAPI.GST_PAD_PROBE_TYPE_IDLE);
}
/**
* Checks if the pad is blocking or not. This is a guaranteed state of
* whether the pad is actually blocking on a {@link Buffer} or an
* {@link Event}.
*
* @return true if the pad is blocking.
*/
public boolean isBlocking() {
return GSTPAD_API.gst_pad_is_blocking(this);
}
/**
* Add a listener for the
* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are
* called, then others, then finally {@link PadProbeType#IDLE}. The only
* exception here are IDLE probes that are called immediately if the pad is
* already idle while calling addProbe(). In each of the groups, probes are
* called in the order in which they were added.
*
* @param mask set of mask flags for probe - common options are fields of
* {@link PadProbeType}
* @param callback callback that will be called with notifications of the
* pad state
*/
public void addProbe(final Set
* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are
* called, then others, then finally {@link PadProbeType#IDLE}. The only
* exception here are IDLE probes that are called immediately if the pad is
* already idle while calling addProbe(). In each of the groups, probes are
* called in the order in which they were added.
*
* @param mask mask flag for probe
* @param callback callback that will be called with notifications of the
* pad state
*/
public void addProbe(PadProbeType mask, PROBE callback) {
addProbe(mask.intValue(), callback);
}
synchronized void addProbe(int mask, PROBE callback) {
final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {
@Override
public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {
PadProbeInfo info = new PadProbeInfo(probeInfo);
PadProbeReturn ret = callback.probeCallback(pad, info);
info.invalidate();
if (ret == PadProbeReturn.REMOVE) {
// don't want handle to try and remove in GCallback::disconnect
// @TODO move to Map
* This function can be used by applications to send events in the pipeline.
*
*
* If this pad is a source pad, event should be an upstream event.
* If this pad is a sink pad, event should be a downstream event.
*
* For example, you would not send a {@link EventType#EOS} on a src pad; EOS
* events only propagate downstream.
*
*
* Furthermore, some downstream events have to be serialized with data flow,
* like EOS, while some can travel out-of-band, like
* {@link EventType#FLUSH_START}. If the event needs to be serialized with
* data flow, this function will take the pad's stream lock while calling
* its event function.
*
* @param event the event to send.
* @return true if the event was handled.
*/
public boolean sendEvent(Event event) {
return GSTPAD_API.gst_pad_send_event(this, event);
}
/**
* Sends the event to the peer of this pad.
*
*
* This function is mainly used by elements to send events to their peer
* elements.
*
* @param event the event to send
* @return true if the event was handled
*/
public boolean pushEvent(Event event) {
return GSTPAD_API.gst_pad_push_event(this, event);
}
/**
* Chain a buffer to pad.
*
* The function returns {@link FlowReturn#FLUSHING} if the
* pad was flushing.
*
* If the caps on buffer are different from the current caps on pad, this
* function will call any function installed on pad (see
* gst_pad_set_setcaps_function()). If the new caps are not acceptable for
* pad, this function returns
* {@link FlowReturn#NOT_NEGOTIATED}.
*
* The function proceeds calling the chain function installed on pad and the
* return value of that function is returned to the caller.
* {@link FlowReturn#NOT_SUPPORTED} is returned if pad has no
* chain function.
*
* In all cases, success or failure, the caller loses its reference to
* buffer after calling this function.
*
* @param buffer the Buffer, returns {@link FlowReturn#ERROR}
* if NULL.
* @return a org.gstreamer.FlowReturn
*/
public FlowReturn chain(Buffer buffer) {
return GSTPAD_API.gst_pad_chain(this, buffer);
}
/**
* When pad is flushing this function returns
* {@link FlowReturn#FLUSHING} immediately.
*
* Calls the getRange function of pad, see GstPadGetRangeFunction for a
* description of a getRange function. If pad has no getRange function
* installed (see gst_pad_set_getrange_function()) this function returns
* {@link FlowReturn#NOT_SUPPORTED}.
*
* This is a lowlevel function. Usualy {@link Pad#pullRange} is used.
*
* @param offset The start offset of the buffer
* @param size The length of the buffer
* @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL.
* @return a FlowReturn from the peer pad. When this function returns OK,
* buffer will contain a valid Buffer.
*/
public FlowReturn getRange(long offset, int size, Buffer[] buffer) {
return GSTPAD_API.gst_pad_get_range(this, offset, size, buffer);
}
/**
* Pulls a buffer from the peer pad.
*
* This function will first trigger the pad block signal if it was
* installed.
*
* When pad is not linked {@link FlowReturn#NOT_LINKED} is returned else
* this function returns the result of {@link Pad#getRange} on the peer pad.
* See {@link Pad#getRange} for a list of return values and for the
* semantics of the arguments of this function.
*
* buffer's caps must either be unset or the same as what is already
* configured on pad. Renegotiation within a running pull-mode pipeline is
* not supported.
*
* @param offset The start offset of the buffer
* @param size The length of the buffer
* @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL.
* @return a FlowReturn from the peer pad. When this function returns OK,
* buffer will contain a valid Buffer. MT safe.
*/
public FlowReturn pullRange(long offset, int size, Buffer[] buffer) {
return GSTPAD_API.gst_pad_pull_range(this, offset, size, buffer);
}
/**
* Pushes a buffer to the peer of pad . This function will call installed
* block probes before triggering any installed data probes.
*
* The function proceeds calling gst_pad_chain() on the peer pad and returns
* the value from that function. If pad has no peer, {@link FlowReturn#NOT_LINKED}
* will be returned.
*
* In all cases, success or failure, the caller loses its reference to
* buffer after calling this function.
*
* @param buffer the GstBuffer to push returns GST_FLOW_ERROR if not.
* [transfer full]
* @return a GstFlowReturn from the peer pad.
*
* MT safe.
*/
public FlowReturn push(final Buffer buffer) {
return GSTPAD_API.gst_pad_push(this, buffer);
}
/**
* Gets the template for pad.
*
* @return the GstPadTemplate from which this pad was instantiated, or NULL
* if this pad has no template.
*/
public PadTemplate getTemplate() {
return GSTPAD_API.gst_pad_get_pad_template(this);
}
/**
* Check if the pad has caps set on it with a GST_EVENT_CAPS events
*
* @return true if the pad has caps set
*/
public boolean hasCurrentCaps() {
return GSTPAD_API.gst_pad_has_current_caps(this);
}
/**
* Signal emitted when new this {@link Pad} is linked to another {@link Pad}
*
* @see #connect(LINKED)
* @see #disconnect(LINKED)
*/
public static interface LINKED {
/**
* Called when a {@link Pad} is linked to another Pad.
*
* @param pad the pad that emitted the signal.
* @param peer the peer pad that has been connected.
*/
public void linked(Pad pad, Pad peer);
}
/**
* Signal emitted when new this {@link Pad} is disconnected from a peer
* {@link Pad}
*
* @see #connect(UNLINKED)
* @see #disconnect(UNLINKED)
*/
public static interface UNLINKED {
/**
* Called when a {@link Pad} is unlinked from another Pad.
*
* @param pad the pad that emitted the signal.
* @param peer the peer pad that has been connected.
*/
public void unlinked(Pad pad, Pad peer);
}
/**
* Callback used by
* {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}
*/
public static interface PROBE {
/**
* Callback used by
* {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}.
* Gets called to notify about the current blocking type.
*
* The PadProbeInfo and any Buffer, Event or Query referenced from
* it, is only valid for the duration of the callback.
*
* @param pad Pad that is blocked
* @param info PadProbeInfo with access to underlying data
* @return PadProbeReturn value
*/
public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info);
}
/**
* Probe for listening when an event passes through this Pad.
*
* @see #addEventProbe(EVENT_PROBE)
* @see #removeEventProbe(EVENT_PROBE)
*/
public static interface EVENT_PROBE {
public PadProbeReturn eventReceived(Pad pad, Event event);
}
/**
* Probe for listening when new data is available on the Pad.
*
* @see #addDataProbe(DATA_PROBE)
* @see #removeDataProbe(DATA_PROBE)
*/
public static interface DATA_PROBE {
public PadProbeReturn dataReceived(Pad pad, Buffer buffer);
}
private static class Handle extends GstObject.Handle {
private final Set
* For convenience, the various flag combinations are provided as immutable
* Sets.
*
* See upstream documentation at
* https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html#GstPadProbeType
*/
public enum PadProbeType implements NativeFlags
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPadTemplate.html
*
* Pad and PadTemplates have {@code Caps} attached to it to describe the media
* type they are capable of dealing with. {@link #getCaps} is used to get the
* caps of a PadTemplate. It is not possible to modify the caps of a PadTemplate
* after creation.
*/
public class PadTemplate extends GstObject {
public static final String GTYPE_NAME = "GstPadTemplate";
/**
* Creates a new proxy for PadTemplate.
*
* This is only for internal use.
*
* @param init internal initialization data.
*/
PadTemplate(Initializer init) {
super(init);
}
/**
* Creates a new pad template with a name according to the given template,
* with the given arguments and {@link PadPresence#ALWAYS }
*
* @param nameTemplate the name template.
* @param direction the direction of the template.
* @param caps a {@code Caps} set for the template.
*/
public PadTemplate(String nameTemplate, PadDirection direction, Caps caps) {
this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, PadPresence.ALWAYS, caps)));
}
/**
* Creates a new pad template with a name according to the given template
* and with the given arguments.
*
* @param nameTemplate the name template.
* @param direction the direction of the template.
* @param presence the presence of the pad, which controls the lifetime.
* @param caps a {@code Caps} set for the template.
*/
public PadTemplate(String nameTemplate, PadDirection direction, PadPresence presence, Caps caps) {
this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, presence, caps)));
}
/**
* Gets the {@link Caps} set on this {@code PadTemplate}
*
* @return the media type on this template.
*/
public Caps getCaps() {
return GSTPADTEMPLATE_API.gst_pad_template_get_caps(this);
}
/**
* Gets the name of this template
*
* @return the name of this template
*/
public String getTemplateName() {
return get("name-template").toString();
}
/**
* Gets the direction of this template
*
* @return {@link PadDirection}
*/
public PadDirection getDirection() {
Object d = get("direction");
if (d instanceof Number) {
return PadDirection.values()[((Number) d).intValue()];
}
return null;
}
/**
* Gets presence of this template
*
* @return {@link PadPresence}
*/
public PadPresence getPresence() {
Object p = get("presence");
if (p instanceof Number) {
return PadPresence.values()[((Number) p).intValue()];
}
return null;
}
}
================================================
FILE: src/org/freedesktop/gstreamer/Pipeline.java
================================================
/*
* Copyright (c) 2021 Neil C Smith
* Copyright (c) 2008 Wayne Meissner
* Copyright (C) 2000 Erik Walthinsen
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPipeline.html
*
* Elements are added and removed from the pipeline using the {@code Bin}
* methods like {@link Bin#add add} and {@link Bin#remove remove}.
*
* Before changing the state of the Pipeline (see {@link Element}) a {@link Bus}
* can be retrieved with {@link #getBus getBus}. This bus can then be used to
* receive {@link Message}s from the elements in the pipeline.
*
* By default, a Pipeline will automatically flush the pending Bus messages when
* going to the NULL state to ensure that no circular references exist when no
* messages are read from the Bus. This behaviour can be changed with
* {@link #setAutoFlushBus setAutoFlushBus}
*
* When the Pipeline performs the PAUSED to PLAYING state change it will select
* a clock for the elements. The clock selection algorithm will by default
* select a clock provided by an element that is most upstream (closest to the
* source). For live pipelines (ones that return
* {@link StateChangeReturn#NO_PREROLL} from the
* {@link Element#setState setState} call) this will select the clock provided
* by the live source. For normal pipelines this will select a clock provided by
* the sinks (most likely the audio sink). If no element provides a clock, a
* default SystemClock is used.
*
*
* The clock selection can be controlled with the gst_pipeline_use_clock()
* method, which will enforce a given clock on the pipeline. With
* gst_pipeline_auto_clock() the default clock selection algorithm can be
* restored.
*
*
* A Pipeline maintains a stream time for the elements. The stream time is
* defined as the difference between the current clock time and the base time.
* When the pipeline goes to READY or a flushing seek is performed on it, the
* stream time is reset to 0. When the pipeline is set from PLAYING to PAUSED,
* the current clock time is sampled and used to configure the base time for the
* elements when the pipeline is set to PLAYING again. This default behaviour
* can be changed with the gst_pipeline_set_new_stream_time() method.
*
* When sending a flushing seek event to a GstPipeline (see {@link #seek seek}),
* it will make sure that the pipeline is properly PAUSED and resumed as well as
* set the new stream time to 0 when the seek succeeded.
*/
public class Pipeline extends Bin {
public static final String GST_NAME = "pipeline";
public static final String GTYPE_NAME = "GstPipeline";
private static Logger LOG = Logger.getLogger(Pipeline.class.getName());
private final Handle handle;
protected Pipeline(Initializer init) {
this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef);
}
Pipeline(Handle handle, boolean needRef) {
super(handle, needRef);
this.handle = handle;
handle.busRef.set(GSTPIPELINE_API.gst_pipeline_get_bus(this));
}
/**
* Creates a new instance of Pipeline with a unique name.
*/
public Pipeline() {
this(Natives.initializer(GSTPIPELINE_API.ptr_gst_pipeline_new(null), false));
}
/**
* Creates a new instance of Pipeline with the given name.
*
* @param name The name used to identify this pipeline.
*/
public Pipeline(String name) {
this(initializer(name));
}
private static Initializer initializer(String name) {
Pointer new_pipeline = GSTPIPELINE_API.ptr_gst_pipeline_new(name);
return Natives.initializer(new_pipeline, false);
}
/**
* Usually, when a pipeline goes from READY to NULL state, it automatically
* flushes all pending messages on the bus, which is done for refcounting
* purposes, to break circular references.
*
* This means that applications that update state using (async) bus messages
* (e.g. do certain things when a pipeline goes from PAUSED to READY) might
* not get to see messages when the pipeline is shut down, because they
* might be flushed before they can be dispatched in the main thread. This
* behaviour can be disabled using this function.
*
* It is important that all messages on the bus are handled when the
* automatic flushing is disabled else memory leaks will be introduced.
*
* MT safe.
*
* @param flush whether or not to automatically flush the bus when the
* pipeline goes from READY to NULL state
*/
public void setAutoFlushBus(boolean flush) {
GSTPIPELINE_API.gst_pipeline_set_auto_flush_bus(this, flush);
}
/**
* Checks if the pipeline will automatically flush messages when going to
* the NULL state.
*
* MT safe.
*
* @return true if the pipeline automatically flushes messages.
*/
public boolean getAutoFlushBus() {
return GSTPIPELINE_API.gst_pipeline_get_auto_flush_bus(this);
}
/**
* Set the clock for pipeline. The clock will be distributed to all the
* elements managed by the pipeline.
*
* MT safe
*
* @param clock The {@link Clock} to use
* @return true if the clock could be set on the pipeline, false if some
* element did not accept the clock.
*
*/
public boolean setClock(Clock clock) {
return GSTPIPELINE_API.gst_pipeline_set_clock(this, clock);
}
/**
* Return the current {@link Clock} used by the pipeline.
*
* @return The {@link Clock} currently in use.
*/
@Override
public Clock getClock() {
return GSTPIPELINE_API.gst_pipeline_get_clock(this);
}
/**
* Force the Pipeline to use the a specific clock. The pipeline will always
* use the given clock even if new clock providers are added to this
* pipeline.
*
* MT safe
*
* @param clock The {@link Clock} to use. If clock is null, all clocking is
* disabled, and the pipeline will run as fast as possible.
*
*/
public void useClock(Clock clock) {
GSTPIPELINE_API.gst_pipeline_use_clock(this, clock);
}
/**
* Gets the {@link Bus} this pipeline uses for messages.
*
* @return The {@link Bus} that this pipeline uses.
*/
@Override
public Bus getBus() {
return handle.busRef.get();
}
/**
* Sets the position in the media stream to time in nanoseconds.
*
* Prefer use of
* {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.
*
* @param time The time to change the position to.
* @return true if seek is successful
*/
// @TODO move seek and query methods on to element?
public boolean seek(long time) {
return seek(time, TimeUnit.NANOSECONDS);
}
/**
* Sets the current position in the media stream.
*
* Prefer use of
* {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.
*
* @param time the time to change the position to.
* @param unit the {@code TimeUnit} the time is expressed in.
* @return true if seek is successful
*/
public boolean seek(long time, TimeUnit unit) {
return seek(1.0, Format.TIME, EnumSet.of(SeekFlags.FLUSH, SeekFlags.KEY_UNIT),
SeekType.SET, TimeUnit.NANOSECONDS.convert(time, unit),
SeekType.NONE, -1);
}
/**
* Seeks to a new position in the media stream.
*
*
* The start and stop values are expressed in format.
*
* A rate of 1.0 means normal playback rate, 2.0 means double speed.
* Negative values means backwards playback. A value of 0.0 for the rate is
* not allowed and should be accomplished instead by PAUSING the pipeline.
*
* A pipeline has a default playback segment configured with a start
* position of 0, a stop position of -1 and a rate of 1.0. The currently
* configured playback segment can be queried with #GST_QUERY_SEGMENT.
*
* startType and stopType specify how to adjust the currently configured
* start and stop fields in segment. Adjustments can be made relative or
* absolute to the last configured values. A type of {@link SeekType#NONE}
* means that the position should not be updated.
*
* When the rate is positive and start has been updated, playback will start
* from the newly configured start position.
*
* For negative rates, playback will start from the newly configured stop
* position (if any). If the stop position if updated, it must be different
* from -1 for negative rates.
*
* It is not possible to seek relative to the current playback position, to
* do this, PAUSE the pipeline, query the current playback position with
* {@link org.gstreamer.Pipeline#queryPosition queryPosition} and update the
* playback segment current position with a {@link SeekType#SET} to the
* desired position.
*
* @param rate the new playback rate
* @param format the format of the seek values
* @param seekFlags the seek flags
* @param startType the type and flags for the new start position
* @param start the value of the new start position
* @param stopType the type and flags for the new stop position
* @param stop the value of the new stop position
* @return true if seek is successful
*/
// for compatibility
public boolean seek(double rate, Format format, EnumSet
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPlugin.html
*
* GStreamer is extensible, so {@link Element} instances can be loaded at
* runtime. A plugin system can provide one or more of the basic GStreamer
* {@link PluginFeature} subclasses.
*
* A plugin should export a symbol
* Once you have a handle to a #GstPlugin (e.g. from the #GstRegistryPool), you
* can add any object that subclasses #GstPluginFeature.
*
* Use gst_plugin_find_feature() and gst_plugin_get_feature_list() to find
* features in a plugin.
*
* Usually plugins are always automatically loaded so you don't need to call
* {@link #loadByName} explicitly to bring it into memory. There are options to
* statically link plugins to an app or even use GStreamer without a plugin
* repository in which case {@link #loadByName} can be needed to bring the
* plugin into memory.
*
* @see PluginFeature
* @see ElementFactory
*/
public class Plugin extends GstObject {
public static final String GTYPE_NAME = "GstPlugin";
/**
* Creates a new instance of GstElement
*
* @param init internal initialization data.
*/
Plugin(Initializer init) {
super(init);
}
/**
* Load the named plugin.
*
* @param pluginName
* @return A new Plugin reference if the plugin was loaded, else null.
*/
public static Plugin loadByName(String pluginName) {
return GSTPLUGIN_API.gst_plugin_load_by_name(pluginName);
}
/**
* Get the short name of the plugin.
*
* @return the name of the plugin.
*/
@Override
public String getName() {
return GSTPLUGIN_API.gst_plugin_get_name(this);
}
/**
* Get the long descriptive name of the plugin.
*
* @return The long name of the plugin.
*/
public String getDescription() {
return GSTPLUGIN_API.gst_plugin_get_description(this);
}
/**
* Get the filename of the plugin.
*
* @return The filename of the plugin.
*/
public String getFilename() {
return GSTPLUGIN_API.gst_plugin_get_filename(this);
}
/**
* Get the version of the plugin.
*
* @return The version of the plugin.
*/
public String getVersion() {
return GSTPLUGIN_API.gst_plugin_get_version(this);
}
/**
* Get the license of the plugin.
*
* @return The license of the plugin.
*/
public String getLicense() {
return GSTPLUGIN_API.gst_plugin_get_license(this);
}
/**
* Get the source module the plugin belongs to.
*
* @return The source of the plugin.
*/
public String getSource() {
return GSTPLUGIN_API.gst_plugin_get_source(this);
}
/**
* Get the package the plugin belongs to.
*
* @return The package of the plugin.
*/
public String getPackage() {
return GSTPLUGIN_API.gst_plugin_get_package(this);
}
/**
* Get the URL where the plugin comes from.
*
* @return The origin of the plugin.
*/
public String getOrigin() {
return GSTPLUGIN_API.gst_plugin_get_origin(this);
}
/**
* Get the release date (and possibly time) in form of a string, if
* available.
*
* For normal GStreamer plugin releases this will usually just be a date in
* the form of "YYYY-MM-DD", while pre-releases and builds from git may
* contain a time component after the date as well, in which case the string
* will be formatted like "YYYY-MM-DDTHH:MMZ" (e.g.
* "2012-04-30T09:30Z").Test
*/
public String getReleaseDateString() {
return GSTPLUGIN_API.gst_plugin_get_release_date_string(this);
}
/**
* Queries if the plugin is loaded into memory.
*
* @return true if it is loaded, false otherwise.
*/
public boolean isLoaded() {
return GSTPLUGIN_API.gst_plugin_is_loaded(this);
}
// /**
// * Ensures this plugin is loaded.
// *
// * @return a potentially new Plugin reference.
// */
// public Plugin load() {
// return GSTPLUGIN_API.gst_plugin_load(this);
// }
}
================================================
FILE: src/org/freedesktop/gstreamer/PluginFeature.java
================================================
/*
* Copyright (C) 2019 Neil C Smith
* Copyright (C) 2007 Wayne Meissner
* Copyright (C) 1999,2000 Erik Walthinsen
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPluginFeature.html
*
* This is a base class for anything that can be added to a Plugin.
*
* @see Plugin
*/
public class PluginFeature extends GstObject {
public static final String GTYPE_NAME = "GstPluginFeature";
/**
* Element priority ranks. Defines the order in which the autoplugger (or
* similar rank-picking mechanisms, such as e.g.
* gst_element_make_from_uri()) will choose this element over an alternative
* one with the same function.
*
* These constants serve as a rough guidance for defining the rank of a
* GstPluginFeature. Any value is valid, including values bigger than
* GST_RANK_PRIMARY .
*/
public enum Rank implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPromise.html
*
*/
@Gst.Since(minor = 14)
public class Promise extends MiniObject {
public static final String GTYPE_NAME = "GstPromise";
private GstCallback changeFunction;
/**
* Creates a new instance of Promise. This constructor is used internally.
*
* @param init internal initialization data.
*/
Promise(final Initializer init) {
super(init);
}
/**
* Creates a new instance of promise
*/
public Promise() {
this(Natives.initializer(GSTPROMISE_API.ptr_gst_promise_new()));
Gst.checkVersion(1, 14); // @TODO ideally this check would be before native call!
}
/**
* Creates a new instance of promise with a callback attached.
*
* @param listener Listener to be called whenever the state of a
* {@link Promise} is changed
*/
public Promise(final PROMISE_CHANGE listener) {
this(new GstCallback() {
public void callback(Promise promise, Pointer userData) {
listener.onChange(promise);
}
});
}
private Promise(GstCallback callback) {
this(Natives.initializer(GSTPROMISE_API
.ptr_gst_promise_new_with_change_func(callback, null, null)));
this.changeFunction = callback;
}
/**
* Wait for the promise to move out of the PENDING {@link PromiseResult}
* state. If the promise is not in PENDING then it will immediately return.
*
* @return the {@link PromiseResult} of the promise.
*/
public PromiseResult waitResult() {
return GSTPROMISE_API.gst_promise_wait(this);
}
/**
* Set a reply on the promise.
*
* Will wake up any waiters on the promise with the REPLIED
* {@link PromiseResult} state. If the promise has already been interrupted
* than the replied will not be visible to any waiters
*
* @param structure the {@link Structure} to reply the promise with, caller
* should not use this structure afterward as it is invalidated through
* {@link NativeObject#invalidate()}
*/
public void reply(final Structure structure) {
GSTPROMISE_API.gst_promise_reply(this, structure);
}
/**
* Interrupt waiting for the result of the promise.
*
* Any waiters on the promise will receive the INTERRUPTED
* {@link PromiseResult} state.
*/
public void interrupt() {
GSTPROMISE_API.gst_promise_interrupt(this);
}
/**
* Expire a promise.
*
* Any waiters on the promise will received the EXPIRED
* {@link PromiseResult} state.
*/
public void expire() {
GSTPROMISE_API.gst_promise_expire(this);
}
/**
* Retrieve the reply set on the promise.
*
* The state of the promise must be in the REPLIED {@link PromiseResult}
* state. The return structure is owned by the promise and thus cannot be
* modified.
*
* @return the {@link Structure} set on the promise reply.
*/
public Structure getReply() {
return Structure.objectFor(GSTPROMISE_API.ptr_gst_promise_get_reply(this), false, false);
}
/**
* Called whenever the state of the promise is changed from PENDING to any
* other {@link PromiseResult}
*/
public static interface PROMISE_CHANGE {
/**
* Called whenever the state of the promise is changed from PENDING to
* any other {@link PromiseResult}
*
* @param promise the original promise that had the callback attached to
*/
public void onChange(Promise promise);
}
}
================================================
FILE: src/org/freedesktop/gstreamer/PromiseResult.java
================================================
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2018 Antonio Morales
*
* 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
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstRegistry.html
*
* One registry holds the metadata of a set of plugins.
* All registries build the RegistryPool.
*
* Design:
*
* The Registry object is a list of plugins and some methods for dealing
* with them. Plugins are matched 1-1 with a file on disk, and may or may
* not be loaded at a given time. There may be multiple Registry objects,
* but the "default registry" is the only object that has any meaning to the
* core.
*
* The registry.xml file is actually a cache of plugin information. This is
* unlike versions prior to 0.10, where the registry file was the primary source
* of plugin information, and was created by the gst-register command.
*
* The primary source, at all times, of plugin information is each plugin file
* itself. Thus, if an application wants information about a particular plugin,
* or wants to search for a feature that satisfies given criteria, the primary
* means of doing so is to load every plugin and look at the resulting
* information that is gathered in the default registry. Clearly, this is a time
* consuming process, so we cache information in the registry.xml file.
*
* On startup, plugins are searched for in the plugin search path. This path can
* be set directly using the GST_PLUGIN_PATH environment variable. The registry
* file is loaded from ~/.gstreamer-$GST_MAJORMINOR/registry-$ARCH.xml or the
* file listed in the GST_REGISTRY environment variable. The only reason to change the
* registry location is for testing.
*
* For each plugin that is found in the plugin search path, there could be 3
* possibilities for cached information:
*
* In the first two cases, the plugin is loaded and the cache updated. In
* addition to these cases, the cache may have entries for plugins that are not
* relevant to the current process. These are marked as not available to the
* current process. If the cache is updated for whatever reason, it is marked
* dirty.
*
* A dirty cache is written out at the end of initialization. Each entry is
* checked to make sure the information is minimally valid. If not, the entry is
* simply dropped.
*
*
* The "cache" and "default registry" are different concepts and can represent
* different sets of plugins. For various reasons, at init time, the cache is
* stored in the default registry, and plugins not relevant to the current
* process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are
* removed at the end of intitialization.
*/
public class Registry extends GstObject {
public static final String GTYPE_NAME = "GstRegistry";
/** Creates a new instance of Registry */
Registry(Initializer init) {
super(init);
}
/**
* Find a plugin in the registry.
*
* @param name The plugin name to find.
* @return The plugin with the given name or null if the plugin was not found.
*/
public Plugin findPlugin(String name) {
return GSTREGISTRY_API.gst_registry_find_plugin(this, name);
}
/**
* Add the plugin to the registry. The plugin-added signal will be emitted.
*
* @param plugin the {@link Plugin} to add
* @return true on success.
*/
public boolean addPlugin(Plugin plugin) {
return GSTREGISTRY_API.gst_registry_add_plugin(this, plugin);
}
/**
* Remove a plugin from the registry.
*
* @param plugin The plugin to remove.
*/
public void removePlugin(Plugin plugin) {
GSTREGISTRY_API.gst_registry_remove_plugin(this, plugin);
}
// /**
// * Find the {@link PluginFeature} with the given name and type in the registry.
// *
// * @param name The name of the plugin feature to find.
// * @param type The type of the plugin feature to find.
// * @return The pluginfeature with the given name and type or null
// * if the plugin was not found.
// */
// public PluginFeature findPluginFeature(String name, GType type) {
// return GSTREGISTRY_API.gst_registry_find_feature(this, name, type);
// }
/**
* Find a {@link PluginFeature} by name in the registry.
*
* @param name The name of the plugin feature to find.
* @return The {@link PluginFeature} or null if not found.
*/
public PluginFeature lookupFeature(String name) {
return GSTREGISTRY_API.gst_registry_lookup_feature(this, name);
}
/**
* Get a list of all plugins registered in the registry.
*
* @return a List of {@link Plugin}
*/
public List
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html
*/
public class SDPMessage extends NativeObject {
public static final String GTYPE_NAME = "GstSDPMessage";
/**
* Internally used constructor. Do not use.
*
* @param init internal initialization data
*/
SDPMessage(Initializer init) {
this(new Handle(init.ptr, init.ownsHandle));
}
SDPMessage(Handle handle) {
super(handle);
}
/**
* Creates a new instance of SDPMessage
*/
public SDPMessage() {
this(initHandle());
}
/**
* A SDP formatted string representation of SDPMessage.
*
* Used for offer/answer exchanges for real time communicationse
*
* @return the SDP string representation of SDPMessage.
*/
public String toString() {
return GSTSDPMESSAGE_API.gst_sdp_message_as_text(this);
}
/**
* Takes a SDP string and parses it and fills in all fields for SDPMessage.
*
* Look at https://tools.ietf.org/html/rfc4566 for more information on SDP
*
* @param sdpString the sdp string
*/
public void parseBuffer(String sdpString) {
byte[] data = sdpString.getBytes(StandardCharsets.US_ASCII);
int length = sdpString.length();
GSTSDPMESSAGE_API.gst_sdp_message_parse_buffer(data, length, this);
}
// /**
// * Creates a copy of this SDPMessage.
// *
// * @return a copy of SDPMessage.
// */
// SDPMessage copy(boolean shouldInvalidateOriginal) {
// Pointer[] ptr = new Pointer[1];
// GSTSDPMESSAGE_API.gst_sdp_message_copy(this, ptr);
// if (shouldInvalidateOriginal) {
// this.invalidate();
// }
// return new SDPMessage(initializer(ptr[0]));
// }
private static Handle initHandle() {
Pointer[] ptr = new Pointer[1];
GSTSDPMESSAGE_API.gst_sdp_message_new(ptr);
return new Handle(new GPointer(ptr[0]), true);
}
private static final class Handle extends NativeObject.Handle {
public Handle(GPointer ptr, boolean ownsHandle) {
super(ptr, ownsHandle);
}
@Override
protected void disposeNativeHandle(GPointer ptr) {
GSTSDPMESSAGE_API.gst_sdp_message_free(ptr.getPointer());
}
}
}
================================================
FILE: src/org/freedesktop/gstreamer/SDPResult.java
================================================
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2018 Antonio Morales
*
* 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
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html#GstSDPResult
*
* @see SDPMessage
*/
public enum SDPResult implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstSample.html
*
*/
public class Sample extends MiniObject {
public static final String GTYPE_NAME = "GstSample";
Sample(Initializer init) {
super(init);
}
/**
* Get the {@link Caps} associated with sample, or NULL when there is no caps.
* The caps remains valid as long as sample is valid.
* If you need to hold on to the caps for longer than that, take a ref to the caps
*
* @return caps of sample or NULL when there is no caps.
*/
public Caps getCaps() {
return GSTSAMPLE_API.gst_sample_get_caps(this);
}
/**
* Set the {@link Caps} associated with sample.
* This sample must be writable.
*
* Since GStreamer 1.16
*
* @param caps
*/
@Gst.Since(minor = 16)
public void setCaps(Caps caps) {
Gst.checkVersion(1, 16);
GSTSAMPLE_API.gst_sample_set_caps(this, caps);
}
/**
* Get the {@link Buffer} associated with sample, or NULL when there is no
* buffer.
* The buffer remains valid as long as sample is valid.
* If you need to hold on to it for longer than that, take a ref to the buffer.
*
* @return buffer of sample or NULL when there is no buffer.
*/
public Buffer getBuffer() {
return GSTSAMPLE_API.gst_sample_get_buffer(this);
}
/**
* Set the {@link Buffer} associated with sample.
* This sample must be writable.
*
* Since GStreamer 1.16
*
* @param buffer
*/
@Gst.Since(minor = 16)
public void setBuffer(Buffer buffer) {
Gst.checkVersion(1, 16);
GSTSAMPLE_API.gst_sample_set_buffer(this, buffer);
}
}
================================================
FILE: src/org/freedesktop/gstreamer/Segment.java
================================================
/*
* Copyright (c) 2010 David Hoyt
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstState
*
*/
public enum State implements NativeEnum
* Only {@link StateChangeReturn#FAILURE} is a real failure.
*
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstStateChangeReturn
*
*/
public enum StateChangeReturn implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstStructure.html
*
* A Structure is a collection of key/value pairs. The keys are expressed as
* GQuarks and the values can be of any GType.
*
* In addition to the key/value pairs, a Structure also has a name. The name
* starts with a letter and can be followed by letters, numbers and any of
* "/-_.:".
*
* Structure is used by various GStreamer subsystems to store information in a
* flexible and extensible way.
*
* A Structure can be created with new {@link #Structure(String)} or
* {@link #Structure(String, String, Object...)}, which both take a name and an
* optional set of key/value pairs along with the types of the values.
*
* Field values can be changed with set{Integer,String}() etc functions.
*
* Field values can be retrieved with get{Integer,String}() etc functions.
*
* Fields can be removed with {@link #removeField} or {@link #removeFields}
*
* @see Caps
* @see Event
*/
public class Structure extends NativeObject {
public static final String GTYPE_NAME = "GstStructure";
/**
* Creates a new, empty #GstStructure with the given name.
*
* @param name The name of new structure.
*/
public Structure(String name) {
this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new_empty(name)), true));
}
/**
* Creates a new Structure with the given name. Parses the list of variable
* arguments and sets fields to the values listed. Variable arguments should
* be passed as field name, field type, and value.
*
* @param name The name of new structure.
* @param firstFieldName The name of first field to set
* @param data Additional arguments.
*/
public Structure(String name, String firstFieldName, Object... data) {
this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new(name, firstFieldName, data)), true));
}
/**
* Creates a new instance of Structure
*/
Structure(Initializer init) {
this(new Handle(init.ptr, init.ownsHandle));
}
private Structure(Handle handle) {
super(handle);
}
public Structure copy() {
return GSTSTRUCTURE_API.gst_structure_copy(this);
}
public boolean fixateNearestInteger(String field, Integer value) {
return GSTSTRUCTURE_API.gst_structure_fixate_field_nearest_int(this, field, value);
}
/**
* Get the value of the named field as a boolean. Throws
* {@link InvalidFieldException} if the Structure does not contain the named
* field or the named field is not a boolean.
*
* @param fieldName name of field
* @return boolean value of the named field
*/
public boolean getBoolean(String fieldName) {
int[] val = {0};
if (!GSTSTRUCTURE_API.gst_structure_get_boolean(this, fieldName, val)) {
throw new InvalidFieldException("boolean", fieldName);
}
return val[0] != 0;
}
/**
* Get the value of the named field as a double. Throws
* {@link InvalidFieldException} if the Structure does not contain the named
* field or the named field is not a double.
*
* @param fieldName name of field
* @return double value of the named field
*/
public double getDouble(String fieldName) {
double[] val = {0d};
if (!GSTSTRUCTURE_API.gst_structure_get_double(this, fieldName, val)) {
throw new InvalidFieldException("double", fieldName);
}
return val[0];
}
/**
* Extract the values of the named field as an array of doubles. If the
* native GType of the field is a GValueArray then this method will return
* an array of the contained values, assuming all contained values are of
* G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array
* will be returned.
*
* This method will create a new array each time. If you are repeatedly
* calling this method consider using
* {@link #getDoubles(java.lang.String, double[])}.
*
* Throws {@link InvalidFieldException} if the field does not exist, or the
* field values contained are not of type G_TYPE_DOUBLE.
*
* This method only currently supports lists of values inside a GValueArray
* - other native list types will be supported in future.
*
* @param fieldName name of field
* @return List of values from the named field
*/
public double[] getDoubles(String fieldName) {
return getDoubles(fieldName, null);
}
/**
* Extract the values of the named field as an array of doubles. If the
* native GType of the field is a GValueArray then this method will return
* an array of the contained values, assuming all contained values are of
* G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array
* will be returned.
*
* An array may be passed into this method to contain the result. A new
* array will be created if the array is null or not of the correct length.
*
* Throws {@link InvalidFieldException} if the field does not exist, or the
* field values contained are not of type G_TYPE_DOUBLE.
*
* This method only currently supports lists of values inside a GValueArray
* - other native list types will be supported in future.
*
* @param fieldName name of field
* @param array an array to hold values, or null
* @return List of values from the named field
*/
public double[] getDoubles(String fieldName, double[] array) {
Object val = getValue(fieldName);
if (val instanceof GValueAPI.GValueArray) {
GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val;
int count = arr.getNValues();
double[] values = array == null || array.length != count
? new double[count] : array;
for (int i = 0; i < count; i++) {
GValue gval = arr.nth(i);
if (gval.checkHolds(GType.DOUBLE)) {
values[i] = GValueAPI.GVALUE_API.g_value_get_double(gval);
} else {
throw new InvalidFieldException("doubles", fieldName);
}
}
return values;
} else {
if (Double.class.isInstance(val)) {
double[] values = array == null || array.length != 1
? new double[1] : array;
values[0] = ((Double) val);
return values;
} else {
throw new InvalidFieldException("double", fieldName);
}
}
}
/**
* Get the number of fields in the {@link Structure}.
*
* @return the structure's filed number.
*/
public int getFields() {
return GSTSTRUCTURE_API.gst_structure_n_fields(this);
}
/**
* Gets FOURCC field int representation
*
* @param fieldName The name of the field.
* @return FOURCC field as a 4 byte integer
*/
public int getFourcc(String fieldName) {
int[] val = {0};
if (!GSTSTRUCTURE_API.gst_structure_get_fourcc(this, fieldName, val)) {
throw new InvalidFieldException("FOURCC", fieldName);
}
return val[0];
}
/**
* Gets FOURCC field String representation
*
* @param fieldName The name of the field.
* @return FOURCC field as a String
*/
public String getFourccString(String fieldName) {
int f = getFourcc(fieldName);
byte[] b = {(byte) ((f >> 0) & 0xff), (byte) ((f >> 8) & 0xff),
(byte) ((f >> 16) & 0xff), (byte) ((f >> 24) & 0xff)};
return new String(b);
}
/**
* Get the value of the named field as a Fraction. Throws
* {@link InvalidFieldException} if the Structure does not contain the named
* field or the named field is not a Fraction.
*
* @param fieldName name of field
* @return boolean value of the named field
*/
public Fraction getFraction(String fieldName) {
int[] numerator = {0};
int[] denominator = {0};
if (!GSTSTRUCTURE_API.gst_structure_get_fraction(this, fieldName, numerator, denominator)) {
throw new InvalidFieldException("fraction", fieldName);
}
return new Fraction(numerator[0], denominator[0]);
}
/**
* Get the value of the named field as an int. Throws
* {@link InvalidFieldException} if the Structure does not contain the named
* field or the named field is not an integer.
*
* @param fieldName name of field
* @return int value of the named field
*/
public int getInteger(String fieldName) {
int[] val = {0};
if (!GSTSTRUCTURE_API.gst_structure_get_int(this, fieldName, val)) {
throw new InvalidFieldException("integer", fieldName);
}
return val[0];
}
/**
* Extract the values of the named field as an array of integers. If the
* native GType of the field is a GValueArray then this method will return
* an array of the contained values, assuming all contained values are of
* G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will
* be returned.
*
* This method will create a new array each time. If you are repeatedly
* calling this method consider using
* {@link #getIntegers(java.lang.String, int[])}.
*
* Throws {@link InvalidFieldException} if the field does not exist, or the
* field values contained are not of type G_TYPE_INT.
*
* This method only currently supports lists of values inside a GValueArray
* - other native list types will be supported in future.
*
* @param fieldName name of field
* @return List of values from the named field
*/
public int[] getIntegers(String fieldName) {
return getIntegers(fieldName, null);
}
/**
* Extract the values of the named field as an array of integers. If the
* native GType of the field is a GValueArray then this method will return
* an array of the contained values, assuming all contained values are of
* G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will
* be returned.
*
* An array may be passed into this method to contain the result. A new
* array will be created if the array is null or not of the correct length.
*
* Throws {@link InvalidFieldException} if the field does not exist, or the
* field values contained are not of type G_TYPE_INT.
*
* This method only currently supports lists of values inside a GValueArray
* - other native list types will be supported in future.
*
* @param fieldName name of field
* @param array an array to hold values, or null
* @return List of values from the named field
*/
public int[] getIntegers(String fieldName, int[] array) {
Object val = getValue(fieldName);
if (val instanceof GValueAPI.GValueArray) {
GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val;
int count = arr.getNValues();
int[] values = array == null || array.length != count
? new int[count] : array;
for (int i = 0; i < count; i++) {
GValue gval = arr.nth(i);
if (gval.checkHolds(GType.INT)) {
values[i] = GValueAPI.GVALUE_API.g_value_get_int(gval);
} else {
throw new InvalidFieldException("integers", fieldName);
}
}
return values;
} else {
if (Integer.class.isInstance(val)) {
int[] values = array == null || array.length != 1
? new int[1] : array;
values[0] = ((Integer) val);
return values;
} else {
throw new InvalidFieldException("integer", fieldName);
}
}
}
/**
* Sets the name of the structure to the given name.
*
* The name must not be empty, must start with a letter and can be followed
* by letters, numbers and any of "/-_.:".
*
* @param name The new name of the structure.
*/
public void setName(String name) {
GSTSTRUCTURE_API.gst_structure_set_name(this, name);
}
/**
* Get the name of @structure as a string.
*
* @return The name of the structure.
*/
public String getName() {
return GSTSTRUCTURE_API.gst_structure_get_name(this);
}
/**
* Get the @structure's ith field name as a string.
*
* @param i the requested filed number
* @return The name of the structure.
*/
public String getName(int i) {
return GSTSTRUCTURE_API.gst_structure_nth_field_name(this, i);
}
/**
* Get the value of the named field as a Range. Throws
* {@link InvalidFieldException} if the Structure does not contain the named
* field.
*
* @param fieldName name of field
* @return Range value of the named field
*/
public Range getRange(String fieldName) {
GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName);
if (val == null) {
throw new InvalidFieldException("Range", fieldName);
}
return new Range(val);
}
/**
* Get the value of the named field as a String.
*
* @param fieldName name of field
* @return String value of the named field
*/
public String getString(String fieldName) {
return GSTSTRUCTURE_API.gst_structure_get_string(this, fieldName);
}
/**
* Get the value of the named field. Throws {@link InvalidFieldException} if
* the Structure does not contain the named field.
*
* @param fieldName name of field
* @return Object representation of the named field
*/
public Object getValue(String fieldName) {
GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName);
if (val == null) {
throw new InvalidFieldException("Object", fieldName);
}
return val.getValue();
}
/**
* Extract the values of the named field as a List of the provided type. If
* the native GType of the field is a GValueArray then this method will
* return a list of the contained values, assuming all contained values can
* be converted to the provided Java type T. Else if the field GType can be
* directly converted to the provided Java type T, a singleton List will be
* returned.
*
* Throws {@link InvalidFieldException} if the field does not exist, or the
* field values cannot be converted to type T.
*
* This method currently supports lists of values inside a GValueArray or
* GstValueList.
*
* @param
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagFlag
*
*/
public enum TagFlag implements NativeEnum
* See upstream documentation at
* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html
*
*/
//@TODO consider handling Sample fields.
public class TagList extends MiniObject {
public static final String GTYPE_NAME = "GstTagList";
/**
* Creates a new instance of TagList
*
* @param init internal initialization data.
*/
TagList(Initializer init) {
super(init);
}
/**
* Constructs a new empty tag list.
*/
public TagList() {
super(initializer());
}
private static Initializer initializer() {
final Pointer ptr_new_tag_list = GSTTAGLIST_API.ptr_gst_tag_list_new_empty();
return Natives.initializer(ptr_new_tag_list);
}
/**
* Gets the number of values of type {@code tag} stored in the list.
*
* @param tag the name of the tag to get the size of.
* @return the number of values for {@code tag} in this list.
*/
public int getValueCount(String tag) {
return GSTTAGLIST_API.gst_tag_list_get_tag_size(this, tag);
}
/**
* Gets all data values for a tag contained in this list.
*
* @param tag the name of the tag to retrieve.
* @return the data associated with {@code tag}.
*/
public Listelement-added signal on this Bin
*
* @param listener The listener to be called when an {@link Element} is
* added.
*/
public void connect(final ELEMENT_ADDED listener) {
connect(ELEMENT_ADDED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Bin bin, Element elem) {
listener.elementAdded(bin, elem);
}
});
}
/**
* Disconnect the listener for the element-added signal
*
* @param listener The listener that was registered to receive the signal.
*/
public void disconnect(ELEMENT_ADDED listener) {
disconnect(ELEMENT_ADDED.class, listener);
}
/**
* Signal emitted when an {@link Element} is removed from this Bin
*
* @see #connect(ELEMENT_REMOVED)
* @see #disconnect(ELEMENT_REMOVED)
*/
public static interface ELEMENT_REMOVED {
/**
* Called when an {@link Element} is removed from a {@link Bin}
*
* @param bin the Bin the element was removed from.
* @param element the {@link Element} that was removed.
*/
public void elementRemoved(Bin bin, Element element);
}
/**
* Add a listener for the element-removed signal on this Bin
*
* @param listener The listener to be called when an {@link Element} is
* removed.
*/
public void connect(final ELEMENT_REMOVED listener) {
connect(ELEMENT_REMOVED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Bin bin, Element elem) {
listener.elementRemoved(bin, elem);
}
});
}
/**
* Disconnect the listener for the element-removed signal
*
* @param listener The listener that was registered to receive the signal.
*/
public void disconnect(ELEMENT_REMOVED listener) {
disconnect(ELEMENT_REMOVED.class, listener);
}
/**
* Signal emitted when an {@link Element} is added to sub-bin of this
* {@link Bin}
*
* @see #connect(DEEP_ELEMENT_ADDED)
* @see #disconnect(DEEP_ELEMENT_ADDED)
*/
@Gst.Since(minor = 10)
public static interface DEEP_ELEMENT_ADDED {
/**
* Called when an {@link Element} is added to a {@link Bin}
*
* Since GStreamer 1.10
*
* @param bin the Bin
* @param sub_bin the Bin the element was added to.
* @param element the {@link Element} that was added.
*/
public void elementAdded(Bin bin, Bin sub_bin, Element element);
}
/**
* Add a listener for the deep-element-added signal on this Bin
*
* @param listener The listener to be called when an {@link Element} is
* added.
*/
@Gst.Since(minor = 10)
public void connect(final DEEP_ELEMENT_ADDED listener) {
Gst.checkVersion(1, 10);
connect(DEEP_ELEMENT_ADDED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Bin bin, Bin sub_bin, Element elem) {
listener.elementAdded(bin, sub_bin, elem);
}
});
}
/**
* Disconnect the listener for the deep-element-added signal
*
* @param listener The listener that was registered to receive the signal.
*/
@Gst.Since(minor = 10)
public void disconnect(DEEP_ELEMENT_ADDED listener) {
disconnect(DEEP_ELEMENT_ADDED.class, listener);
}
/**
* Signal emitted when an {@link Element} is removed from sub-bin of this
* {@link Bin}
*
* @see #connect(ELEMENT_REMOVED)
* @see #disconnect(ELEMENT_REMOVED)
*/
@Gst.Since(minor = 10)
public static interface DEEP_ELEMENT_REMOVED {
/**
* Called when an {@link Element} is removed from a {@link Bin}
*
* Since GStreamer 1.10
*
* @param bin the Bin
* @param sub_bin the Bin the element was removed from.
* @param element the {@link Element} that was removed.
*/
public void elementRemoved(Bin bin, Bin sub_bin, Element element);
}
/**
* Add a listener for the deep-element-removed signal on this
* Bin
*
* @param listener The listener to be called when an {@link Element} is
* removed.
*/
@Gst.Since(minor = 10)
public void connect(final DEEP_ELEMENT_REMOVED listener) {
Gst.checkVersion(1, 10);
connect(DEEP_ELEMENT_REMOVED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Bin bin, Bin sub_bin, Element elem) {
listener.elementRemoved(bin, sub_bin, elem);
}
});
}
/**
* Disconnect the listener for the deep-element-removed signal
*
* @param listener The listener that was registered to receive the signal.
*/
@Gst.Since(minor = 10)
public void disconnect(DEEP_ELEMENT_REMOVED listener) {
disconnect(DEEP_ELEMENT_REMOVED.class, listener);
}
/**
* Signal emitted when an {@link Element} has latency
*
* @see #connect(DO_LATENCY)
* @see #disconnect(DO_LATENCY)
*/
public static interface DO_LATENCY {
/**
* Called when an {@link Element} is removed from a {@link Bin}
*
* @param bin the Bin the element was removed from.
*/
public void doLatency(Bin bin);
}
/**
* Add a listener for the do-latency signal on this Bin
*
* @param listener The listener to be called when an {@link Element} is
* removed.
*/
public void connect(final DO_LATENCY listener) {
connect(DO_LATENCY.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Bin bin) {
listener.doLatency(bin);
}
});
}
/**
* Disconnect the listener for the do-latency signal
*
* @param listener The listener that was registered to receive the signal.
*/
public void disconnect(DO_LATENCY listener) {
disconnect(DO_LATENCY.class, listener);
}
/**
* Available details for pipeline graphs produced by
* {@link #debugToDotFile(java.util.EnumSet, java.lang.String)}
*/
public static enum DebugGraphDetails implements NativeFlags
* Caps caps = Caps.fromString("video/x-raw-rgb, bpp=32, depth=24, width=640, height=480");
*
*
* Caps caps = Caps.fromString("video/x-raw, format=RGB, bpp=32, depth=24, width=640, height=480");
*
*
* @param caps The string representation of the caps.
* @return The new Caps.
*/
public static Caps fromString(String caps) {
return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps)));
}
/**
* Merge two {@link Caps} together.
*
* time = (internal_time - internal) * rateNumerator/ rateDenominator + external
*
*
*
* pad-added signal
*
* @param listener Listener to be called when a {@link Pad} is added to the
* element.
*/
public void connect(final PAD_ADDED listener) {
connect(PAD_ADDED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Element elem, Pad pad) {
listener.padAdded(elem, pad);
}
});
}
/**
* Remove a listener for the pad-added signal
*
* @param listener The listener that was previously added.
*/
public void disconnect(PAD_ADDED listener) {
disconnect(PAD_ADDED.class, listener);
}
/**
* Add a listener for the pad-added signal
*
* @param listener Listener to be called when a {@link Pad} is removed from
* the element.
*/
public void connect(final PAD_REMOVED listener) {
connect(PAD_REMOVED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Element elem, Pad pad) {
listener.padRemoved(elem, pad);
}
});
}
/**
* Remove a listener for the pad-removed signal
*
* @param listener The listener that was previously added.
*/
public void disconnect(PAD_REMOVED listener) {
disconnect(PAD_REMOVED.class, listener);
}
/**
* Add a listener for the no-more-pads signal
*
* @param listener Listener to be called when the element has finished
* generating dynamic pads.
*/
public void connect(final NO_MORE_PADS listener) {
connect(NO_MORE_PADS.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public void callback(Element elem) {
listener.noMorePads(elem);
}
});
}
/**
* Remove a listener for the no-more-pads signal
*
* @param listener The listener that was previously added.
*/
public void disconnect(NO_MORE_PADS listener) {
disconnect(NO_MORE_PADS.class, listener);
}
/**
* Link together a list of elements.
* double, or Double.NaN if the denominator is 0
*/
public double toDouble() {
return denominator != 0 ? ((double) numerator / denominator) : Double.NaN;
}
}
================================================
FILE: src/org/freedesktop/gstreamer/GhostPad.java
================================================
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2009 Levente Farkas
* Copyright (C) 2007 Wayne Meissner
* Copyright (C) 1999,2000 Erik Walthinsen GstException without detail message.
*/
public GstException() {
}
/**
* Constructs an instance of GstException with the specified detail message.
*
* @param msg the detail message.
*/
public GstException(String msg) {
super(msg);
}
public GstException(GError error) {
super(error);
}
}
================================================
FILE: src/org/freedesktop/gstreamer/GstIterator.java
================================================
/*
* Copyright (c) 2021 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 gst_value_deserialize.
*
* @param property the property to set
* @param data the value as a valid String representation
* @throws IllegalArgumentException if the data cannot be deserialized to
* the required type.
*/
public void setAsString(String property, String data) {
GObjectAPI.GParamSpec propertySpec = findProperty(property);
if (propertySpec == null) {
throw new IllegalArgumentException("Unknown property: " + property);
}
final GType propType = propertySpec.value_type;
GValue propValue = new GValue();
GVALUE_API.g_value_init(propValue, propType);
boolean success = GSTVALUE_API.gst_value_deserialize(propValue, data);
if (success) {
GOBJECT_API.g_param_value_validate(propertySpec, propValue);
GOBJECT_API.g_object_set_property(this, property, propValue);
}
GVALUE_API.g_value_unset(propValue); // Release any memory
if (!success) {
throw new IllegalArgumentException(
"Unable to deserialize data to required type: "
+ propType.getTypeName());
}
}
/**
* Get the value of a GstObject property as a serialized String
* representation of its value.
* gst_value_serialize.
*
* @param property the property to get
* @return serialized String value of property
*/
public String getAsString(String property) {
GObjectAPI.GParamSpec propertySpec = findProperty(property);
if (propertySpec == null) {
throw new IllegalArgumentException("Unknown property: " + property);
}
final GType propType = propertySpec.value_type;
GValue propValue = new GValue();
GVALUE_API.g_value_init(propValue, propType);
GOBJECT_API.g_object_get_property(this, property, propValue);
Pointer ptr = GSTVALUE_API.gst_value_serialize(propValue);
String ret = ptr.getString(0);
GLIB_API.g_free(ptr);
return ret;
}
private GObjectAPI.GParamSpec findProperty(String propertyName) {
Pointer ptr = GOBJECT_API.g_object_class_find_property(
getRawPointer().getPointer(0), propertyName);
if (ptr == null) {
return null;
}
return new GObjectAPI.GParamSpec(ptr);
}
/**
* Sets the name of this object, or gives this object a guaranteed unique
* name (if name is null).
*
* Returns: TRUE if the name could be set. Since Objects that have a parent
* cannot be renamed, this function returns FALSE in those cases.
*
* MT safe.
*
* @param name new name of object
* @return true if the name was set. Since Objects that have a parent cannot
* be renamed, this function returns false in those cases.
*/
public boolean setName(String name) {
LOG.entering("GstObject", "setName", name);
return GSTOBJECT_API.gst_object_set_name(this, name);
}
/**
* Returns a copy of the name of this object.
*
* For a nameless object, this returns null.
*
* @return the name of this object.
*/
public String getName() {
LOG.entering("GstObject", "getName");
return GSTOBJECT_API.gst_object_get_name(this);
}
/**
* Returns this object's parent, if there is one.
*
* @return parent or null
*/
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.
* linked signal on this {@link Pad}
*
* @param listener The listener to be called when a peer {@link Pad} is
* linked.
*/
public void connect(final LINKED listener) {
connect(LINKED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public boolean callback(Pad pad, Pad peer) {
listener.linked(pad, peer);
return true;
}
});
}
/**
* Remove a listener for the linked signal on this {@link Pad}
*
* @param listener The listener previously added for this signal.
*/
public void disconnect(LINKED listener) {
disconnect(LINKED.class, listener);
}
/**
* Add a listener for the unlinked signal on this {@link Pad}
*
* @param listener The listener to be called when when a peer {@link Pad} is
* unlinked.
*/
public void connect(final UNLINKED listener) {
connect(UNLINKED.class, listener, new GstCallback() {
@SuppressWarnings("unused")
public boolean callback(Pad pad, Pad peer) {
listener.unlinked(pad, peer);
return true;
}
});
}
/**
* Remove a listener for the unlinked signal on this
* {@link Pad}
*
* @param listener The listener previously added for this signal.
*/
public void disconnect(UNLINKED listener) {
disconnect(UNLINKED.class, listener);
}
/**
* Be notified of different states of pads. The provided callback is called
* for every state that matches mask.
* gst_plugin_desc that is a struct
* of type GstPluginDesc. the plugin loader will check the version of the core
* library the plugin was linked against and will create a new Plugin. It will
* then call the #GstPluginInitFunc function that was provided in the
*
*
*