Skip to content

Commit 8dc16d7

Browse files
Merge pull request #237 from codelerity/minor-api-14
Minor API additions for 1.4.
2 parents 9c50f74 + df7001a commit 8dc16d7

File tree

5 files changed

+183
-54
lines changed

5 files changed

+183
-54
lines changed

src/org/freedesktop/gstreamer/Element.java

Lines changed: 119 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2+
* Copyright (c) 2021 Neil C Smith
23
* Copyright (c) 2019 Christophe Lafolet
3-
* Copyright (c) 2019 Neil C Smith
44
* Copyright (c) 2009 Levente Farkas
55
* Copyright (C) 2007 Wayne Meissner
66
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
@@ -22,17 +22,21 @@
2222
*/
2323
package org.freedesktop.gstreamer;
2424

25-
import org.freedesktop.gstreamer.query.Query;
26-
import org.freedesktop.gstreamer.message.Message;
27-
import org.freedesktop.gstreamer.event.Event;
2825
import java.util.List;
26+
import java.util.Set;
2927
import java.util.concurrent.TimeUnit;
28+
import org.freedesktop.gstreamer.event.Event;
29+
import org.freedesktop.gstreamer.event.SeekEvent;
30+
import org.freedesktop.gstreamer.event.SeekFlags;
31+
import org.freedesktop.gstreamer.event.SeekType;
32+
import org.freedesktop.gstreamer.glib.NativeFlags;
3033
import org.freedesktop.gstreamer.glib.Natives;
31-
3234
import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;
3335
import org.freedesktop.gstreamer.lowlevel.GstContextPtr;
3436
import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;
3537
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
38+
import org.freedesktop.gstreamer.message.Message;
39+
import org.freedesktop.gstreamer.query.Query;
3640

3741
import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;
3842
import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;
@@ -41,8 +45,8 @@
4145
* Abstract base class for all pipeline elements.
4246
* <p>
4347
* See upstream documentation at
44-
* <a href="https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html"
45-
* >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html</a>
48+
* <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html"
49+
* >https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html</a>
4650
* <p>
4751
* Element is the abstract base class needed to construct an element that can be
4852
* used in a GStreamer pipeline. Please refer to the plugin writers guide for
@@ -185,28 +189,44 @@ public boolean isPlaying() {
185189
}
186190

187191
/**
188-
* Tells the Element to start playing the media stream.
192+
* Tells the Element to start playing the media stream. Equivalent to
193+
* calling {@link #setState(org.freedesktop.gstreamer.State)} with
194+
* {@link State#PLAYING}.
195+
*
196+
* @return the status of the element's state change.
189197
*/
190198
public StateChangeReturn play() {
191199
return setState(State.PLAYING);
192200
}
193201

194202
/**
195-
* Tells the Element to set ready the media stream.
203+
* Tells the Element to set ready the media stream. Equivalent to calling
204+
* {@link #setState(org.freedesktop.gstreamer.State)} with
205+
* {@link State#READY}.
206+
*
207+
* @return the status of the element's state change.
196208
*/
197209
public StateChangeReturn ready() {
198210
return setState(State.READY);
199211
}
200212

201213
/**
202-
* Tells the Element to pause playing the media stream.
214+
* Tells the Element to pause playing the media stream. Equivalent to
215+
* calling {@link #setState(org.freedesktop.gstreamer.State)} with
216+
* {@link State#PAUSED}.
217+
*
218+
* @return the status of the element's state change.
203219
*/
204220
public StateChangeReturn pause() {
205221
return setState(State.PAUSED);
206222
}
207223

