Jogamp
Bump scripts to jre1.8.0_66
[jogl.git] / src / jogl / classes / com / jogamp / opengl / util / av / GLMediaPlayer.java
1 /**
2  * Copyright 2012 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  */
28 package com.jogamp.opengl.util.av;
29
30 import com.jogamp.opengl.GL;
31 import com.jogamp.opengl.GLEventListener;
32 import com.jogamp.opengl.GLException;
33
34 import jogamp.opengl.Debug;
35
36 import com.jogamp.common.net.Uri;
37 import com.jogamp.opengl.util.texture.Texture;
38 import com.jogamp.opengl.util.texture.TextureSequence;
39 import com.jogamp.opengl.util.TimeFrameI;
40
41 /**
42  * GLMediaPlayer interface specifies a {@link TextureSequence} state machine
43  * using a multiplexed audio/video stream as it's source.
44  * <p>
45  * Audio maybe supported and played back internally or via an {@link AudioSink} implementation.
46  * </p>
47  * <p>
48  * Audio and video streams can be selected or muted via {@link #initStream(Uri, int, int, int)}
49  * using the appropriate <a href="#streamIDs">stream id</a>'s.
50  * </p>
51  * <p>
52  * Camera input can be selected using the {@link #CameraInputScheme} Uri.
53  * </p>
54  *
55  * <a name="streamworker"><h5><i>StreamWorker</i> Decoding Thread</h5></a>
56  * <p>
57  * Most of the stream processing is performed on the decoding thread, a.k.a. <i>StreamWorker</i>:
58  * <ul>
59  *   <li>Stream initialization triggered by {@link #initStream(Uri, int, int, int) initStream(..)} - User gets notified whether the stream has been initialized or not via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.</li>
60  *   <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>
61  *   <li>Caught <a href="#streamerror">exceptions on the decoding thread</a> are delivered as {@link StreamException}s.</li>
62  * </ul>
63  * <i>StreamWorker</i> generates it's own {@link GLContext}, shared with the one passed to {@link #initGL(GL)}.
64  * The shared {@link GLContext} allows the decoding thread to push the video frame data directly into
65  * the designated {@link TextureFrame}, later returned via {@link #getNextTexture(GL)} and used by the user.
66  * </p>
67  * <a name="streamerror"><h7><i>StreamWorker</i> Error Handling</h7></a>
68  * <p>
69  * Caught exceptions on <a href="#streamworker">StreamWorker</a> are delivered as {@link StreamException}s,
70  * which either degrades the {@link State} to {@link State#Uninitialized} or {@link State#Paused}.
71  * </p>
72  * <p>
73  * An occurring {@link StreamException} triggers a {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} event,
74  * which can be listened to via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long)}.
75  * </p>
76  * <p>
77  * An occurred {@link StreamException} can be read via {@link #getStreamException()}.
78  * </p>
79  *
80  * </p>
81  * <a name="lifecycle"><h5>GLMediaPlayer Lifecycle</h5></a>
82  * <p>
83  * <table border="1">
84  *   <tr><th>Action</th>                                               <th>{@link State} Before</th>                                        <th>{@link State} After</th>                                                                                                       <th>{@link GLMediaEventListener Event}</th></tr>
85  *   <tr><td>{@link #initStream(Uri, 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 GLMediaEventListener#EVENT_CHANGE_INIT EVENT_CHANGE_INIT} or ( {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr>
86  *   <tr><td>{@link #initGL(GL)}</td>                                  <td>{@link State#Initialized Initialized}</td>                       <td>{@link State#Paused Paused}, , {@link State#Uninitialized Uninitialized}</td>                                                  <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE} or ( {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr>
87  *   <tr><td>{@link #play()}</td>                                      <td>{@link State#Paused Paused}</td>                                 <td>{@link State#Playing Playing}</td>                                                                                             <td>{@link GLMediaEventListener#EVENT_CHANGE_PLAY EVENT_CHANGE_PLAY}</td></tr>
88  *   <tr><td>{@link #pause(boolean)}</td>                              <td>{@link State#Playing Playing}</td>                               <td>{@link State#Paused Paused}</td>                                                                                               <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr>
89  *   <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>
90  *   <tr><td>{@link #getNextTexture(GL)}</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>
91  *   <tr><td>{@link #getLastTexture()}</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>
92  *   <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 GLMediaEventListener#EVENT_CHANGE_EOS EVENT_CHANGE_EOS} + {@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr>
93  *   <tr><td>{@link StreamException}</td>                              <td>ANY</td>                                                         <td>{@link State#Paused Paused}, {@link State#Uninitialized Uninitialized}</td>                                                    <td>{@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + ( {@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE} or {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr>
94  *   <tr><td>{@link #destroy(GL)}</td>                                 <td>ANY</td>                                                         <td>{@link State#Uninitialized Uninitialized}</td>                                                                                 <td>{@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT}</td></tr>
95  * </table>
96  * </p>
97  *
98  * <a name="streamIDs"><h5>Audio and video Stream IDs</h5></a>
99  * <p>
100  * <table border="1">
101  *   <tr><th>value</th>                    <th>request</th>             <th>get</th></tr>
102  *   <tr><td>{@link #STREAM_ID_NONE}</td>  <td>mute</td>                <td>not available</td></tr>
103  *   <tr><td>{@link #STREAM_ID_AUTO}</td>  <td>auto</td>                <td>unspecified</td></tr>
104  *   <tr><td>&ge;0</td>                    <td>specific stream</td>     <td>specific stream</td></tr>
105  * </table>
106  * </p>
107  * <p>
108  * Current implementations (check each API doc link for details):
109  * <ul>
110  *   <li>{@link jogamp.opengl.util.av.NullGLMediaPlayer}</li>
111  *   <li>{@link jogamp.opengl.util.av.impl.OMXGLMediaPlayer}</li>
112  *   <li>{@link jogamp.opengl.util.av.impl.FFMPEGMediaPlayer}</li>
113  *   <li>{@link jogamp.opengl.android.av.AndroidGLMediaPlayerAPI14}</li>
114  * </ul>
115  * </p>
116  * <p>
117  * Implementations of this interface must implement:
118  * <pre>
119  *    public static final boolean isAvailable();
120  * </pre>
121  * to be properly considered by {@link GLMediaPlayerFactory#create(ClassLoader, String)}
122  * and {@link GLMediaPlayerFactory#createDefault()}.
123  * </p>
124  * <a name="timestampaccuracy"><h5>Timestamp Accuracy</h5></a>
125  * <p>
126  * <p>
127  * Timestamp type and value range has been chosen to suit embedded CPUs
128  * and characteristics of audio and video streaming. See {@link TimeFrameI}.
129  * </p>
130  *
131  * <a name="synchronization"><h5>Audio and video synchronization</h5></a>
132  * <p>
133  * The class follows a passive A/V synchronization pattern.
134  * Audio is being untouched, while {@link #getNextTexture(GL)} delivers a new video frame
135  * only, if its timestamp is less than {@link #MAXIMUM_VIDEO_ASYNC} ahead of <i>time</i>.
136  * If its timestamp is more than {@link #MAXIMUM_VIDEO_ASYNC} ahead of <i>time</i>,
137  * the previous frame is returned.
138  * If its timestamp is more than {@link #MAXIMUM_VIDEO_ASYNC} after <i>time</i>,
139  * the frame is dropped and the next frame is being fetched.
140  * </p>
141  * <p>
142  * https://en.wikipedia.org/wiki/Audio_to_video_synchronization
143  * <pre>
144  *   d_av = v_pts - a_pts;
145  * </pre>
146  * </p>
147  * <p>
148  * Recommendation of audio/video pts time lead/lag at production:
149  * <ul>
150  *   <li>Overall:    +40ms and -60ms  audio ahead video / audio after video</li>
151  *   <li>Each stage:  +5ms and -15ms. audio ahead video / audio after video</li>
152  * </ul>
153  * </p>
154  * <p>
155  * Recommendation of av pts time lead/lag at presentation:
156  * <ul>
157  *   <li>TV:         +15ms and -45ms. audio ahead video / audio after video.</li>
158  *   <li>Film:       +22ms and -22ms. audio ahead video / audio after video.</li>
159  * </ul>
160  * </p>
161  *
162  * <a name="teststreams"><h5>Test Streams</h5></a>
163  * <p>
164  * <table border="1">
165  *   <tr><th colspan=5>Big Buck Bunny 24f 16:9</th></tr>
166  *   <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>
167  *   <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>
168  *   <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>
169  *   <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>
170  *   <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>
171  *   <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>
172  *   <tr><th colspan=5>WebM/Matroska (vp8/vorbis)</th></tr>
173  *   <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>
174  *   <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>
175  *   <tr><th colspan=5>You Tube http/rtsp</th></tr>
176  *   <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>
177  *   <tr><th colspan=5>Audio/Video Sync</th></tr>
178  *   <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>
179  *   <tr><td>Audio-Video-Sync-Test-Calibration-23.98fps-24fps</td><td colspan=4>https://www.youtube.com/watch?v=cGgf_dbDMsw</td></tr>
180  *   <tr><td>sound_in_sync_test</td><td colspan=4>https://www.youtube.com/watch?v=O-zIZkhXNLE</td></tr>
181  *   <!-- <tr><td> title </td><td>1080p</td><td>mpeg4<td>ac3 48000Hz 5.1 chan</td><td> url </td></tr> -->
182  *   <!-- <tr><td> title </td><td colspan=3> url1 </td><td> url2 </td></tr>
183  * </table>
184  * </p>
185  * <p>
186  * Since 2.3.0 this interface uses {@link Uri} instead of {@link java.net.URI}.
187  * </p>
188  */
189 public interface GLMediaPlayer extends TextureSequence {
190     public static final boolean DEBUG = Debug.debug("GLMediaPlayer");
191     public static final boolean DEBUG_NATIVE = Debug.debug("GLMediaPlayer.Native");
192
193     /** Default texture count, value {@value}. */
194     public static final int TEXTURE_COUNT_DEFAULT = 4;
195
196     /** Minimum texture count, value {@value}. Using the minimum texture count disables multi-threaded decoding. */
197     public static final int TEXTURE_COUNT_MIN = 1;
198
199     /** Constant {@value} for <i>mute</i> or <i>not available</i>. See <a href="#streamIDs">Audio and video Stream IDs</a>. */
200     public static final int STREAM_ID_NONE = -2;
201     /** Constant {@value} for <i>auto</i> or <i>unspecified</i>. See <a href="#streamIDs">Audio and video Stream IDs</a>. */
202     public static final int STREAM_ID_AUTO = -1;
203
204     /**
205      * {@link Uri#scheme Uri scheme} name {@value} for camera input. E.g. <code>camera:/0</code>
206      * for the 1st camera device.
207      * <p>
208      * The {@link Uri#path Uri path} is being used to identify the camera (<i>&lt;id&gt;</i>),
209      * where the root fwd-slash is being cut-off.
210      * </p>
211      * <p>
212      * The <i>&lt;id&gt;</i> is usually an integer value indexing the camera
213      * ranging from [0..<i>max-number</i>].
214      * </p>
215      * <p>
216      * The <i>&lt;somewhere&gt;</i> is usually empty, since it would imply a networking camera protocol.
217      * </p>
218      * <p>
219      * The {@link Uri#query Uri query} is used to pass options to the camera
220      * using <i>;</i> as the separator. The latter avoids trouble w/ escaping.
221      * </p>
222      * <pre>
223      *    camera:/&lt;id&gt;
224      *    camera:/&lt;id&gt;?width=640;height=480;rate=15
225      *    camera:/&lt;id&gt;?size=640x480;rate=15
226      *    camera://&lt;somewhere&gt;/&lt;id&gt;
227      *    camera://&lt;somewhere&gt;/&lt;id&gt;?width=640;height=480;rate=15
228      *    camera://&lt;somewhere&gt;/&lt;id&gt;?size=640x480;rate=15
229      *    camera:///&lt;id&gt;?width=640;height=480;rate=15
230      *    camera:///&lt;id&gt;?size=640x480;rate=15
231      * </pre>
232      * <pre>
233      *  Uri: [scheme:][//authority][path][?query][#fragment]
234      *  w/ authority: [user-info@]host[:port]
235      *  Note: 'path' starts w/ fwd slash
236      * </pre>
237      * </p>
238      */
239     public static final Uri.Encoded CameraInputScheme = Uri.Encoded.cast("camera");
240     /** Camera property {@value}, size as string, e.g. <code>1280x720</code>, <code>hd720</code>. May not be supported on all platforms. See {@link #CameraInputScheme}. */
241     public static final String CameraPropSizeS = "size";
242     /** Camera property {@value}. See {@link #CameraInputScheme}. */
243     public static final String CameraPropWidth = "width";
244     /** Camera property {@value}. See {@link #CameraInputScheme}. */
245     public static final String CameraPropHeight = "height";
246     /** Camera property {@value}. See {@link #CameraInputScheme}. */
247     public static final String CameraPropRate = "rate";
248
249     /** Maximum video frame async of {@value} milliseconds. */
250     public static final int MAXIMUM_VIDEO_ASYNC = 22;
251
252     /**
253      * A StreamException encapsulates a caught exception in the decoder thread, a.k.a <i>StreamWorker</i>,
254      * see See <a href="#streamerror"><i>StreamWorker</i> Error Handling</a>.
255      */
256     @SuppressWarnings("serial")
257     public static class StreamException extends Exception {
258         public StreamException(final Throwable cause) {
259             super(cause);
260         }
261         public StreamException(final String message, final Throwable cause) {
262             super(message, cause);
263         }
264     }
265
266     /**
267      * {@inheritDoc}
268      * <p>
269      * As the contract of {@link TexSeqEventListener} requests,
270      * implementations of {@link GLMediaEventListener} shall also:
271      * <ul>
272      *   <li>off-load complex or {@link GLMediaPlayer} commands on another thread, or</li>
273      *   <li>simply changing a volatile state of their {@link GLEventListener} implementation.</li>
274      * </ul>
275      * </p>
276      */
277     public interface GLMediaEventListener extends TexSeqEventListener<GLMediaPlayer> {
278
279         /** State changed to {@link State#Initialized}. See <a href="#lifecycle">Lifecycle</a>.*/
280         static final int EVENT_CHANGE_INIT   = 1<<0;
281         /** State changed to {@link State#Uninitialized}. See <a href="#lifecycle">Lifecycle</a>.*/
282         static final int EVENT_CHANGE_UNINIT = 1<<1;
283         /** State changed to {@link State#Playing}. See <a href="#lifecycle">Lifecycle</a>.*/
284         static final int EVENT_CHANGE_PLAY   = 1<<2;
285         /** State changed to {@link State#Paused}. See <a href="#lifecycle">Lifecycle</a>.*/
286         static final int EVENT_CHANGE_PAUSE  = 1<<3;
287         /** End of stream reached. See <a href="#lifecycle">Lifecycle</a>.*/
288         static final int EVENT_CHANGE_EOS    = 1<<4;
289         /** An error occurred, e.g. during off-thread initialization. See {@link StreamException} and <a href="#lifecycle">Lifecycle</a>. */
290         static final int EVENT_CHANGE_ERR    = 1<<5;
291
292         /** Stream video id change. */
293         static final int EVENT_CHANGE_VID    = 1<<16;
294         /** Stream audio id change. */
295         static final int EVENT_CHANGE_AID    = 1<<17;
296         /** TextureFrame size or vertical flip change. */
297         static final int EVENT_CHANGE_SIZE   = 1<<18;
298         /** Stream fps change. */
299         static final int EVENT_CHANGE_FPS    = 1<<19;
300         /** Stream bps change. */
301         static final int EVENT_CHANGE_BPS    = 1<<20;
302         /** Stream length change. */
303         static final int EVENT_CHANGE_LENGTH = 1<<21;
304         /** Stream codec change. */
305         static final int EVENT_CHANGE_CODEC  = 1<<22;
306
307         /**
308          * @param mp the event source
309          * @param event_mask the changes attributes
310          * @param when system time in msec.
311          */
312         public void attributesChanged(GLMediaPlayer mp, int event_mask, long when);
313     }
314
315     /**
316      * See <a href="#lifecycle">Lifecycle</a>.
317      */
318     public enum State {
319         /** Uninitialized player, no resources shall be hold. */
320         Uninitialized(0),
321         /** Stream has been initialized, user may play or call {@link #initGL(GL)}. */
322         Initialized(1),
323         /** Stream is playing. */
324         Playing(2),
325         /** Stream is pausing. */
326         Paused(3);
327
328         public final int id;
329
330         State(final int id){
331             this.id = id;
332         }
333     }
334
335     public int getTextureCount();
336
337     /** Sets the texture unit. Defaults to 0. */
338     public void setTextureUnit(int u);
339
340     /** Sets the texture min-mag filter, defaults to {@link GL#GL_NEAREST}. */
341     public void setTextureMinMagFilter(int[] minMagFilter);
342     /** Sets the texture min-mag filter, defaults to {@link GL#GL_CLAMP_TO_EDGE}. */
343     public void setTextureWrapST(int[] wrapST);
344
345     /**
346      * Issues asynchronous stream initialization.
347      * <p>
348      * <a href="#lifecycle">Lifecycle</a>: {@link State#Uninitialized} -> {@link State#Initialized}<sup><a href="#streamworker">1</a></sup> or {@link State#Uninitialized}
349      * </p>
350      * <p>
351      * {@link State#Initialized} is reached asynchronous,
352      * i.e. user gets notified via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.
353      * </p>
354      * <p>
355      * A possible caught asynchronous {@link StreamException} while initializing the stream off-thread
356      * will be thrown at {@link #initGL(GL)}.
357      * </p>
358      * <p>
359      * Muted audio can be achieved by passing {@link #STREAM_ID_NONE} to <code>aid</code>.
360      * </p>
361      * <p>
362      * Muted video can be achieved by passing {@link #STREAM_ID_NONE} to <code>vid</code>,
363      * in which case <code>textureCount</code> is ignored as well as the passed GL object of the subsequent {@link #initGL(GL)} call.
364      * </p>
365      * @param streamLoc the stream location
366      * @param vid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
367      * @param aid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>
368      * @param textureCount desired number of buffered textures to be decoded off-thread, will be validated by implementation.
369      *        The minimum value is {@link #TEXTURE_COUNT_DEFAULT}.
370      *        Ignored if video is muted.
371      * @throws IllegalStateException if not invoked in {@link State#Uninitialized}
372      * @throws IllegalArgumentException if arguments are invalid
373      * @since 2.3.0
374      */
375     public void initStream(Uri streamLoc, int vid, int aid, int textureCount) throws IllegalStateException, IllegalArgumentException;
376
377     /**
378      * Returns the {@link StreamException} caught in the decoder thread, or <code>null</code> if none occured.
379      * <p>
380      * Method clears the cached {@link StreamException}, hence an immediate subsequent call will return <code>null</code>.
381      * </p>
382      * @see GLMediaEventListener#EVENT_CHANGE_ERR
383      * @see StreamException
384      */
385     public StreamException getStreamException();
386
387     /**
388      * Initializes OpenGL related resources.
389      * <p>
390      * <a href="#lifecycle">Lifecycle</a>: {@link State#Initialized} -> {@link State#Paused} or {@link State#Initialized}
391      * </p>
392      * Argument <code>gl</code> is ignored if video is muted, see {@link #initStream(Uri, int, int, int)}.
393      *
394      * @param gl current GL object. Maybe <code>null</code>, for audio only.
395      * @throws IllegalStateException if not invoked in {@link State#Initialized}.
396      * @throws StreamException forwarded from the off-thread stream initialization
397      * @throws GLException in case of difficulties to initialize the GL resources
398      */
399     public void initGL(GL gl) throws IllegalStateException, StreamException, GLException;
400
401     /**
402      * If implementation uses a {@link AudioSink}, it's instance will be returned.
403      * <p>
404      * The {@link AudioSink} instance is available after {@link #initStream(Uri, int, int, int)},
405      * if used by implementation.
406      * </p>
407      */
408     public AudioSink getAudioSink();
409
410     /**
411      * Releases the GL, stream and other resources, including {@link #attachObject(String, Object) attached user objects}.
412      * <p>
413      * <a href="#lifecycle">Lifecycle</a>: <code>ANY</code> -> {@link State#Uninitialized}
414      * </p>
415      */
416     public State destroy(GL gl);
417
418     /**
419      * Sets the playback speed.
420      * <p>
421      * To simplify test, play speed is  <i>normalized</i>, i.e.
422      * <ul>
423      *   <li><code>1.0f</code>: if <code> Math.abs(1.0f - rate) < 0.01f </code></li>
424      * </ul>
425      * </p>
426      * @return true if successful, otherwise false, i.e. due to unsupported value range of implementation.
427      */
428     public boolean setPlaySpeed(float rate);
429
430     /** Returns the playback speed. */
431     public float getPlaySpeed();
432
433     /**
434      * Sets the audio volume, [0f..1f].
435      * <p>
436      * To simplify test, volume is <i>normalized</i>, i.e.
437      * <ul>
438      *   <li><code>0.0f</code>: if <code> Math.abs(v) < 0.01f </code></li>
439      *   <li><code>1.0f</code>: if <code> Math.abs(1.0f - v) < 0.01f </code></li>
440      * </ul>
441      * </p>
442      * @return true if successful, otherwise false, i.e. due to unsupported value range of implementation.
443      */
444     public boolean setAudioVolume(float v);
445
446     /** Returns the audio volume. */
447     public float getAudioVolume();
448
449     /**
450      * Starts or resumes the <i>StreamWorker</i> decoding thread.
451      * <p>
452      * <a href="#lifecycle">Lifecycle</a>: {@link State#Paused} -> {@link State#Playing}
453      * </p>
454      */
455     public State play();
456
457     /**
458      * Pauses the <i>StreamWorker</i> decoding thread.
459      * <p>
460      * <a href="#lifecycle">Lifecycle</a>: {@link State#Playing} -> {@link State#Paused}
461      * </p>
462      * <p>
463      * If a <i>new</i> frame is desired after the next {@link #play()} call,
464      * e.g. to make a snapshot of a camera input stream,
465      * <code>flush</code> shall be set to <code>true</code>.
466      * </p>
467      * @param flush if <code>true</code> flushes the video and audio buffers, otherwise keep them intact.
468      */
469     public State pause(boolean flush);
470
471     /**
472      * Seeks to the new absolute position. The <i>StreamWorker</i> decoding thread
473      * is paused while doing so and the A/V buffers are flushed.
474      * <p>
475      * Allowed in state {@link State#Playing} and {@link State#Paused}, otherwise ignored,
476      * see <a href="#lifecycle">Lifecycle</a>.
477      * </p>
478      *
479      * @param msec absolute desired time position in milliseconds
480      * @return time current position in milliseconds, after seeking to the desired position
481      **/
482     public int seek(int msec);
483
484     /**
485      * See <a href="#lifecycle">Lifecycle</a>.
486      * @return the current state, either {@link State#Uninitialized}, {@link State#Initialized}, {@link State#Playing} or {@link State#Paused}
487      */
488     public State getState();
489
490     /**
491      * Return the video stream id, see <a href="#streamIDs">audio and video Stream IDs</a>.
492      */
493     public int getVID();
494
495     /**
496      * Return the audio stream id, see <a href="#streamIDs">audio and video Stream IDs</a>.
497      */
498     public int getAID();
499
500     /**
501      * @return the current decoded frame count since {@link #play()} and {@link #seek(int)}
502      *         as increased by {@link #getNextTexture(GL)} or the decoding thread.
503      */
504     public int getDecodedFrameCount();
505
506     /**
507      * @return the current presented frame count since {@link #play()} and {@link #seek(int)}
508      *         as increased by {@link #getNextTexture(GL)} for new frames.
509      */
510     public int getPresentedFrameCount();
511
512     /**
513      * @return current video presentation timestamp (PTS) in milliseconds of {@link #getLastTexture()}
514      **/
515     public int getVideoPTS();
516
517     /**
518      * @return current audio presentation timestamp (PTS) in milliseconds.
519      **/
520     public int getAudioPTS();
521
522     /**
523      * {@inheritDoc}
524      * <p>
525      * See <a href="#synchronization">audio and video synchronization</a>.
526      * </p>
527      * @throws IllegalStateException if not invoked in {@link State#Paused} or {@link State#Playing}
528      */
529     @Override
530     public TextureSequence.TextureFrame getLastTexture() throws IllegalStateException;
531
532     /**
533      * {@inheritDoc}
534      *
535      * <p>
536      * In case the current state is not {@link State#Playing}, {@link #getLastTexture()} is returned.
537      * </p>
538      * <p>
539      * See <a href="#synchronization">audio and video synchronization</a>.
540      * </p>
541      * @throws IllegalStateException if not invoked in {@link State#Paused} or {@link State#Playing}
542      *
543      * @see #addEventListener(GLMediaEventListener)
544      * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, TextureFrame, long)
545      */
546     @Override
547     public TextureSequence.TextureFrame getNextTexture(GL gl) throws IllegalStateException;
548
549     /**
550      * Return the stream location, as set by {@link #initStream(Uri, int, int, int)}.
551      * @since 2.3.0
552      */
553     public Uri getUri();
554
555     /**
556      * <i>Warning:</i> Optional information, may not be supported by implementation.
557      * @return the code of the video stream, if available
558      */
559     public String getVideoCodec();
560
561     /**
562      * <i>Warning:</i> Optional information, may not be supported by implementation.
563      * @return the code of the audio stream, if available
564      */
565     public String getAudioCodec();
566
567     /**
568      * <i>Warning:</i> Optional information, may not be supported by implementation.
569      * @return the total number of video frames
570      */
571     public int getVideoFrames();
572
573     /**
574      * <i>Warning:</i> Optional information, may not be supported by implementation.
575      * @return the total number of audio frames
576      */
577     public int getAudioFrames();
578
579     /**
580      * @return total duration of stream in msec.
581      */
582     public int getDuration();
583
584     /**
585      * <i>Warning:</i> Optional information, may not be supported by implementation.
586      * @return the overall bitrate of the stream.
587      */
588     public long getStreamBitrate();
589
590     /**
591      * <i>Warning:</i> Optional information, may not be supported by implementation.
592      * @return video bitrate
593      */
594     public int getVideoBitrate();
595
596     /**
597      * <i>Warning:</i> Optional information, may not be supported by implementation.
598      * @return the audio bitrate
599      */
600     public int getAudioBitrate();
601
602     /**
603      * <i>Warning:</i> Optional information, may not be supported by implementation.
604      * @return the framerate of the video
605      */
606     public float getFramerate();
607
608     /**
609      * Returns <code>true</code> if the video frame is oriented in
610      * OpenGL's coordinate system, <i>origin at bottom left</i>.
611      * <p>
612      * Otherwise returns <code>false</code>, i.e.
613      * video frame is oriented <i>origin at top left</i>.
614      * </p>
615      * <p>
616      * <code>false</code> is the default assumption for videos,
617      * but user shall not rely on.
618      * </p>
619      * <p>
620      * <code>false</code> GL orientation leads to
621      * {@link Texture#getMustFlipVertically()} == <code>true</code>,
622      * as reflected by all {@link TextureFrame}'s {@link Texture}s
623      * retrieved via {@link #getLastTexture()} or {@link #getNextTexture(GL)}.
624      * </p>
625      */
626     public boolean isGLOriented();
627
628     /** Returns the width of the video. */
629     public int getWidth();
630
631     /** Returns the height of the video. */
632     public int getHeight();
633
634     /** Returns a string represantation of this player, incl. state and audio/video details. */
635     @Override
636     public String toString();
637
638     /** Returns a string represantation of this player's performance values. */
639     public String getPerfString();
640
641     /** Adds a {@link GLMediaEventListener} to this player. */
642     public void addEventListener(GLMediaEventListener l);
643
644     /** Removes a {@link GLMediaEventListener} to this player. */
645     public void removeEventListener(GLMediaEventListener l);
646
647     /** Return all {@link GLMediaEventListener} of this player. */
648     public GLMediaEventListener[] getEventListeners();
649
650     /**
651      * Returns the attached user object for the given name.
652      */
653     public Object getAttachedObject(String name);
654
655     /**
656      * Attaches the user object for the given name.
657      * Returns the previously set object, may be null.
658      */
659     public Object attachObject(String name, Object obj);
660
661     /**
662      * Detaches the user object for the given name.
663      * Returns the previously set object, may be null.
664      */
665     public Object detachObject(String name);
666
667 }
http://JogAmp.org git info: FAQ, tutorial and man pages.