|
1 | 1 | /*
|
| 2 | + * Copyright (c) 2021 Neil C Smith |
2 | 3 | * Copyright (c) 2019 Christophe Lafolet
|
3 |
| - * Copyright (c) 2019 Neil C Smith |
4 | 4 | * Copyright (c) 2009 Levente Farkas
|
5 | 5 | * Copyright (C) 2007 Wayne Meissner
|
6 | 6 | * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
|
|
22 | 22 | */
|
23 | 23 | package org.freedesktop.gstreamer;
|
24 | 24 |
|
25 |
| -import org.freedesktop.gstreamer.query.Query; |
26 |
| -import org.freedesktop.gstreamer.message.Message; |
27 |
| -import org.freedesktop.gstreamer.event.Event; |
28 | 25 | import java.util.List;
|
| 26 | +import java.util.Set; |
29 | 27 | 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; |
30 | 33 | import org.freedesktop.gstreamer.glib.Natives;
|
31 |
| - |
32 | 34 | import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;
|
33 | 35 | import org.freedesktop.gstreamer.lowlevel.GstContextPtr;
|
34 | 36 | import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;
|
35 | 37 | import org.freedesktop.gstreamer.lowlevel.GstObjectPtr;
|
| 38 | +import org.freedesktop.gstreamer.message.Message; |
| 39 | +import org.freedesktop.gstreamer.query.Query; |
36 | 40 |
|
37 | 41 | import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;
|
38 | 42 | import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;
|
|
41 | 45 | * Abstract base class for all pipeline elements.
|
42 | 46 | * <p>
|
43 | 47 | * 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> |
46 | 50 | * <p>
|
47 | 51 | * Element is the abstract base class needed to construct an element that can be
|
48 | 52 | * used in a GStreamer pipeline. Please refer to the plugin writers guide for
|
@@ -185,28 +189,44 @@ public boolean isPlaying() {
|
185 | 189 | }
|
186 | 190 |
|
187 | 191 | /**
|
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. |
189 | 197 | */
|
190 | 198 | public StateChangeReturn play() {
|
191 | 199 | return setState(State.PLAYING);
|
192 | 200 | }
|
193 | 201 |
|
194 | 202 | /**
|
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. |
196 | 208 | */
|
197 | 209 | public StateChangeReturn ready() {
|
198 | 210 | return setState(State.READY);
|
199 | 211 | }
|
200 | 212 |
|
201 | 213 | /**
|
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. |
203 | 219 | */
|
204 | 220 | public StateChangeReturn pause() {
|
205 | 221 | return setState(State.PAUSED);
|
206 | 222 | }
|
207 | 223 |
|
208 | 224 | /**
|
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. |
210 | 230 | */
|
211 | 231 | public StateChangeReturn stop() {
|
212 | 232 | return setState(State.NULL);
|
@@ -784,6 +804,94 @@ public Context getContext(String context_type) {
|
784 | 804 | return gstContextPtr != null ? Natives.callerOwnsReturn(gstContextPtr, Context.class) : null;
|
785 | 805 | }
|
786 | 806 |
|
| 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 | + |
787 | 895 | static class Handle extends GstObject.Handle {
|
788 | 896 |
|
789 | 897 | public Handle(GstObjectPtr ptr, boolean ownsHandle) {
|
|
0 commit comments