208224
/**
209-
* Tells the Element to pause playing the media stream.
225+
* Tells the Element to pause playing the media stream. Equivalent to
226+
* calling {@link #setState(org.freedesktop.gstreamer.State)} with
227+
* {@link State#NULL}.
228+
*
229+
* @return the status of the element's state change.
210230
*/
211231
public StateChangeReturn stop() {
212232
return setState(State.NULL);
@@ -784,6 +804,94 @@ public Context getContext(String context_type) {
784804
return gstContextPtr != null ? Natives.callerOwnsReturn(gstContextPtr, Context.class) : null;
785805
}
786806

807+
/**
808+
* Queries an element (usually top-level pipeline or playbin element) for
809+
* the total stream duration in nanoseconds. This query will only work once
810+
* the pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The
811+
* application will receive an ASYNC_DONE message on the pipeline bus when
812+
* that is the case.
813+
* <p>
814+
* If the duration changes for some reason, you will get a DURATION_CHANGED
815+
* message on the pipeline bus, in which case you should re-query the
816+
* duration using this function.
817+
*
818+
* @param format the {@code Format} to return the duration in
819+
* @return the total duration of the current media stream, or -1 if the
820+
* query failed
821+
*/
822+
public long queryDuration(Format format) {
823+
long[] dur = {0};
824+
return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L;
825+
}
826+
827+
/**
828+
* Queries an element (usually top-level pipeline or playbin element) for
829+
* the stream position in nanoseconds. This will be a value between 0 and
830+
* the stream duration (if the stream duration is known). This query will
831+
* usually only work once the pipeline is prerolled (i.e. reached PAUSED or
832+
* PLAYING state). The application will receive an ASYNC_DONE message on the
833+
* pipeline bus when that is the case.
834+
*
835+
* @param format The {@link Format} to return the position in
836+
* @return the current position or -1 if the query failed.
837+
*/
838+
public long queryPosition(Format format) {
839+
long[] pos = {0};
840+
return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L;
841+
}
842+
843+
/**
844+
* Sends a seek event to an element. See {@link SeekEvent} for the details
845+
* of the parameters. The seek event is sent to the element using the native
846+
* equivalent of {@link #sendEvent(org.freedesktop.gstreamer.event.Event)}.
847+
*
848+
* @param rate the new playback rate
849+
* @param format the format of the seek values
850+
* @param seekFlags the seek flags
851+
* @param startType the type and flags for the new start position
852+
* @param start the value of the new start position
853+
* @param stopType the type and flags for the new stop position
854+
* @param stop the value of the new stop position
855+
* @return true if seek operation succeeded. Flushing seeks will trigger a
856+
* preroll, which will emit an ASYNC_DONE message
857+
*/
858+
public boolean seek(double rate, Format format, Set<SeekFlags> seekFlags,
859+
SeekType startType, long start, SeekType stopType, long stop) {
860+
861+
return GSTELEMENT_API.gst_element_seek(this, rate, format,
862+
NativeFlags.toInt(seekFlags), startType, start, stopType, stop);
863+
}
864+
865+
/**
866+
* Simple API to perform a seek on the given element, meaning it just seeks
867+
* to the given position relative to the start of the stream. For more
868+
* complex operations like segment seeks (e.g. for looping) or changing the
869+
* playback rate or seeking relative to the last configured playback segment
870+
* you should use
871+
* {@link #seek(double, org.freedesktop.gstreamer.Format, java.util.Set, org.freedesktop.gstreamer.event.SeekType, long, org.freedesktop.gstreamer.event.SeekType, long)}.
872+
* <p>
873+
* In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
874+
* guaranteed to return TRUE on a seekable media type or FALSE when the
875+
* media type is certainly not seekable (such as a live stream).
876+
* <p>
877+
* Some elements allow for seeking in the READY state, in this case they
878+
* will store the seek event and execute it when they are put to PAUSED. If
879+
* the element supports seek in READY, it will always return TRUE when it
880+
* receives the event in the READY state.
881+
*
882+
* @param format a {@link Format} to seek in, such as {@link Format#TIME}
883+
* @param seekFlags seek options; playback applications will usually want to
884+
* use {@link SeekFlags#FLUSH} and {@link SeekFlags#KEY_UNIT} here
885+
* @param seekPosition position to seek to (relative to the start); if you
886+
* are doing a seek in format TIME this value is in nanoseconds
887+
* @return true if seek operation succeeded. Flushing seeks will trigger a
888+
* preroll, which will emit an ASYNC_DONE message
889+
*/
890+
public boolean seekSimple(Format format, Set<SeekFlags> seekFlags, long seekPosition) {
891+
return GSTELEMENT_API.gst_element_seek_simple(this, format,
892+
NativeFlags.toInt(seekFlags), seekPosition);
893+
}
894+
787895
static class Handle extends GstObject.Handle {
788896

789897
public Handle(GstObjectPtr ptr, boolean ownsHandle) {

src/org/freedesktop/gstreamer/Pipeline.java

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019 Neil C Smith
2+
* Copyright (c) 2021 Neil C Smith
33
* Copyright (c) 2008 Wayne Meissner
44
* Copyright (C) 2000 Erik Walthinsen <omega@cse.ogi.edu>
55
* 2005 Wim Taymans <wim@fluendo.com>
@@ -20,23 +20,21 @@
2020
*/
2121
package org.freedesktop.gstreamer;
2222

23-
import org.freedesktop.gstreamer.event.SeekType;
24-
import org.freedesktop.gstreamer.event.SeekFlags;
25-
import org.freedesktop.gstreamer.query.Query;
26-
import java.util.concurrent.TimeUnit;
27-
2823
import com.sun.jna.Pointer;
2924
import java.util.EnumSet;
25+
import java.util.Set;
26+
import java.util.concurrent.TimeUnit;
3027
import java.util.concurrent.atomic.AtomicReference;
3128
import java.util.logging.Logger;
32-
29+
import org.freedesktop.gstreamer.event.SeekFlags;
30+
import org.freedesktop.gstreamer.event.SeekType;
31+
import org.freedesktop.gstreamer.glib.Natives;
32+
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
33+
import org.freedesktop.gstreamer.query.Query;
3334

3435
import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;
3536
import static org.freedesktop.gstreamer.lowlevel.GstPipelineAPI.GSTPIPELINE_API;
3637
import static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API;
37-
import org.freedesktop.gstreamer.glib.NativeFlags;
38-
import org.freedesktop.gstreamer.glib.Natives;
39-
import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
4038

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

218216
/**
219217
* Sets the position in the media stream to time in nanoseconds.
218+
* <p>
219+
* Prefer use of
220+
* {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.
220221
*
221222
* @param time The time to change the position to.
222223
* @return true if seek is successful
@@ -228,6 +229,9 @@ public boolean seek(long time) {
228229

229230
/**
230231
* Sets the current position in the media stream.
232+
* <p>
233+
* Prefer use of
234+
* {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.
231235
*
232236
* @param time the time to change the position to.
233237
* @param unit the {@code TimeUnit} the time is expressed in.
@@ -253,10 +257,11 @@ public boolean seek(long time, TimeUnit unit) {
253257
* position of 0, a stop position of -1 and a rate of 1.0. The currently
254258
* configured playback segment can be queried with #GST_QUERY_SEGMENT.
255259
* <p>
256-
* <ttstartType and stopType specify how to adjust the currently configured
260+
* startType and stopType specify how to adjust the currently configured
257261
* start and stop fields in segment. Adjustments can be made relative or
258262
* absolute to the last configured values. A type of {@link SeekType#NONE}
259-
* means that the position should not be updated. <p>
263+
* means that the position should not be updated.
264+
* <p>
260265
* When the rate is positive and start has been updated, playback will start
261266
* from the newly configured start position.
262267
* <p>
@@ -279,13 +284,18 @@ public boolean seek(long time, TimeUnit unit) {
279284
* @param stop the value of the new stop position
280285
* @return true if seek is successful
281286
*/
287+
// for compatibility
282288
public boolean seek(double rate, Format format, EnumSet<SeekFlags> seekFlags,
283289
SeekType startType, long start, SeekType stopType, long stop) {
284-
285-
return GSTELEMENT_API.gst_element_seek(this, rate, format, NativeFlags.toInt(seekFlags),
286-
startType, start, stopType, stop);
290+
return super.seek(rate, format, seekFlags, startType, start, stopType, stop);
287291
}
288-
292+
293+
@Override
294+
public boolean seek(double rate, Format format, Set<SeekFlags> seekFlags,
295+
SeekType startType, long start, SeekType stopType, long stop) {
296+
return super.seek(rate, format, seekFlags, startType, start, stopType, stop);
297+
}
298+
289299
/**
290300
* Gets the current position in the media stream.
291301
*
@@ -296,15 +306,9 @@ public long queryPosition(TimeUnit unit) {
296306
return unit.convert(queryPosition(Format.TIME), TimeUnit.NANOSECONDS);
297307
}
298308

299-
/**
300-
* Gets the current position in terms of the specified {@link Format}.
301-
*
302-
* @param format The {@link Format} to return the position in.
303-
* @return The current position or -1 if the query failed.
304-
*/
309+
@Override
305310
public long queryPosition(Format format) {
306-
long[] pos = {0};
307-
return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L;
311+
return super.queryPosition(format);
308312
}
309313

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

320-
/**
321-
* Gets the duration of the current media stream in terms of the specified
322-
* {@link Format}.
323-
*
324-
* @param format the {@code Format} to return the duration in.
325-
* @return The total duration of the current media stream.
326-
*/
324+
@Override
327325
public long queryDuration(Format format) {
328-
long[] dur = {0};
329-
return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L;
326+
return super.queryDuration(format);
330327
}
331328

332329
/**

src/org/freedesktop/gstreamer/Version.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019 Neil C Smith
2+
* Copyright (c) 2021 Neil C Smith
33
* Copyright (c) 2008 Wayne Meissner
44
*
55
* This file is part of gstreamer-java.
@@ -22,8 +22,8 @@
2222
* Describes a GStreamer version.
2323
* <p>
2424
* Also upstream documentation at
25-
* <a href="https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstVersion.html"
26-
* >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstVersion.html</a>
25+
* <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version"
26+
* >https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version</a>
2727
* <p>
2828
*/
2929
public class Version {
@@ -37,9 +37,9 @@ public class Version {
3737
private final int major, minor, micro, nano;
3838

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

133+
/**
134+
* Create a Version with specified major and minor version, and micro and
135+
* nano version set to zero. Useful for specifying a required version in
136+
* {@link Gst#init(org.freedesktop.gstreamer.Version)}.
137+
* <p>
138+
* <b>The library only supports major version 1</b>
139+
* <p>
140+
* Unlike the constructor this method will throw an exception if the version
141+
* is not greater or equal to {@link #BASELINE}, or the major version isn't
142+
* 1.
143+
*
144+
* @param major major version, currently must be 1
145+
* @param minor minor version, greater or equal to 8
146+
* @return requested version
147+
* @throws IllegalArgumentException if the requested version is invalid
148+
*/
149+
public static Version of(int major, int minor) {
150+
if (major == BASELINE.getMajor()
151+
&& minor >= BASELINE.getMinor()) {
152+
return new Version(major, minor);
153+
}
154+
throw new IllegalArgumentException("Invalid version");
155+
}
156+
133157
}

src/org/freedesktop/gstreamer/lowlevel/GstElementAPI.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ public interface GstElementAPI extends com.sun.jna.Library {
6464
boolean gst_element_query_position(Element elem, Format fmt, long[] pos);
6565
boolean gst_element_query_duration(Element elem, Format fmt, long[] pos);
6666
boolean gst_element_query(Element elem, Query query);
67-
boolean gst_element_seek(Element elem, double rate, Format format, int flags,
68-
SeekType cur_type, long cur, SeekType stop_type, long stop);
69-
boolean gst_element_seek_simple(Element elem, Format format, int flags, long pos);
67+
boolean gst_element_seek(Element element, double rate, Format format, int flags,
68+
SeekType start_type, long start, SeekType stop_type, long stop);
69+
boolean gst_element_seek_simple(Element elem, Format format, int seek_flags, long seek_pos);
7070
boolean gst_element_link(Element elem1, Element elem2);
7171
boolean gst_element_link_filtered(Element elem1, Element elem2, Caps filter);
7272
boolean gst_element_link_many(Element... elements);

0 commit comments

Comments
 (0)