Skip to content

Commit

Permalink
Merge pull request #237 from codelerity/minor-api-14
Browse files Browse the repository at this point in the history
Minor API additions for 1.4.
  • Loading branch information
neilcsmith-net authored Jan 11, 2021
2 parents 9c50f74 + df7001a commit 8dc16d7
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 54 deletions.
130 changes: 119 additions & 11 deletions src/org/freedesktop/gstreamer/Element.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021 Neil C Smith
* Copyright (c) 2019 Christophe Lafolet
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2009 Levente Farkas
* Copyright (C) 2007 Wayne Meissner
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
Expand All @@ -22,17 +22,21 @@
*/
package org.freedesktop.gstreamer;

import org.freedesktop.gstreamer.query.Query;
import org.freedesktop.gstreamer.message.Message;
import org.freedesktop.gstreamer.event.Event;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.freedesktop.gstreamer.event.Event;
import org.freedesktop.gstreamer.event.SeekEvent;
import org.freedesktop.gstreamer.event.SeekFlags;
import org.freedesktop.gstreamer.event.SeekType;
import org.freedesktop.gstreamer.glib.NativeFlags;
import org.freedesktop.gstreamer.glib.Natives;

import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;
import org.freedesktop.gstreamer.lowlevel.GstContextPtr;
import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
import org.freedesktop.gstreamer.message.Message;
import org.freedesktop.gstreamer.query.Query;

import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;
import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;
Expand All @@ -41,8 +45,8 @@
* Abstract base class for all pipeline elements.
* <p>
* See upstream documentation at
* <a href="https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html"
* >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html</a>
* <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html"
* >https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html</a>
* <p>
* 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
Expand Down Expand Up @@ -185,28 +189,44 @@ public boolean isPlaying() {
}

/**
* Tells the Element to start playing the media stream.
* 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.
* 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.
* 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 pause playing the media stream.
* Tells the Element to pause 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);
Expand Down Expand Up @@ -784,6 +804,94 @@ public Context getContext(String 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.
* <p>
* 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<SeekFlags> seekFlags,
SeekType startType, long start, SeekType stopType, long stop) {

return GSTELEMENT_API.gst_element_seek(this, rate, format,
NativeFlags.toInt(seekFlags), startType, start, stopType, stop);
}

/**
* Simple API to perform a seek on the given element, meaning it just seeks
* to the given position relative to the start of the stream. For more
* complex operations like segment seeks (e.g. for looping) or changing the
* playback rate or seeking relative to the last configured playback segment
* you should use
* {@link #seek(double, org.freedesktop.gstreamer.Format, java.util.Set, org.freedesktop.gstreamer.event.SeekType, long, org.freedesktop.gstreamer.event.SeekType, long)}.
* <p>
* 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).
* <p>
* 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<SeekFlags> seekFlags, long seekPosition) {
return GSTELEMENT_API.gst_element_seek_simple(this, format,
NativeFlags.toInt(seekFlags), seekPosition);
}

static class Handle extends GstObject.Handle {

public Handle(GstObjectPtr ptr, boolean ownsHandle) {
Expand Down
63 changes: 30 additions & 33 deletions src/org/freedesktop/gstreamer/Pipeline.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2021 Neil C Smith
* Copyright (c) 2008 Wayne Meissner
* Copyright (C) 2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2005 Wim Taymans <wim@fluendo.com>
Expand All @@ -20,23 +20,21 @@
*/
package org.freedesktop.gstreamer;

import org.freedesktop.gstreamer.event.SeekType;
import org.freedesktop.gstreamer.event.SeekFlags;
import org.freedesktop.gstreamer.query.Query;
import java.util.concurrent.TimeUnit;

import com.sun.jna.Pointer;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;

import org.freedesktop.gstreamer.event.SeekFlags;
import org.freedesktop.gstreamer.event.SeekType;
import org.freedesktop.gstreamer.glib.Natives;
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
import org.freedesktop.gstreamer.query.Query;

import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;
import static org.freedesktop.gstreamer.lowlevel.GstPipelineAPI.GSTPIPELINE_API;
import static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API;
import org.freedesktop.gstreamer.glib.NativeFlags;
import org.freedesktop.gstreamer.glib.Natives;
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;

