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 
29 package jogamp.opengl.util.av.impl;
30 
31 import java.io.IOException;
32 
33 import com.jogamp.opengl.GL;
34 import com.jogamp.opengl.GLException;
35 
36 import com.jogamp.opengl.egl.EGL;
37 import com.jogamp.opengl.util.texture.TextureSequence;
38 
39 import jogamp.opengl.util.av.EGLMediaPlayerImpl;
40 
41 /**
42  * OpenMAX IL implementation. This implementation is currently not tested
43  * due to lack of an available device or working <i>software</i> implementation.
44  * It is kept alive through all changes in the hope of a later availability though.
45  */
46 public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
47     static final boolean available;
48 
49     static {
50         available = false;
51         /** FIXME!
52         // OMX binding is included in jogl_desktop and jogl_mobile
53         GLProfile.initSingleton();
54         available = initIDs0(); */
55     }
56 
isAvailable()57     public static final boolean isAvailable() { return available; }
58 
59     protected long moviePtr = 0;
60 
OMXGLMediaPlayer()61     public OMXGLMediaPlayer() {
62         super(TextureType.KHRImage, true);
63         if(!available) {
64             throw new RuntimeException("OMXGLMediaPlayer not available");
65         }
66         initOMX();
67     }
68 
initOMX()69     protected void initOMX() {
70         moviePtr = _createInstance();
71         if(0==moviePtr) {
72             throw new GLException("Couldn't create OMXInstance");
73         }
74     }
75 
76     @Override
createTexImage(final GL gl, final int texName)77     protected TextureSequence.TextureFrame createTexImage(final GL gl, final int texName) {
78         final EGLTextureFrame eglTex = (EGLTextureFrame) super.createTexImage(gl, texName);
79         _setStreamEGLImageTexture2D(moviePtr, texName, eglTex.getImage(), eglTex.getSync());
80         return eglTex;
81     }
82 
83     @Override
destroyTexFrame(final GL gl, final TextureSequence.TextureFrame imgTex)84     protected void destroyTexFrame(final GL gl, final TextureSequence.TextureFrame imgTex) {
85         super.destroyTexFrame(gl, imgTex);
86     }
87 
88     @Override
destroyImpl(final GL gl)89     protected void destroyImpl(final GL gl) {
90         if (moviePtr != 0) {
91             _stop(moviePtr);
92             _detachVideoRenderer(moviePtr);
93             _destroyInstance(moviePtr);
94             moviePtr = 0;
95         }
96     }
97 
98     @Override
initStreamImpl(final int vid, final int aid)99     protected void initStreamImpl(final int vid, final int aid) throws IOException {
100         if(0==moviePtr) {
101             throw new GLException("OMX native instance null");
102         }
103         if( !getUri().isFileScheme() ) {
104             throw new IOException("Only file schemes are allowed: "+getUri());
105         }
106         final String path=getUri().path.decode();
107         if(DEBUG) {
108             System.out.println("initGLStream: clean path "+path);
109         }
110 
111         if(DEBUG) {
112             System.out.println("initGLStream: p1 "+this);
113         }
114         _setStream(moviePtr, getTextureCount(), path);
115         if(DEBUG) {
116             System.out.println("initGLStream: p2 "+this);
117         }
118     }
119     @Override
initGLImpl(final GL gl)120     protected final void initGLImpl(final GL gl) throws IOException, GLException {
121         // NOP
122         setIsGLOriented(true);
123     }
124 
125     @Override
getAudioPTSImpl()126     protected int getAudioPTSImpl() {
127         return 0!=moviePtr ? _getCurrentPosition(moviePtr) : 0;
128     }
129 
130     @Override
setPlaySpeedImpl(final float rate)131     protected boolean setPlaySpeedImpl(final float rate) {
132         if(0==moviePtr) {
133             throw new GLException("OMX native instance null");
134         }
135         _setPlaySpeed(moviePtr, rate);
136         return true;
137     }
138 
139     @Override
playImpl()140     public synchronized boolean playImpl() {
141         if(0==moviePtr) {
142             return false;
143         }
144         _play(moviePtr);
145         return true;
146     }
147 
148     /** @return time position after issuing the command */
149     @Override
pauseImpl()150     public synchronized boolean pauseImpl() {
151         if(0==moviePtr) {
152             return false;
153         }
154         _pause(moviePtr);
155         return true;
156     }
157 
158     /** @return time position after issuing the command */
159     @Override
seekImpl(final int msec)160     protected int seekImpl(final int msec) {
161         if(0==moviePtr) {
162             throw new GLException("OMX native instance null");
163         }
164         return _seek(moviePtr, msec);
165     }
166 
167     @Override
getNextTextureImpl(final GL gl, final TextureFrame nextFrame)168     protected int getNextTextureImpl(final GL gl, final TextureFrame nextFrame) {
169         if(0==moviePtr) {
170             throw new GLException("OMX native instance null");
171         }
172         final int nextTex = _getNextTextureID(moviePtr, true);
173         if(0 < nextTex) {
174             // FIXME set pts !
175             /* FIXME
176             final TextureSequence.TextureFrame eglImgTex =
177                     texFrameMap.get(new Integer(_getNextTextureID(moviePtr, blocking)));
178             if(null!=eglImgTex) {
179                 lastTex = eglImgTex;
180             } */
181         }
182         return 0; // FIXME: return pts
183     }
184 
replaceAll(final String orig, final String search, final String repl)185     private String replaceAll(final String orig, final String search, final String repl) {
186         final StringBuilder dest = new StringBuilder();
187         // In case replaceAll / java.util.regex.* is not supported (-> CVM)
188         int i=0,j;
189         while((j=orig.indexOf(search, i))>=0) {
190             dest.append(orig.substring(i, j));
191             dest.append(repl);
192             i=j+1;
193         }
194         return dest.append(orig.substring(i, orig.length())).toString();
195     }
196 
errorCheckEGL(final String s)197     private void errorCheckEGL(final String s) {
198         int e;
199         if( (e=EGL.eglGetError()) != EGL.EGL_SUCCESS ) {
200             System.out.println("EGL Error: ("+s+"): 0x"+Integer.toHexString(e));
201         }
202     }
203 
initIDs0()204     private static native boolean initIDs0();
_createInstance()205     private native long _createInstance();
_destroyInstance(long moviePtr)206     private native void _destroyInstance(long moviePtr);
207 
_detachVideoRenderer(long moviePtr)208     private native void _detachVideoRenderer(long moviePtr); // stop before
_attachVideoRenderer(long moviePtr)209     private native void _attachVideoRenderer(long moviePtr); // detach before
_setStream(long moviePtr, int textureNum, String path)210     private native void _setStream(long moviePtr, int textureNum, String path);
_activateStream(long moviePtr)211     private native void _activateStream(long moviePtr);
212 
_setStreamEGLImageTexture2D(long moviePtr, int tex, long image, long sync)213     private native void _setStreamEGLImageTexture2D(long moviePtr, int tex, long image, long sync);
_seek(long moviePtr, int position)214     private native int  _seek(long moviePtr, int position);
_setPlaySpeed(long moviePtr, float rate)215     private native void _setPlaySpeed(long moviePtr, float rate);
_play(long moviePtr)216     private native void _play(long moviePtr);
_pause(long moviePtr)217     private native void _pause(long moviePtr);
_stop(long moviePtr)218     private native void _stop(long moviePtr);
_getNextTextureID(long moviePtr, boolean blocking)219     private native int  _getNextTextureID(long moviePtr, boolean blocking);
_getCurrentPosition(long moviePtr)220     private native int  _getCurrentPosition(long moviePtr);
221 }
222 
223