JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLMediaPlayer.java
Go to the documentation of this file.
1/**
2 * Copyright 2012-2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.util.av;
29
30import com.jogamp.opengl.GL;
31import com.jogamp.opengl.GLEventListener;
32import com.jogamp.opengl.GLException;
33
34import jogamp.opengl.Debug;
35
36import java.io.PrintStream;
37import java.util.List;
38
39import com.jogamp.common.av.AudioSink;
40import com.jogamp.common.av.PTS;
41import com.jogamp.common.av.TimeFrameI;
42import com.jogamp.common.net.Uri;
43import com.jogamp.math.Vec4f;
44import com.jogamp.opengl.util.texture.Texture;
45import com.jogamp.opengl.util.texture.TextureSequence;
46
47/**
48 * GLMediaPlayer interface specifies a {@link TextureSequence} state machine
49 * using a multiplexed audio/video stream as it's source.
50 * <p>
51 * Audio maybe supported and played back internally or via an {@link AudioSink} implementation.
52 * </p>
53 * <p>
54 * Audio and video streams can be selected or muted via {@link #playStream(Uri, int, int, int, int)}
55 * or {@link #playStream(Uri, int, String, int, String, int, int)}
56 * using the appropriate <a href="#streamIDs">stream id</a>'s.
57 * </p>
58 * <p>
59 * Camera input can be selected using the {@link #CameraInputScheme} Uri.
60 * </p>
61 *
62 * <a name="streamworker"><h5><i>StreamWorker</i> Decoding Thread</h5></a>
63 * <p>
64 * Most of the stream processing is performed on the decoding thread, a.k.a. <i>StreamWorker</i>:
65 * <ul>
66 * <li>Stream initialization triggered by {@link #playStream(Uri, int, int, int, int) playStream(..)} - User gets notified whether the stream has been initialized or not via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.</li>
67 * <li>Stream decoding - User gets notified of a new frame via {@link GLMediaEventListener#newFrameAvailable(GLMediaPlayer, com.jogamp.opengl.util.texture.TextureSequence.TextureFrame, long) newFrameAvailable(...)}.</li>
68 * <li>Caught <a href="#streamerror">exceptions on the decoding thread</a> are delivered as {@link StreamException}s.</li>
69 * </ul>
70 * <i>StreamWorker</i> generates it's own {@link GLContext}, shared with the one passed to {@link #initGL(GL)}.
71 * The shared {@link GLContext} allows the decoding thread to push the video frame data directly into
72 * the designated {@link TextureFrame}, later returned via {@link #getNextTexture(GL)} and used by the user.
73 * </p>
74 * <a name="streamerror"><h7><i>StreamWorker</i> Error Handling</h7></a>
75 * <p>
76 * Caught exceptions on <a href="#streamworker">StreamWorker</a> are delivered as {@link StreamException}s,
77 * which either degrades the {@link State} to {@link State#Uninitialized} or {@link State#Paused}.
78 * </p>
79 * <p>
80 * An occurring {@link StreamException} triggers a {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} event,
81 * which can be listened to via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long)}.
82 * </p>
83 * <p>
84 * An occurred {@link StreamException} can be read via {@link #getStreamException()}.
85 * </p>
86 *
87 * </p>
88 * <a name="lifecycle"><h5>GLMediaPlayer Lifecycle</h5></a>
89 * <p>
90 * <table border="1">
91 * <tr><th>Action</th> <th>{@link State} Before</th> <th>{@link State} After</th> <th>{@link EventMask#Bit Event}</th></tr>
92 * <tr><td>{@link #playStream(Uri, int, int, int, int)}</td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link State#Initialized Initialized}<sup><a href="#streamworker">1</a></sup>, {@link State#Uninitialized Uninitialized}</td> <td>{@link EventMask.Bit#Init Init} or ( {@link EventMask.Bit#Error Error} + {@link EventMask.Bit#Uninit Uninit} )</td></tr>
93 * <tr><td>{@link #initGL(GL)}</td> <td>{@link State#Initialized Initialized}, {@link State#Uninitialized Uninitialized} </td> <td>{@link State#Playing Playing}, {@link State#Uninitialized Uninitialized}</td> <td>{@link EventMask.Bit#Play Play} or ( {@link EventMask.Bit#Error Error} + {@link EventMask.Bit#Uninit Uninit} )</td></tr>
94 * <tr><td>{@link #pause(boolean)}</td> <td>{@link State#Playing Playing}</td> <td>{@link State#Paused Paused}</td> <td>{@link EventMask.Bit#Pause Pause}</td></tr>
95 * <tr><td>{@link #resume()}</td> <td>{@link State#Paused Paused}</td> <td>{@link State#Playing Playing}</td> <td>{@link EventMask.Bit#Play Play}</td></tr>
96 * <tr><td>{@link #stop()}</td> <td>{@link State#Playing Playing}, {@link State#Paused Paused}</td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link EventMask.Bit#Pause Pause}</td></tr>
97 * <tr><td>{@link #seek(int)}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>none</td></tr>
98 * <tr><td>{@link #getNextTexture(GL)}</td> <td><i>any</i></td> <td><i>same</i></td> <td>none</td></tr>
99 * <tr><td>{@link #getLastTexture()}</td> <td><i>any</i></td> <td><i>same</i></td> <td>none</td></tr>
100 * <tr><td>{@link TextureFrame#END_OF_STREAM_PTS END_OF_STREAM}</td> <td>{@link State#Playing Playing}</td> <td>{@link State#Paused Paused}</td> <td>{@link EventMask.Bit#EOS EOS} + {@link EventMask.Bit#Pause Pause}</td></tr>
101 * <tr><td>{@link StreamException}</td> <td><i>any</i></td> <td>{@link State#Paused Paused}, {@link State#Uninitialized Uninitialized}</td> <td>{@link EventMask.Bit#Error Error} + ( {@link EventMask.Bit#Pause Pause} or {@link EventMask.Bit#Uninit Uninit} )</td></tr>
102 * <tr><td>{@link #destroy(GL)}</td> <td><i>any</i></td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link EventMask.Bit#Uninit Uninit}</td></tr>
103 * </table>
104 * </p>
105 *
106 * <a name="streamIDs"><h5>Audio and video Stream IDs</h5></a>
107 * <p>
108 * <table border="1">
109 * <tr><th>value</th> <th>request</th> <th>get</th></tr>
110 * <tr><td>{@link #STREAM_ID_NONE}</td> <td>mute</td> <td>not available</td></tr>
111 * <tr><td>{@link #STREAM_ID_AUTO}</td> <td>auto</td> <td>unspecified</td></tr>
112 * <tr><td>&ge;0</td> <td>specific stream</td> <td>specific stream</td></tr>
113 * </table>
114 * </p>
115 * <p>
116 * Current implementations (check each API doc link for details):
117 * <ul>
118 * <li>{@link jogamp.opengl.util.av.NullGLMediaPlayer}</li>
119 * <li>{@link jogamp.opengl.util.av.impl.OMXGLMediaPlayer}</li>
120 * <li>{@link jogamp.opengl.util.av.impl.FFMPEGMediaPlayer}</li>
121 * <li>{@link jogamp.opengl.android.av.AndroidGLMediaPlayerAPI14}</li>
122 * </ul>
123 * </p>
124 * <p>
125 * Implementations of this interface must implement:
126 * <pre>
127 * public static final boolean isAvailable();
128 * </pre>
129 * to be properly considered by {@link GLMediaPlayerFactory#create(ClassLoader, String)}
130 * and {@link GLMediaPlayerFactory#createDefault()}.
131 * </p>
132 * <a name="timestampaccuracy"><h5>Timestamp Accuracy</h5></a>
133 * <p>
134 * <p>
135 * Timestamp type and value range has been chosen to suit embedded CPUs
136 * and characteristics of audio and video streaming. See {@link TimeFrameI}.
137 * </p>
138 *
139 * <a name="synchronization"><h5>Audio and video synchronization</h5></a>
140 * <p>
141 * The class follows a passive A/V synchronization pattern.
142 * Audio is being untouched, while {@link #getNextTexture(GL)} delivers a new video frame
143 * only, if its timestamp is less than {@link #MAX_VIDEO_ASYNC} ahead of <i>time</i>.
144 * If its timestamp is more than {@link #MAX_VIDEO_ASYNC} ahead of <i>time</i>,
145 * the previous frame is returned.
146 * If its timestamp is more than {@link #MAX_VIDEO_ASYNC} after <i>time</i>,
147 * the frame is dropped and the next frame is being fetched.
148 * </p>
149 * <p>
150 * https://en.wikipedia.org/wiki/Audio_to_video_synchronization
151 * <pre>
152 * d_av = v_pts - a_pts;
153 * </pre>
154 * </p>
155 * <p>
156 * Recommendation of audio/video pts time lead/lag at production:
157 * <ul>
158 * <li>Overall: +40ms and -60ms audio ahead video / audio after video</li>
159 * <li>Each stage: +5ms and -15ms. audio ahead video / audio after video</li>
160 * </ul>
161 * </p>
162 * <p>
163 * Recommendation of av pts time lead/lag at presentation:
164 * <ul>
165 * <li>TV: +15ms and -45ms. audio ahead video / audio after video.</li>
166 * <li>Film: +22ms and -22ms. audio ahead video / audio after video.</li>
167 * </ul>
168 * </p>
169 *
170 * <a name="teststreams"><h5>Test Streams</h5></a>
171 * <p>
172 * <table border="1">
173 * <tr><th colspan=5>Big Buck Bunny 24f 16:9</th></tr>
174 * <tr><td>Big Buck Bunny</td><td>320p</td><td>h264<td>aac 48000Hz 2 chan</td><td>http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4</td></tr>
175 * <tr><td>Big Buck Bunny</td><td>240p</td><td>h264<td>aac 48000Hz 2 chan</td><td>http://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4</td></tr>
176 * <tr><td>Big Buck Bunny</td><td>720p</td><td>mpeg4<td>ac3 48000Hz 5.1 chan</td><td>http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_surround.avi</td></tr>
177 * <tr><td>Big Buck Bunny</td><td>720p</td><td>msmpeg4v2<td>mp3 48000Hz 2 chan</td><td>http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_stereo.avi</td></tr>
178 * <tr><td>Big Buck Bunny</td><td>720p</td><td>theora<td>vorbis 48000Hz 2 chan</td><td>http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_stereo.ogg</td></tr>
179 * <tr><td>Big Buck Bunny</td><td>1080p</td><td>mpeg4<td>ac3 48000Hz 5.1 chan</td><td>http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_1080p_surround.avi</td></tr>
180 * <tr><th colspan=5>WebM/Matroska (vp8/vorbis)</th></tr>
181 * <tr><td>Big Buck Bunny Trailer</td><td>640p</td><td>vp8<td>vorbis 44100Hz 1 chan</td><td>http://video.webmfiles.org/big-buck-bunny_trailer.webm</td></tr>
182 * <tr><td>Elephants Dream</td><td>540p</td><td>vp8<td>vorbis 44100Hz 1 chan</td><td>http://video.webmfiles.org/elephants-dream.webm</td></tr>
183 * <tr><th colspan=5>You Tube http/rtsp</th></tr>
184 * <tr><td>Sintel</td><td colspan=3>http://www.youtube.com/watch?v=eRsGyueVLvQ</td><td>rtsp://v3.cache1.c.youtube.com/CiILENy73wIaGQn0LpXnygYbeRMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp</td></tr>
185 * <tr><th colspan=5>Audio/Video Sync</th></tr>
186 * <tr><td>Five-minute-sync-test1080p</td><td colspan=3>https://www.youtube.com/watch?v=szoOsG9137U</td><td>rtsp://v7.cache8.c.youtube.com/CiILENy73wIaGQm133VvsA46sxMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp</td></tr>
187 * <tr><td>Audio-Video-Sync-Test-Calibration-23.98fps-24fps</td><td colspan=4>https://www.youtube.com/watch?v=cGgf_dbDMsw</td></tr>
188 * <tr><td>sound_in_sync_test</td><td colspan=4>https://www.youtube.com/watch?v=O-zIZkhXNLE</td></tr>
189 * <!-- <tr><td> title </td><td>1080p</td><td>mpeg4<td>ac3 48000Hz 5.1 chan</td><td> url </td></tr> -->
190 * <!-- <tr><td> title </td><td colspan=3> url1 </td><td> url2 </td></tr>
191 * </table>
192 * </p>
193 * <p>
194 * Since 2.3.0 this interface uses {@link Uri} instead of {@link java.net.URI}.
195 * </p>
196 */
197public interface GLMediaPlayer extends TextureSequence {
198 public static final boolean DEBUG = Debug.debug("GLMediaPlayer");
199 public static final boolean DEBUG_AVSYNC = Debug.debug("GLMediaPlayer.AVSync");
200 public static final boolean DEBUG_NATIVE = Debug.debug("GLMediaPlayer.Native");
201
202 /** Default texture count, value {@value}. */
203 public static final int TEXTURE_COUNT_DEFAULT = 3;
204
205 /** Minimum texture count, value {@value}. Using the minimum texture count disables multi-threaded decoding. */
206 public static final int TEXTURE_COUNT_MIN = 1;
207
208 /** Constant {@value} for <i>mute</i> or <i>not available</i>. See <a href="#streamIDs">Audio and video Stream IDs</a>. */
209 public static final int STREAM_ID_NONE = -2;
210 /** Constant {@value} for <i>auto</i> or <i>unspecified</i>. See <a href="#streamIDs">Audio and video Stream IDs</a>. */
211 public static final int STREAM_ID_AUTO = -1;
212
213 /**
214 * {@link Uri#scheme Uri scheme} name {@value} for camera input. E.g. <code>camera:/0</code>
215 * for the 1st camera device.
216 * <p>
217 * The {@link Uri#path Uri path} is being used to identify the camera (<i>&lt;id&gt;</i>),
218 * where the root fwd-slash is being cut-off.
219 * </p>
220 * <p>
221 * The <i>&lt;id&gt;</i> is usually an integer value indexing the camera
222 * ranging from [0..<i>max-number</i>].
223 * </p>
224 * <p>
225 * The <i>&lt;somewhere&gt;</i> is usually empty, since it would imply a networking camera protocol.
226 * </p>
227 * <p>
228 * The {@link Uri#query Uri query} is used to pass options to the camera
229 * using <i>;</i> as the separator. The latter avoids trouble w/ escaping.
230 * </p>
231 * <pre>
232 * camera:/&lt;id&gt;
233 * camera:/&lt;id&gt;?width=640;height=480;rate=15
234 * camera:/&lt;id&gt;?size=640x480;rate=15
235 * camera://&lt;somewhere&gt;/&lt;id&gt;
236 * camera://&lt;somewhere&gt;/&lt;id&gt;?width=640;height=480;rate=15
237 * camera://&lt;somewhere&gt;/&lt;id&gt;?size=640x480;rate=15
238 * camera:///&lt;id&gt;?width=640;height=480;rate=15
239 * camera:///&lt;id&gt;?size=640x480;rate=15
240 * </pre>
241 * <pre>
242 * Uri: [scheme:][//authority][path][?query][#fragment]
243 * w/ authority: [user-info@]host[:port]
244 * Note: 'path' starts w/ fwd slash
245 * </pre>
246 * </p>
247 */
248 public static final Uri.Encoded CameraInputScheme = Uri.Encoded.cast("camera");
249 /** Camera property {@value}, size as string, e.g. <code>1280x720</code>, <code>hd720</code>. May not be supported on all platforms. See {@link #CameraInputScheme}. */
250 public static final String CameraPropSizeS = "size";
251 /** Camera property {@value}. See {@link #CameraInputScheme}. */
252 public static final String CameraPropWidth = "width";
253 /** Camera property {@value}. See {@link #CameraInputScheme}. */
254 public static final String CameraPropHeight = "height";
255 /** Camera property {@value}. See {@link #CameraInputScheme}. */
256 public static final String CameraPropRate = "rate";
257
258 /** Maximum video frame async of {@value} milliseconds. */
259 public static final int MAX_VIDEO_ASYNC = 22;
260 public static final int MIN_VIDEO_ASYNC = 11;
261
262 /**
263 * A StreamException encapsulates a caught exception in the decoder thread, a.k.a <i>StreamWorker</i>,
264 * see See <a href="#streamerror"><i>StreamWorker</i> Error Handling</a>.
265 */
266 @SuppressWarnings("serial")
267 public static class StreamException extends Exception {
268 public StreamException(final Throwable cause) {
269 super(cause);
270 }
271 public StreamException(final String message, final Throwable cause) {
272 super(message, cause);
273 }
274 }
275
276 /** Chapter meta-data of stream, see {@link GLMediaPlayer#getChapters()}. */
277 public static class Chapter {
278 /** Chapter ID */
279 public final int id;
280 /** Chapter start PTS in ms */
281 public final int start;
282 /** Chapter end PTS in ms */
283 public final int end;
284 /** Chapter title */
285 public final String title;
286 public Chapter(final int i, final int s, final int e, final String t) {
287 id = i; start = s; end = e; title = t;
288 }
289 /** Returns chapter duration, i.e. {@code end - start + 1}. */
290 public int duration() { return end - start + 1; }
291 @Override
292 public String toString() {
293 return String.format("%02d: [%s .. %s] %s", id, PTS.toTimeStr(start), PTS.toTimeStr(end), title);
294 }
295 }
296
297 /**
298 * As the contract of {@link GLMediaFrameListener} and {@link TexSeqEventListener} requests,
299 * implementations of {@link GLMediaEventListener} shall:
300 * <ul>
301 * <li>off-load complex or {@link GLMediaPlayer} commands on another thread, or</li>
302 * <li>simply changing a volatile state of their {@link GLEventListener} implementation.</li>
303 * </ul>
304 */
305 public interface GLMediaEventListener {
306 /**
307 * @param mp the event source
308 * @param event_mask the changes attributes
309 * @param when system time in msec.
310 */
311 public void attributesChanged(GLMediaPlayer mp, EventMask event_mask, long when);
312 }
313 /**
314 * {@inheritDoc}
315 * <p>
316 * Optional Video {@link TextureFrame} listener.
317 * Usually one wants to use {@link GLMediaPlayer#getNextTexture(GL)} is used to retrieve the next frame and keep
318 * decoding going, while {@link GLMediaPlayer#getLastTexture(GL)} is used to simply retrieve the
319 * last decoded frame.
320 * </p>
321 * <p>
322 * As the contract of {@link TexSeqEventListener} requests,
323 * implementations of {@link GLMediaEventListener} shall also:
324 * <ul>
325 * <li>off-load complex or {@link GLMediaPlayer} commands on another thread, or</li>
326 * <li>simply changing a volatile state of their {@link GLEventListener} implementation.</li>
327 * </ul>
328 * </p>
329 */
330 public interface GLMediaFrameListener extends TexSeqEventListener<GLMediaPlayer> {
331 }
332
333 /** Changes attributes event mask */
334 public static final class EventMask {
335
336 /** Attribute change bits */
337 public static enum Bit {
338 /** State changed to {@link State#Initialized}. See <a href="#lifecycle">Lifecycle</a>.*/
339 Init ( 1<<0 ),
340 /** State changed to {@link State#Uninitialized}. See <a href="#lifecycle">Lifecycle</a>.*/
341 Uninit ( 1<<1 ),
342 /** State changed to {@link State#Playing}. See <a href="#lifecycle">Lifecycle</a>.*/
343 Play ( 1<<2 ),
344 /** State changed to {@link State#Paused}. See <a href="#lifecycle">Lifecycle</a>.*/
345 Pause ( 1<<3 ),
346 /** Time position has changed, e.g. via {@link GLMediaPlayer#seek(int)}.*/
347 Seek ( 1<<4 ),
348 /** End of stream reached. See <a href("#lifecycle">Lifecycle</a>.*/
349 EOS ( 1<<5 ),
350 /** An error occurred, e.g. during off-thread initialization. See {@link StreamException} and <a href("#lifecycle">Lifecycle</a>. */
351 Error ( 1<<6 ),
352
353 /** Stream video id change. */
354 VID ( 1<<16 ),
355 /** Stream audio id change. */
356 AID ( 1<<17 ),
357 /** Stream subtitle id change. */
358 SID ( 1<<18 ),
359 /** TextureFrame size or vertical flip change. */
360 Size ( 1<<19 ),
361 /** Stream fps change. */
362 FPS ( 1<<20 ),
363 /** Stream bps change. */
364 BPS ( 1<<21 ),
365 /** Stream length change. */
366 Length ( 1<<22 ),
367 /** Audio, video or subtitle stream codec change. */
368 Codec ( 1<<23 ),
369 /** Audio stream codec change. */
370 ACodec ( 1<<24 ),
371 /** Video stream codec change. */
372 VCodec ( 1<<25 ),
373 /** Subtitle stream codec change. */
374 SCodec ( 1<<26 );
375
376 Bit(final int v) { value = v; }
377 public final int value;
378 }
379 public int mask;
380
381 public static int getBits(final List<Bit> v) {
382 int res = 0;
383 for(final Bit b : v) {
384 res |= b.value;
385 }
386 return res;
387 }
388 public EventMask(final List<Bit> v) {
389 mask = getBits(v);
390 }
391 public EventMask(final Bit v) {
392 mask = v.value;
393 }
394 public EventMask(final int v) {
395 mask = v;
396 }
397 public EventMask() {
398 mask = 0;
399 }
400
401 public boolean isSet(final Bit bit) { return bit.value == ( mask & bit.value ); }
402 public boolean isSet(final List<Bit> bits) { final int bits_i = getBits(bits); return bits_i == ( mask & bits_i ); }
403 public boolean isSet(final int bits) { return bits == ( mask & bits ); }
404 public boolean isZero() { return 0 == mask; }
405
406 public EventMask setBit(final Bit v) { mask |= v.value; return this; }
407 public EventMask setBits(final List<Bit> v) {
408 for(final Bit b : v) {
409 mask |= b.value;
410 }
411 return this;
412 }
413
414 @Override
415 public String toString() {
416 int count = 0;
417 final StringBuilder out = new StringBuilder();
418 for (final Bit dt : Bit.values()) {
419 if( isSet(dt) ) {
420 if( 0 < count ) { out.append(", "); }
421 out.append(dt.name()); count++;
422 }
423 }
424 if( 0 == count ) {
425 out.append("None");
426 } else if( 1 < count ) {
427 out.insert(0, "[");
428 out.append("]");
429 }
430 return out.toString();
431 }
432
433 @Override
434 public boolean equals(final Object other) {
435 if (this == other) {
436 return true;
437 }
438 return (other instanceof EventMask) &&
439 this.mask == ((EventMask)other).mask;
440 }
441 }
442
443 /**
444 * See <a href="#lifecycle">Lifecycle</a>.
445 */
446 public enum State {
447 /** Uninitialized player, no resources shall be hold. */
449 /** Stream has been initialized, user may play or call {@link #initGL(GL)}. */
451 /** Stream is playing. */
453 /** Stream is pausing. */
455
456 public final int id;
457
458 State(final int id){
459 this.id = id;
460 }
461 }
462
463 /** Print native library information of used implementation to given out PrintStream. */
464 public void printNativeInfo(final PrintStream out);
465
466 public int getTextureCount();
467
468 /** Sets the texture unit. Defaults to 0. */
469 public void setTextureUnit(int u);
470
471 /** Sets the texture min-mag filter, defaults to {@link GL#GL_NEAREST}. */
472 public void setTextureMinMagFilter(int[] minMagFilter);
473 /** Sets the texture min-mag filter, defaults to {@link GL#GL_CLAMP_TO_EDGE}. */
474 public void setTextureWrapST(int[] wrapST);
475
476 /**
477 * {@inheritDoc}
478 * <p>
479 * Defaults to {@code true} and toggling not supported.
480 * </p>
481 */
482 @Override
483 public boolean useARatioAdjustment();
484
485 /**
486 * {@inheritDoc}
487 * <p>
488 * Defaults to {@code true} and toggling is not supported.
489 * </p>
490 */
491 @Override
492 public void setARatioAdjustment(final boolean v);
493
494 /**
495 * {@inheritDoc}
496 * <p>
497 * Defaults to {@code false} and toggling is supported via {@link #setARatioLetterbox(boolean, Vec4f)}
498 * </p>
499 */
500 @Override
501 public boolean useARatioLetterbox();
502
503 /**
504 * {@inheritDoc}
505 */
506 @Override
508
509 /**
510 * {@inheritDoc}
511 * <p>
512 * Defaults to {@code false}.
513 * </p>
514 */
515 @Override
516 public void setARatioLetterbox(final boolean v, Vec4f backColor);
517
518 /**
519 * Limit maximum supported audio channels by user.
520 * <p>
521 * Must be set before {@link #playStream(Uri, int, int, int, int)}
522 * </p>
523 * <p>
524 * May be utilized to enforce 1 channel (mono) downsampling
525 * in combination with JOAL/OpenAL to experience spatial 3D position effects.
526 * </p>
527 * @param cc maximum supported audio channels, will be clipped [1..x], with x being the underlying audio subsystem's maximum
528 * @see #playStream(Uri, int, int, int, int)
529 */
530 public void setAudioChannelLimit(final int cc);
531
532 /**
533 * Issues asynchronous stream initialization.
534 * <p>
535 * <a href="#lifecycle">Lifecycle</a>: {@link State#Uninitialized} -> {@link State#Initialized}<sup><a href="#streamworker">1</a></sup> or {@link State#Uninitialized}
536 * </p>
537 * <p>
538 * {@link State#Initialized} is reached asynchronous,
539 * i.e. user gets notified via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.
540 * </p>
541 * <p>
542 * A possible caught asynchronous {@link StreamException} while initializing the stream off-thread
543 * will be thrown at {@link #initGL(GL)}.
544 * </p>
545 * <p>
546 * Muted audio can be achieved by passing {@link #STREAM_ID_NONE} to <code>aid</code>.
547 * </p>
548 * <p>
549 * Muted video can be achieved by passing {@link #STREAM_ID_NONE} to <code>vid</code>,
550 * in which case <code>textureCount</code> is ignored as well as the passed GL object of the subsequent {@link #initGL(GL)} call.
551 * </p>
552 * @param streamLoc the stream location
553 * @param vid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
554 * @param aid audio stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
555 * @param sid subtitle stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
556 * @param textureCount desired number of buffered textures to be decoded off-thread, will be validated by implementation.
557 * The minimum value is {@link #TEXTURE_COUNT_MIN} (single-threaded) or above to enable multi-threaded stream decoding.
558 * Default is {@link #TEXTURE_COUNT_DEFAULT}.
559 * Value is ignored if video is muted.
560 * @throws IllegalStateException if not invoked in {@link State#Uninitialized}
561 * @throws IllegalArgumentException if arguments are invalid
562 * @see #playStream(Uri, int, String, int, String, int, int)
563 * @since 2.6.0
564 */
565 public void playStream(Uri streamLoc, int vid, int aid, int sid, int textureCount) throws IllegalStateException, IllegalArgumentException;
566
567 /**
568 * Same as {@link #playStream(Uri, int, int, int, int)}, but providing desired audio- and subtile languages to be selected.
569 * @param streamLoc the stream location
570 * @param vid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
571 * @param alang desired audio language, pass {@code null} to use {@code aid}
572 * @param aid fallback audio stream id in case {@code alang} is {@code null}, see <a href="#streamIDs">audio and video Stream IDs</a>
573 * @param slang desired subtitle language, pass {@code null} to use {@code sid}
574 * @param sid fallback subtitle stream id in case {@code alang} is {@code null}, see <a href="#streamIDs">audio and video Stream IDs</a>
575 * @param textureCount desired number of buffered textures to be decoded off-thread, will be validated by implementation.
576 * The minimum value is {@link #TEXTURE_COUNT_MIN} (single-threaded) or above to enable multi-threaded stream decoding.
577 * Default is {@link #TEXTURE_COUNT_DEFAULT}.
578 * Value is ignored if video is muted.
579 * @throws IllegalStateException if not invoked in {@link State#Uninitialized}
580 * @throws IllegalArgumentException if arguments are invalid
581 * @see #playStream(Uri, int, int, int, int)
582 * @since 2.6.0
583 */
584 public void playStream(final Uri streamLoc, final int vid,
585 final String alang, final int aid, final String slang, final int sid,
586 final int reqTextureCount) throws IllegalStateException, IllegalArgumentException;
587
588 /**
589 * Switches current {@link #playStream(Uri, int, int, int, int)} to given stream IDs and continues at same {@link #getVideoPTS()}.
590 * <p>
591 * Implementation just issues {@link #stop()}, {@link #seek(int)} and {@link #playStream(Uri, int, int, int, int)}.
592 * </p>
593 * @param vid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
594 * @param aid audio stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
595 * @param sid subtitle stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
596 * @throws IllegalStateException
597 * @throws IllegalArgumentException
598 * @since 2.6.0
599 */
600 public void switchStream(final int vid, final int aid, final int sid) throws IllegalStateException, IllegalArgumentException;
601
602 /**
603 * Returns the {@link StreamException} caught in the decoder thread, or <code>null</code> if none occured.
604 * <p>
605 * Method clears the cached {@link StreamException}, hence an immediate subsequent call will return <code>null</code>.
606 * </p>
607 * @see GLMediaEventListener#EVENT_CHANGE_ERR
608 * @see StreamException
609 */
611
612 /**
613 * Initializes OpenGL related resources.
614 * <p>
615 * <a href="#lifecycle">Lifecycle</a>: {@link State#Initialized} -> {@link State#Paused} or {@link State#Initialized}
616 * </p>
617 * Argument <code>gl</code> is ignored if video is muted, see {@link #playStream(Uri, int, int, int, int)}.
618 *
619 * @param gl current GL object. Maybe <code>null</code>, for audio only.
620 * @throws IllegalStateException if not invoked in {@link State#Initialized}.
621 * @throws StreamException forwarded from the off-thread stream initialization
622 * @throws GLException in case of difficulties to initialize the GL resources
623 */
624 public void initGL(GL gl) throws IllegalStateException, StreamException, GLException;
625
626 /**
627 * If implementation uses a {@link AudioSink}, it's instance will be returned.
628 * <p>
629 * The {@link AudioSink} instance is available after {@link #playStream(Uri, int, int, int, int)},
630 * if used by implementation.
631 * </p>
632 */
633 public AudioSink getAudioSink();
634
635 /**
636 * Releases the GL, stream and other resources, including {@link #attachObject(String, Object) attached user objects}.
637 * <p>
638 * <a href="#lifecycle">Lifecycle</a>: <code>ANY</code> -> {@link State#Uninitialized}
639 * </p>
640 */
641 public State destroy(GL gl);
642
643 /**
644 * Stops streaming and releases the GL, stream and other resources, but keeps {@link #attachObject(String, Object) attached user objects}.
645 * <p>
646 * <a href="#lifecycle">Lifecycle</a>: <code>ANY</code> -> {@link State#Uninitialized}
647 * </p>
648 */
649 public State stop();
650
651 /**
652 * Sets the playback speed.
653 * <p>
654 * To simplify test, play speed is <i>normalized</i>, i.e.
655 * <ul>
656 * <li><code>1.0f</code>: if <code> Math.abs(1.0f - rate) < 0.01f </code></li>
657 * </ul>
658 * </p>
659 * @return true if successful, otherwise false, i.e. due to unsupported value range of implementation.
660 */
661 public boolean setPlaySpeed(float rate);
662
663 /** Returns the playback speed. */
664 public float getPlaySpeed();
665
666 /**
667 * Sets the audio volume, [0f..1f].
668 * <p>
669 * To simplify test, volume is <i>normalized</i>, i.e.
670 * <ul>
671 * <li><code>0.0f</code>: if <code> Math.abs(v) < 0.01f </code></li>
672 * <li><code>1.0f</code>: if <code> Math.abs(1.0f - v) < 0.01f </code></li>
673 * </ul>
674 * </p>
675 * @return true if successful, otherwise false, i.e. due to unsupported value range of implementation.
676 */
677 public boolean setAudioVolume(float v);
678
679 /** Returns the audio volume. */
680 public float getAudioVolume();
681
682 /** Returns true if audio is muted, i.e. {@link #setAudioVolume(float)} to zero. */
683 public boolean isAudioMuted();
684
685 /**
686 * Starts or resumes the <i>StreamWorker</i> decoding thread.
687 * <p>
688 * <a href="#lifecycle">Lifecycle</a>: {@link State#Paused} -> {@link State#Playing}
689 * </p>
690 */
691 public State resume();
692
693 /**
694 * Pauses the <i>StreamWorker</i> decoding thread.
695 * <p>
696 * <a href="#lifecycle">Lifecycle</a>: {@link State#Playing} -> {@link State#Paused}
697 * </p>
698 * <p>
699 * If a <i>new</i> frame is desired after the next {@link #resume()} call,
700 * e.g. to make a snapshot of a camera input stream,
701 * <code>flush</code> shall be set to <code>true</code>.
702 * </p>
703 * @param flush if <code>true</code> flushes the video and audio buffers, otherwise keep them intact.
704 */
705 public State pause(boolean flush);
706
707 /**
708 * Seeks to the new absolute position. The <i>StreamWorker</i> decoding thread
709 * is paused while doing so and the A/V buffers are flushed.
710 * <p>
711 * Allowed in state {@link State#Playing} and {@link State#Paused}, otherwise ignored,
712 * see <a href="#lifecycle">Lifecycle</a>.
713 * </p>
714 *
715 * @param msec absolute desired time position in milliseconds
716 * @return time current position in milliseconds, after seeking to the desired position
717 **/
718 public int seek(int msec);
719
720 /**
721 * See <a href="#lifecycle">Lifecycle</a>.
722 * @return the current state, either {@link State#Uninitialized}, {@link State#Initialized}, {@link State#Playing} or {@link State#Paused}
723 */
724 public State getState();
725
726 /**
727 * Return an array of detected video stream IDs.
728 */
729 public int[] getVStreams();
730
731 /**
732 * Return an array of detected video stream language codes, matching {@link #getVStreams()} array and its indices.
733 * <p>
734 * The language code is supposed to be 3-letters of `ISO 639-2 language codes`.
735 * </p>
736 * @see #getLang(int)
737 */
738 public String[] getVLangs();
739
740 /**
741 * Return the video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>.
742 */
743 public int getVID();
744
745 /** Returns the next video stream id, rotates. */
746 public int getNextVID();
747
748 /**
749 * Return an array of detected audio stream IDs.
750 */
751 public int[] getAStreams();
752
753 /**
754 * Return an array of detected audio stream language codes, matching {@link #getAStreams()} array and its indices.
755 * <p>
756 * The language code is supposed to be 3-letters of `ISO 639-2 language codes`.
757 * </p>
758 * @see #getLang(int)
759 */
760 public String[] getALangs();
761
762 /**
763 * Return the audio stream id, see <a href="#streamIDs">audio and video Stream IDs</a>.
764 */
765 public int getAID();
766
767 /** Returns the next audio stream id, rotates. */
768 public int getNextAID();
769
770 /**
771 * Return an array of detected subtitle stream IDs.
772 */
773 public int[] getSStreams();
774
775 /**
776 * Return an array of detected subtitle stream language codes, matching {@link #getSStreams()} array and its indices.
777 * <p>
778 * The language code is supposed to be 3-letters of `ISO 639-2 language codes`.
779 * </p>
780 * @see #getLang(int)
781 */
782 public String[] getSLangs();
783
784 /**
785 * Return the subtitle stream id, see <a href="#streamIDs">audio and video Stream IDs</a>.
786 */
787 public int getSID();
788
789 /** Returns the next subtitle stream id, rotates including no-stream*/
790 public int getNextSID();
791
792 /**
793 * Return whether the given stream ID is available, i.e. matching one of the stream IDs in {@link #getVStreams()}, {@link #getAStreams()} or {@link #getSStreams()}.
794 */
795 public boolean hasStreamID(int id);
796
797 /**
798 * Return the matching language code of given stream ID, matching one of the stream IDs in {@link #getVStreams()}, {@link #getAStreams()} or {@link #getSStreams()}.
799 * <p>
800 * The language code is supposed to be 3-letters of `ISO 639-2 language codes`.
801 * </p>
802 * <p>
803 * If the stream ID is not available, {@code und} is returned
804 * </p>
805 * @see #getVStreams()
806 * @see #getAStreams()
807 * @see #getSStreams()
808 * @see #getVLangs()
809 * @see #getALangs()
810 * @see #getSLangs()
811 */
812 public String getLang(int id);
813
814 /**
815 * @return the current decoded video frame count since {@link #resume()} and {@link #seek(int)}
816 * as increased by {@link #getNextTexture(GL)} or the decoding thread.
817 */
819
820 /**
821 * @return the current presented video frame count since {@link #resume()} and {@link #seek(int)}
822 * as increased by {@link #getNextTexture(GL)} for new frames.
823 */
825
826
827 /**
828 * Returns current System Clock Reference (SCR) presentation timestamp ({@link PTS}).
829 * <p>
830 * To retrieve the current interpolated PTS against the stored System Clock Reference (SCR), use:
831 * <pre>
832 * int pts = mPlayer.getPTS().get(Clock.currentMillis());
833 * </pre>
834 * </p>
835 **/
836 public PTS getPTS();
837
838 /**
839 * Returns current video presentation timestamp (PTS) in milliseconds of {@link #getLastTexture()},
840 * try using {@link #getPTS()}.
841 * <p>
842 * The relative millisecond PTS since start of the presentation stored in integer
843 * covers a time span of 2'147'483'647 ms (see {@link Integer#MAX_VALUE}
844 * or 2'147'483 seconds or 24.855 days.
845 * </p>
846 * @see #getPTS()
847 **/
848 public int getVideoPTS();
849
850 /**
851 * Returns current audio presentation timestamp (PTS) in milliseconds,
852 * try using {@link #getPTS()}.
853 * <p>
854 * The relative millisecond PTS since start of the presentation stored in integer
855 * covers a time span of 2'147'483'647 ms (see {@link Integer#MAX_VALUE}
856 * or 2'147'483 seconds or 24.855 days.
857 * </p>
858 * @see #getPTS()
859 **/
860 public int getAudioPTS();
861
862 /**
863 * {@inheritDoc}
864 * <p>
865 * Returns the last decoded Video {@link TextureSequence.TextureFrame}.
866 * </p>
867 * <p>
868 * See <a href="#synchronization">audio and video synchronization</a>.
869 * </p>
870 * @throws IllegalStateException if not invoked in {@link State#Paused} or {@link State#Playing}
871 */
872 @Override
873 public TextureSequence.TextureFrame getLastTexture() throws IllegalStateException;
874
875 /**
876 * {@inheritDoc}
877 * <p>
878 * Returns the next Video {@link TextureSequence.TextureFrame} to be rendered in sync with {@link #getPTS()}
879 * and keeps decoding going.
880 * </p>
881 * <p>
882 * In case the current state is not {@link State#Playing}, {@link #getLastTexture()} is returned.
883 * </p>
884 * <p>
885 * See <a href="#synchronization">audio and video synchronization</a>.
886 * </p>
887 * @throws IllegalStateException if not invoked in {@link State#Paused} or {@link State#Playing}
888 *
889 * @see #addEventListener(GLMediaEventListener)
890 * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, TextureFrame, long)
891 */
892 @Override
893 public TextureSequence.TextureFrame getNextTexture(GL gl) throws IllegalStateException;
894
895 /**
896 * Return the stream location, as set by {@link #playStream(Uri, int, int, int, int)}.
897 * @since 2.3.0
898 */
899 public Uri getUri();
900
901 /**
902 * <i>Warning:</i> Optional information, may not be supported by implementation.
903 * @return the {@link CodecID} of the video stream, if available
904 */
906
907 /**
908 * <i>Warning:</i> Optional information, may not be supported by implementation.
909 * @return the codec of the video stream, if available
910 */
911 public String getVideoCodec();
912
913 /**
914 * <i>Warning:</i> Optional information, may not be supported by implementation.
915 * @return the {@link CodecID} of the audio stream, if available
916 */
918
919 /**
920 * <i>Warning:</i> Optional information, may not be supported by implementation.
921 * @return the codec of the audio stream, if available
922 */
923 public String getAudioCodec();
924
925 /**
926 * <i>Warning:</i> Optional information, may not be supported by implementation.
927 * @return the {@link CodecID} of the subtitle stream, if available
928 */
930
931 /**
932 * <i>Warning:</i> Optional information, may not be supported by implementation.
933 * @return the codec of the subtitle stream, if available
934 */
935 public String getSubtitleCodec();
936
937 /**
938 * <i>Warning:</i> Optional information, may not be supported by implementation.
939 * @return the total number of video frames
940 */
941 public int getVideoFrames();
942
943 /**
944 * <i>Warning:</i> Optional information, may not be supported by implementation.
945 * @return the total number of audio frames
946 */
947 public int getAudioFrames();
948
949 /**
950 * Return total duration of stream in msec.
951 * <p>
952 * The duration stored in integer covers 2'147'483'647 ms (see {@link Integer#MAX_VALUE}
953 * or 2'147'483 seconds or 24.855 days.
954 * </p>
955 */
956 public int getDuration();
957
958 /**
959 * <i>Warning:</i> Optional information, may not be supported by implementation.
960 * @return the overall bitrate of the stream.
961 */
962 public long getStreamBitrate();
963
964 /**
965 * <i>Warning:</i> Optional information, may not be supported by implementation.
966 * @return video bitrate
967 */
968 public int getVideoBitrate();
969
970 /**
971 * <i>Warning:</i> Optional information, may not be supported by implementation.
972 * @return the audio bitrate
973 */
974 public int getAudioBitrate();
975
976 /**
977 * <i>Warning:</i> Optional information, may not be supported by implementation.
978 * @return the framerate of the video
979 */
980 public float getFramerate();
981
982 /**
983 * Returns <code>true</code> if the video frame is oriented in
984 * OpenGL's coordinate system, <i>origin at bottom left</i>.
985 * <p>
986 * Otherwise returns <code>false</code>, i.e.
987 * video frame is oriented <i>origin at top left</i>.
988 * </p>
989 * <p>
990 * <code>false</code> is the default assumption for videos,
991 * but user shall not rely on.
992 * </p>
993 * <p>
994 * <code>false</code> GL orientation leads to
995 * {@link Texture#getMustFlipVertically()} == <code>true</code>,
996 * as reflected by all {@link TextureFrame}'s {@link Texture}s
997 * retrieved via {@link #getLastTexture()} or {@link #getNextTexture(GL)}.
998 * </p>
999 */
1000 public boolean isGLOriented();
1001
1002 /** Returns the width of the video. */
1003 public int getWidth();
1004
1005 /** Returns the height of the video. */
1006 public int getHeight();
1007
1008 /**
1009 * Returns title meta-data from stream, available after {@link State#Initialized} is reached after issuing {@link #playStream(Uri, int, int, int, int)}.
1010 * <p>
1011 * In case no title meta-data is being used, the {@link #getUri()} basename w/o suffix is being returned.
1012 * </p>
1013 */
1014 public String getTitle();
1015
1016 /** Returns {@link Chapter} meta-data from stream, available after {@link State#Initialized} is reached after issuing {@link #playStream(Uri, int, int, int, int)}. */
1018 /**
1019 * Returns {@link Chapter} covering given time position in milliseconds or null if none covers given time
1020 * @param msec desired chapter covering time position in milliseconds
1021 */
1022 public Chapter getChapter(int msec);
1023
1024 /** Returns a string representation of this player, incl. state and audio/video details. */
1025 @Override
1026 public String toString();
1027
1028 /** Returns a string representation of this player's performance values. */
1029 public String getPerfString();
1030
1031 /** Adds a {@link GLMediaEventListener} to this player. */
1033
1034 /** Removes a {@link GLMediaEventListener} to this player. */
1036
1037 /** Return all {@link GLMediaEventListener} of this player. */
1039
1040 /** Adds a {@link GLMediaFrameListener} to this player. */
1042
1043 /** Removes a {@link GLMediaFrameListener} to this player. */
1045
1046 /** Return all {@link GLMediaFrameListener} of this player. */
1048
1049 /** Sets the {@link SubtitleEventListener} for this player. */
1051 /** Returns the {@link #setSubtitleEventListener(SubtitleEventListener)} of this player. */
1053
1054 /**
1055 * Returns the attached user object for the given name.
1056 */
1057 public Object getAttachedObject(String name);
1058
1059 /**
1060 * Attaches the user object for the given name.
1061 * Returns the previously set object, may be null.
1062 */
1063 public Object attachObject(String name, Object obj);
1064
1065 /**
1066 * Detaches the user object for the given name.
1067 * Returns the previously set object, may be null.
1068 */
1069 public Object detachObject(String name);
1070
1071}
4D Vector based upon four float components.
Definition: Vec4f.java:37
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Chapter meta-data of stream, see GLMediaPlayer#getChapters().
final int start
Chapter start PTS in ms.
Chapter(final int i, final int s, final int e, final String t)
int duration()
Returns chapter duration, i.e.
A StreamException encapsulates a caught exception in the decoder thread, a.k.a StreamWorker,...
StreamException(final String message, final Throwable cause)
Texture holder interface, maybe specialized by implementation to associated related data.
FFmpeg/libAV analog AVCodecID.
Definition: CodecID.java:37
Codec
Audio, video or subtitle stream codec change.
Uninit
State changed to State#Uninitialized.
Size
TextureFrame size or vertical flip change.
Uninitialized
Uninitialized player, no resources shall be hold.
Initialized
Stream has been initialized, user may play or call initGL(GL).
As the contract of GLMediaFrameListener and TexSeqEventListener requests, implementations of GLMediaE...
void attributesChanged(GLMediaPlayer mp, EventMask event_mask, long when)
GLMediaPlayer interface specifies a TextureSequence state machine using a multiplexed audio/video str...
int[] getVStreams()
Return an array of detected video stream IDs.
State pause(boolean flush)
Pauses the StreamWorker decoding thread.
int getVID()
Return the video stream id, see audio and video Stream IDs.
float getAudioVolume()
Returns the audio volume.
void removeEventListener(GLMediaEventListener l)
Removes a GLMediaEventListener to this player.
int getDuration()
Return total duration of stream in msec.
int getWidth()
Returns the width of the video.
static final int MAX_VIDEO_ASYNC
Maximum video frame async of {@value} milliseconds.
State destroy(GL gl)
Releases the GL, stream and other resources, including attached user objects.
boolean setAudioVolume(float v)
Sets the audio volume, [0f..1f].
static final String CameraPropWidth
Camera property {@value}.
static final int STREAM_ID_NONE
Constant {@value} for mute or not available.
boolean useARatioLetterbox()
Returns whether useARatioAdjustment() shall add letter-box space to match aspect-ratio,...
TextureSequence.TextureFrame getLastTexture()
Returns the last updated texture.In case the instance is just initialized, it shall return a TextureF...
CodecID getAudioCodecID()
Warning: Optional information, may not be supported by implementation.
int getAudioFrames()
Warning: Optional information, may not be supported by implementation.
void initGL(GL gl)
Initializes OpenGL related resources.
void setTextureWrapST(int[] wrapST)
Sets the texture min-mag filter, defaults to GL#GL_CLAMP_TO_EDGE.
GLMediaFrameListener[] getFrameListeners()
Return all GLMediaFrameListener of this player.
float getPlaySpeed()
Returns the playback speed.
Object getAttachedObject(String name)
Returns the attached user object for the given name.
String getTitle()
Returns title meta-data from stream, available after State#Initialized is reached after issuing playS...
void setTextureUnit(int u)
Sets the texture unit.
Uri getUri()
Return the stream location, as set by playStream(Uri, int, int, int, int).
CodecID getSubtitleCodecID()
Warning: Optional information, may not be supported by implementation.
String[] getVLangs()
Return an array of detected video stream language codes, matching getVStreams() array and its indices...
void setARatioAdjustment(final boolean v)
Toggles useARatioLetterbox().Default value is implementation specific and toggling is optional....
Chapter[] getChapters()
Returns Chapter meta-data from stream, available after State#Initialized is reached after issuing pla...
static final int TEXTURE_COUNT_DEFAULT
Default texture count, value {@value}.
void setTextureMinMagFilter(int[] minMagFilter)
Sets the texture min-mag filter, defaults to GL#GL_NEAREST.
String getLang(int id)
Return the matching language code of given stream ID, matching one of the stream IDs in getVStreams()...
int getVideoFrames()
Warning: Optional information, may not be supported by implementation.
boolean setPlaySpeed(float rate)
Sets the playback speed.
String toString()
Returns a string representation of this player, incl.
void playStream(final Uri streamLoc, final int vid, final String alang, final int aid, final String slang, final int sid, final int reqTextureCount)
Same as playStream(Uri, int, int, int, int), but providing desired audio- and subtile languages to be...
static final String CameraPropHeight
Camera property {@value}.
void playStream(Uri streamLoc, int vid, int aid, int sid, int textureCount)
Issues asynchronous stream initialization.
int getSID()
Return the subtitle stream id, see audio and video Stream IDs.
int getHeight()
Returns the height of the video.
void addEventListener(GLMediaEventListener l)
Adds a GLMediaEventListener to this player.
boolean useARatioAdjustment()
Returning true indicates texture correction for aspect-ratio in the shader.Graph's Region shader will...
int getNextSID()
Returns the next subtitle stream id, rotates including no-stream.
static final String CameraPropSizeS
Camera property {@value}, size as string, e.g.
StreamException getStreamException()
Returns the StreamException caught in the decoder thread, or null if none occured.
int getAudioPTS()
Returns current audio presentation timestamp (PTS) in milliseconds, try using getPTS().
static final int TEXTURE_COUNT_MIN
Minimum texture count, value {@value}.
int getAID()
Return the audio stream id, see audio and video Stream IDs.
int getNextVID()
Returns the next video stream id, rotates.
TextureSequence.TextureFrame getNextTexture(GL gl)
Returns the next texture to be rendered.Implementation shall return the next frame if available,...
Object detachObject(String name)
Detaches the user object for the given name.
GLMediaEventListener[] getEventListeners()
Return all GLMediaEventListener of this player.
String[] getSLangs()
Return an array of detected subtitle stream language codes, matching getSStreams() array and its indi...
boolean isGLOriented()
Returns true if the video frame is oriented in OpenGL's coordinate system, origin at bottom left.
int getAudioBitrate()
Warning: Optional information, may not be supported by implementation.
long getStreamBitrate()
Warning: Optional information, may not be supported by implementation.
Vec4f getARatioLetterboxBackColor()
Returns useARatioLetterbox() background color for added letter-box space, defaults to transparent zer...
float getFramerate()
Warning: Optional information, may not be supported by implementation.
void printNativeInfo(final PrintStream out)
Print native library information of used implementation to given out PrintStream.
int[] getAStreams()
Return an array of detected audio stream IDs.
int seek(int msec)
Seeks to the new absolute position.
boolean hasStreamID(int id)
Return whether the given stream ID is available, i.e.
CodecID getVideoCodecID()
Warning: Optional information, may not be supported by implementation.
boolean isAudioMuted()
Returns true if audio is muted, i.e.
String getVideoCodec()
Warning: Optional information, may not be supported by implementation.
int getNextAID()
Returns the next audio stream id, rotates.
AudioSink getAudioSink()
If implementation uses a AudioSink, it's instance will be returned.
String getSubtitleCodec()
Warning: Optional information, may not be supported by implementation.
static final String CameraPropRate
Camera property {@value}.
String[] getALangs()
Return an array of detected audio stream language codes, matching getAStreams() array and its indices...
void removeFrameListener(GLMediaFrameListener l)
Removes a GLMediaFrameListener to this player.
Object attachObject(String name, Object obj)
Attaches the user object for the given name.
Chapter getChapter(int msec)
Returns Chapter covering given time position in milliseconds or null if none covers given time.
static final Uri.Encoded CameraInputScheme
Uri scheme name {@value} for camera input.
int[] getSStreams()
Return an array of detected subtitle stream IDs.
SubtitleEventListener getSubtitleEventListener()
Returns the setSubtitleEventListener(SubtitleEventListener) of this player.
State resume()
Starts or resumes the StreamWorker decoding thread.
void setARatioLetterbox(final boolean v, Vec4f backColor)
Toggles useARatioLetterbox().Default value is implementation specific and toggling is optional....
int getVideoBitrate()
Warning: Optional information, may not be supported by implementation.
PTS getPTS()
Returns current System Clock Reference (SCR) presentation timestamp (PTS).
static final int STREAM_ID_AUTO
Constant {@value} for auto or unspecified.
State stop()
Stops streaming and releases the GL, stream and other resources, but keeps attached user objects.
void switchStream(final int vid, final int aid, final int sid)
Switches current playStream(Uri, int, int, int, int) to given stream IDs and continues at same getVid...
void setSubtitleEventListener(SubtitleEventListener l)
Sets the SubtitleEventListener for this player.
String getAudioCodec()
Warning: Optional information, may not be supported by implementation.
void addFrameListener(GLMediaFrameListener l)
Adds a GLMediaFrameListener to this player.
String getPerfString()
Returns a string representation of this player's performance values.
int getVideoPTS()
Returns current video presentation timestamp (PTS) in milliseconds of getLastTexture(),...
void setAudioChannelLimit(final int cc)
Limit maximum supported audio channels by user.
Event listener to notify users of updates regarding the TextureSequence.
Protocol for texture sequences, like animations, movies, etc.