/**
* A {@code Pipeline} is a special {@link Bin} used as the top level container
Expand Down Expand Up @@ -217,6 +215,9 @@ public Bus getBus() {

/**
* Sets the position in the media stream to time in nanoseconds.
* <p>
* 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
Expand All @@ -228,6 +229,9 @@ public boolean seek(long time) {

/**
* Sets the current position in the media stream.
* <p>
* 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.
Expand All @@ -253,10 +257,11 @@ public boolean seek(long time, TimeUnit unit) {
* 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.
* <p>
* <ttstartType and stopType specify how to adjust the currently configured
* 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. <p>
* means that the position should not be updated.
* <p>
* When the rate is positive and start has been updated, playback will start
* from the newly configured start position.
* <p>
Expand All @@ -279,13 +284,18 @@ public boolean seek(long time, TimeUnit unit) {
* @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<SeekFlags> seekFlags,
SeekType startType, long start, SeekType stopType, long stop) {

return GSTELEMENT_API.gst_element_seek(this, rate, format, NativeFlags.toInt(seekFlags),
startType, start, stopType, stop);
return super.seek(rate, format, seekFlags, startType, start, stopType, stop);
}


@Override
public boolean seek(double rate, Format format, Set<SeekFlags> seekFlags,
SeekType startType, long start, SeekType stopType, long stop) {
return super.seek(rate, format, seekFlags, startType, start, stopType, stop);
}

/**
* Gets the current position in the media stream.
*
Expand All @@ -296,15 +306,9 @@ public long queryPosition(TimeUnit unit) {
return unit.convert(queryPosition(Format.TIME), TimeUnit.NANOSECONDS);
}

/**
* Gets the current position in terms of the specified {@link Format}.
*
* @param format The {@link Format} to return the position in.
* @return The current position or -1 if the query failed.
*/
@Override
public long queryPosition(Format format) {
long[] pos = {0};
return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L;
return super.queryPosition(format);
}

/**
Expand All @@ -317,16 +321,9 @@ public long queryDuration(TimeUnit unit) {
return unit.convert(queryDuration(Format.TIME), TimeUnit.NANOSECONDS);
}

/**
* Gets the duration of the current media stream in terms of the specified
* {@link Format}.
*
* @param format the {@code Format} to return the duration in.
* @return The total duration of the current media stream.
*/
@Override
public long queryDuration(Format format) {
long[] dur = {0};
return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L;
return super.queryDuration(format);
}

/**
Expand Down
36 changes: 30 additions & 6 deletions src/org/freedesktop/gstreamer/Version.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Neil C Smith
* Copyright (c) 2021 Neil C Smith
* Copyright (c) 2008 Wayne Meissner
*
* This file is part of gstreamer-java.
Expand All @@ -22,8 +22,8 @@
* Describes a GStreamer version.
* <p>
* Also upstream documentation at
* <a href="https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstVersion.html"
* >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstVersion.html</a>
* <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version"
* >https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version</a>
* <p>
*/
public class Version {
Expand All @@ -37,9 +37,9 @@ public class Version {
private final int major, minor, micro, nano;

/**
* Constructor for creating a Version with micro and nano set to zero - most
* useful for requesting version in {@link Gst#init(org.freedesktop.gstreamer.Version)
* }
* Constructor for creating a Version with micro and nano set to zero. For
* requesting version in {@link Gst#init(org.freedesktop.gstreamer.Version)}
* prefer using {@link #of(int, int)}.
* <p>
* <b>The library only supports major version 1</b>
*
Expand Down Expand Up @@ -130,4 +130,28 @@ public boolean checkSatisfies(Version required) {
|| (major == required.major && minor == required.minor && micro >= required.micro);
}

/**
* Create a Version with specified major and minor version, and micro and
* nano version set to zero. Useful for specifying a required version in
* {@link Gst#init(org.freedesktop.gstreamer.Version)}.
* <p>
* <b>The library only supports major version 1</b>
* <p>
* Unlike the constructor this method will throw an exception if the version
* is not greater or equal to {@link #BASELINE}, or the major version isn't
* 1.
*
* @param major major version, currently must be 1
* @param minor minor version, greater or equal to 8
* @return requested version
* @throws IllegalArgumentException if the requested version is invalid
*/
public static Version of(int major, int minor) {
if (major == BASELINE.getMajor()
&& minor >= BASELINE.getMinor()) {
return new Version(major, minor);
}
throw new IllegalArgumentException("Invalid version");
}

}
6 changes: 3 additions & 3 deletions src/org/freedesktop/gstreamer/lowlevel/GstElementAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public interface GstElementAPI extends com.sun.jna.Library {
boolean gst_element_query_position(Element elem, Format fmt, long[] pos);
boolean gst_element_query_duration(Element elem, Format fmt, long[] pos);
boolean gst_element_query(Element elem, Query query);
boolean gst_element_seek(Element elem, double rate, Format format, int flags,
SeekType cur_type, long cur, SeekType stop_type, long stop);
boolean gst_element_seek_simple(Element elem, Format format, int flags, long pos);
boolean gst_element_seek(Element element, double rate, Format format, int flags,
SeekType start_type, long start, SeekType stop_type, long stop);
boolean gst_element_seek_simple(Element elem, Format format, int seek_flags, long seek_pos);
boolean gst_element_link(Element elem1, Element elem2);
boolean gst_element_link_filtered(Element elem1, Element elem2, Caps filter);
boolean gst_element_link_many(Element... elements);
Expand Down
Loading

0 comments on commit 8dc16d7

Please sign in to comment.