Guest User

GLMediaPlayer initStream deadlock

a guest
Jan 20th, 2016
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.11 KB | None | 0 0
  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 com.jogamp.opengl.test.junit.jogl.demos.es2.av;
  30.  
  31. import java.io.File;
  32. import java.io.IOException;
  33. import java.net.URI;
  34. import java.net.URISyntaxException;
  35. import java.nio.FloatBuffer;
  36.  
  37. import com.jogamp.common.net.Uri;
  38. import com.jogamp.common.os.Platform;
  39. import com.jogamp.newt.opengl.GLWindow;
  40. import com.jogamp.opengl.GL;
  41. import com.jogamp.opengl.GL2ES2;
  42. import com.jogamp.opengl.GLAutoDrawable;
  43. import com.jogamp.opengl.GLCapabilities;
  44. import com.jogamp.opengl.GLES2;
  45. import com.jogamp.opengl.GLEventListener;
  46. import com.jogamp.opengl.GLException;
  47. import com.jogamp.opengl.GLExtensions;
  48. import com.jogamp.opengl.GLProfile;
  49. import com.jogamp.opengl.GLUniformData;
  50. import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
  51. import com.jogamp.opengl.util.FPSAnimator;
  52. import com.jogamp.opengl.util.GLArrayDataServer;
  53. import com.jogamp.opengl.util.PMVMatrix;
  54. import com.jogamp.opengl.util.av.GLMediaPlayer;
  55. import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
  56. import com.jogamp.opengl.util.glsl.ShaderCode;
  57. import com.jogamp.opengl.util.glsl.ShaderProgram;
  58. import com.jogamp.opengl.util.glsl.ShaderState;
  59. import com.jogamp.opengl.util.texture.Texture;
  60. import com.jogamp.opengl.util.texture.TextureCoords;
  61. import com.jogamp.opengl.util.texture.TextureSequence;
  62. import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
  63.  
  64. /**
  65.  * Simple planar movie player w/ orthogonal 1:1 projection.
  66.  */
  67. public class MovieSimpleDeadlock implements GLEventListener {
  68.     public static final int EFFECT_NORMAL                  =    0;
  69.     public static final int EFFECT_GRADIENT_BOTTOM2TOP     = 1<<1;
  70.     public static final int EFFECT_TRANSPARENT             = 1<<3;
  71.  
  72.     public static final String WINDOW_KEY = "window";
  73.     public static final String PLAYER = "player";
  74.  
  75.     private long startTime;
  76.     private int effects = EFFECT_NORMAL;
  77.     private float alpha = 1.0f;
  78.  
  79.     private GLMediaPlayer mPlayer;
  80.     private boolean mPlayerScaleOrig;
  81.     private float[] verts = null;
  82.     private GLArrayDataServer interleavedVBO;
  83.     private volatile boolean resetGLState = false;
  84.  
  85.     private ShaderState st;
  86.     private PMVMatrix pmvMatrix;
  87.     private GLUniformData pmvMatrixUniform;
  88.     private static final String shaderBasename = "texsequence_xxx";
  89.     private static final String myTextureLookupName = "myTexture2D";
  90.  
  91.     /** Blender's Big Buck Bunny: 24f 416p H.264,  AAC 48000 Hz, 2 ch, mpeg stream. */
  92.     public static final Uri defURI;
  93.     static {
  94.         Uri _defURI = null;
  95.         try {
  96.             // Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream.
  97.             // _defURI = new URI("http://video.webmfiles.org/big-buck-bunny_trailer.webm");
  98. //            _defURI = Uri.cast("http://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4");
  99.             _defURI = Uri.valueOf(new File("E:\\Videos\\Indy Car Edmonton.mp4"));
  100.         } catch (final URISyntaxException e) {
  101.             e.printStackTrace();
  102.         }
  103.         defURI = _defURI;
  104.     }
  105.  
  106.     /** Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */
  107.     public MovieSimpleDeadlock(final GLMediaPlayer sharedMediaPlayer) throws IllegalStateException {
  108.         mPlayer = sharedMediaPlayer;
  109.         mPlayerScaleOrig = false;
  110.         mPlayer = GLMediaPlayerFactory.createDefault();
  111.         mPlayer.attachObject(PLAYER, this);
  112.     }
  113.  
  114.     public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
  115.         mPlayer.initStream(streamLoc, vid, aid, textureCount);
  116.     }
  117.  
  118.     public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
  119.  
  120.     public void setScaleOrig(final boolean v) {
  121.         mPlayerScaleOrig = v;
  122.     }
  123.  
  124.     public boolean hasEffect(final int e) { return 0 != ( effects & e ) ; }
  125.     public void setEffects(final int e) { effects = e; };
  126.     public void setTransparency(final float alpha) {
  127.         this.effects |= EFFECT_TRANSPARENT;
  128.         this.alpha = alpha;
  129.     }
  130.  
  131.     public void resetGLState() {
  132.         resetGLState = true;
  133.     }
  134.  
  135.     private void initShader(final GL2ES2 gl) {
  136.         // Create & Compile the shader objects
  137.         final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimpleDeadlock.class,
  138.                                             "../shader", "../shader/bin", shaderBasename, true);
  139.         final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MovieSimpleDeadlock.class,
  140.                                             "../shader", "../shader/bin", shaderBasename, true);
  141.  
  142.         boolean preludeGLSLVersion = true;
  143.         if( GLES2.GL_TEXTURE_EXTERNAL_OES == mPlayer.getTextureTarget() ) {
  144.             if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
  145.                 throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
  146.             }
  147.             if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
  148.                 // Bug on Nexus 10, ES3 - Android 4.3, where
  149.                 // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
  150.                 //   P0003: Extension 'GL_OES_EGL_image_external' not supported
  151.                 preludeGLSLVersion = false;
  152.             }
  153.         }
  154.         rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
  155.  
  156.         int rsFpPos = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
  157.         rsFpPos = rsFp.insertShaderSource(0, rsFpPos, mPlayer.getRequiredExtensionsShaderStub());
  158.         rsFp.addDefaultShaderPrecision(gl, rsFpPos);
  159.  
  160.         final String texLookupFuncName = mPlayer.getTextureLookupFunctionName(myTextureLookupName);
  161.         rsFp.replaceInShaderSource(myTextureLookupName, texLookupFuncName);
  162.  
  163.         // Inject TextureSequence shader details
  164.         final StringBuilder sFpIns = new StringBuilder();
  165.         sFpIns.append("uniform ").append(mPlayer.getTextureSampler2DType()).append(" mgl_ActiveTexture;\n");
  166.         sFpIns.append(mPlayer.getTextureLookupFragmentShaderImpl());
  167.         rsFp.insertShaderSource(0, "TEXTURE-SEQUENCE-CODE-BEGIN", 0, sFpIns);
  168.  
  169.         // Create & Link the shader program
  170.         final ShaderProgram sp = new ShaderProgram();
  171.         sp.add(rsVp);
  172.         sp.add(rsFp);
  173.         if(!sp.link(gl, System.err)) {
  174.             throw new GLException("Couldn't link program: "+sp);
  175.         }
  176.  
  177.         // Let's manage all our states using ShaderState.
  178.         st = new ShaderState();
  179.         st.attachShaderProgram(gl, sp, false);
  180.     }
  181.  
  182.     @Override
  183.     public void init(final GLAutoDrawable drawable) {
  184.  
  185.         if(null == mPlayer) {
  186.             throw new InternalError("mPlayer null");
  187.         }
  188.         if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) {
  189.             throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer);
  190.         }
  191.         final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
  192.         resetGLState = false;
  193.  
  194.         final GL2ES2 gl = drawable.getGL().getGL2ES2();
  195.  
  196. //        if(waitForKey) {
  197. //            UITestCase.waitForKey("Init>");
  198. //        }
  199.         final Texture tex;
  200.         try {
  201.             if(GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
  202.                 mPlayer.initGL(gl);
  203.             }
  204.             final TextureFrame frame = mPlayer.getLastTexture();
  205.             if( null != frame ) {
  206.                 if( !hasVideo ) {
  207.                     throw new InternalError("XXX: "+mPlayer);
  208.                 }
  209.                 tex = frame.getTexture();
  210.                 if( null == tex ) {
  211.                     throw new InternalError("XXX: "+mPlayer);
  212.                 }
  213.             } else {
  214.                 tex = null;
  215.                 if( hasVideo ) {
  216.                     throw new InternalError("XXX: "+mPlayer);
  217.                 }
  218.             }
  219.             mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } );
  220.         } catch (final Exception glex) {
  221.             glex.printStackTrace();
  222.             if(null != mPlayer) {
  223.                 mPlayer.destroy(gl);
  224.                 mPlayer = null;
  225.             }
  226.             throw new GLException(glex);
  227.         }
  228.  
  229.         if( hasVideo ) {
  230.             initShader(gl);
  231.  
  232.             // Push the 1st uniform down the path
  233.             st.useProgram(gl, true);
  234.  
  235.             final int[] viewPort = new int[] { 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()};
  236.             pmvMatrix = new PMVMatrix();
  237.             reshapePMV(viewPort[2], viewPort[3]);
  238.             pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
  239.             if(!st.uniform(gl, pmvMatrixUniform)) {
  240.                 throw new GLException("Error setting PMVMatrix in shader: "+st);
  241.             }
  242.             if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) {
  243.                 throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
  244.             }
  245.  
  246.             final float dWidth = drawable.getSurfaceWidth();
  247.             final float dHeight = drawable.getSurfaceHeight();
  248.             final float mWidth = mPlayer.getWidth();
  249.             final float mHeight = mPlayer.getHeight();
  250.             final float mAspect = mWidth/mHeight;
  251.             float xs, ys;
  252.             if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
  253.                 xs   = mWidth/2f;                ys   = xs / mAspect;
  254.             } else {
  255.                 xs   = dWidth/2f;                ys   = xs / mAspect; // w>h
  256.             }
  257.             verts = new float[] { -1f*xs, -1f*ys, 0f, // LB
  258.                                    1f*xs,  1f*ys, 0f  // RT
  259.                                 };
  260.             {
  261.                 final float[] winLB = new float[3];
  262.                 final float[] winRT = new float[3];
  263.                 pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0);
  264.                 pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0);
  265.             }
  266.  
  267.             interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
  268.             {
  269.                 interleavedVBO.addGLSLSubArray("mgl_Vertex",        3, GL.GL_ARRAY_BUFFER);
  270.                 interleavedVBO.addGLSLSubArray("mgl_Color",         4, GL.GL_ARRAY_BUFFER);
  271.                 interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
  272.             }
  273.             updateInterleavedVBO(gl, tex);
  274.  
  275.             st.ownAttribute(interleavedVBO, true);
  276.             gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f);
  277.  
  278.             gl.glEnable(GL.GL_DEPTH_TEST);
  279.  
  280.             st.useProgram(gl, false);
  281.  
  282.             // Let's show the completed shader state ..
  283.         }
  284.  
  285.         mPlayer.play();
  286.         startTime = System.currentTimeMillis();
  287.     }
  288.  
  289.     protected void updateInterleavedVBO(final GL gl, final Texture tex) {
  290.         final float ss = 1f, ts = 1f; // scale tex-coord
  291.         final boolean wasEnabled = interleavedVBO.enabled();
  292.         interleavedVBO.seal(gl, false);
  293.         interleavedVBO.rewind();
  294.         {
  295.             final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
  296.             final TextureCoords tc = tex.getImageTexCoords();
  297.  
  298.              // left-bottom
  299.             ib.put(verts[0]);  ib.put(verts[1]);  ib.put(verts[2]);
  300.             if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
  301.                 ib.put( 0);    ib.put( 0);     ib.put( 0);    ib.put(alpha);
  302.             } else {
  303.                 ib.put( 1);    ib.put( 1);     ib.put( 1);    ib.put(alpha);
  304.             }
  305.             ib.put( tc.left()   *ss);  ib.put( tc.bottom() *ts);
  306.  
  307.              // right-bottom
  308.             ib.put(verts[3]);  ib.put(verts[1]);  ib.put(verts[2]);
  309.             if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
  310.                 ib.put( 0);    ib.put( 0);     ib.put( 0);    ib.put(alpha);
  311.             } else {
  312.                 ib.put( 1);    ib.put( 1);     ib.put( 1);    ib.put(alpha);
  313.             }
  314.             ib.put( tc.right()  *ss);  ib.put( tc.bottom() *ts);
  315.  
  316.              // left-top
  317.             ib.put(verts[0]);  ib.put(verts[4]);  ib.put(verts[2]);
  318.             ib.put( 1);    ib.put( 1);     ib.put( 1);    ib.put(alpha);
  319.             ib.put( tc.left()   *ss);  ib.put( tc.top()    *ts);
  320.  
  321.              // right-top
  322.             ib.put(verts[3]);  ib.put(verts[4]);  ib.put(verts[2]);
  323.             ib.put( 1);    ib.put( 1);     ib.put( 1);    ib.put(alpha);
  324.             ib.put( tc.right()  *ss);  ib.put( tc.top()    *ts);
  325.         }
  326.         interleavedVBO.seal(gl, true);
  327.         if( !wasEnabled ) {
  328.             interleavedVBO.enableBuffer(gl, false);
  329.         }
  330.     }
  331.  
  332.     @Override
  333.     public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
  334.         final GL2ES2 gl = drawable.getGL().getGL2ES2();
  335.         if(null == mPlayer) { return; }
  336.  
  337.         if(null != st) {
  338.             reshapePMV(width, height);
  339.             st.useProgram(gl, true);
  340.             st.uniform(gl, pmvMatrixUniform);
  341.             st.useProgram(gl, false);
  342.         }
  343.     }
  344.  
  345.     private void reshapePMV(final int width, final int height) {
  346.         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
  347.         pmvMatrix.glLoadIdentity();
  348.         final float fw = width / 2f;
  349.         final float fh = height/ 2f;
  350.         pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f);
  351.  
  352.         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
  353.         pmvMatrix.glLoadIdentity();
  354.         pmvMatrix.glTranslatef(0, 0, 0);
  355.     }
  356.  
  357.     @Override
  358.     public void dispose(final GLAutoDrawable drawable) {
  359.         disposeImpl(drawable, true);
  360.     }
  361.  
  362.     private void disposeImpl(final GLAutoDrawable drawable, final boolean disposePlayer) {
  363.         if(null == mPlayer) { return; }
  364.  
  365.         final GL2ES2 gl = drawable.getGL().getGL2ES2();
  366.         if( disposePlayer ) {
  367.             mPlayer.destroy(gl);
  368.             mPlayer=null;
  369.         }
  370.         pmvMatrixUniform = null;
  371.         if(null != pmvMatrix) {
  372.             pmvMatrix=null;
  373.         }
  374.         if(null != st) {
  375.             st.destroy(gl);
  376.             st=null;
  377.         }
  378.     }
  379.  
  380.     long lastPerfPos = 0;
  381.  
  382.     @Override
  383.     public void display(final GLAutoDrawable drawable) {
  384.         final GL2ES2 gl = drawable.getGL().getGL2ES2();
  385.         if(null == mPlayer) { return; }
  386.  
  387.         if( resetGLState ) {
  388.             resetGLState = false;
  389.             disposeImpl(drawable, false);
  390.             init(drawable);
  391.             reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
  392.         }
  393.  
  394.         final long currentPos = System.currentTimeMillis();
  395.         if( currentPos - lastPerfPos > 2000 ) {
  396.             lastPerfPos = currentPos;
  397.         }
  398.  
  399.         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
  400.  
  401.         if(null == st) {
  402.             return;
  403.         }
  404.  
  405.         st.useProgram(gl, true);
  406.  
  407.         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
  408.         pmvMatrix.glLoadIdentity();
  409.         pmvMatrix.glTranslatef(0, 0, 0);
  410.         st.uniform(gl, pmvMatrixUniform);
  411.         interleavedVBO.enableBuffer(gl, true);
  412.         Texture tex = null;
  413.         if(null!=mPlayer) {
  414.             final TextureSequence.TextureFrame texFrame;
  415.             texFrame=mPlayer.getNextTexture(gl);
  416.             if(null != texFrame) {
  417.                 tex = texFrame.getTexture();
  418.                 gl.glActiveTexture(GL.GL_TEXTURE0+mPlayer.getTextureUnit());
  419.                 tex.enable(gl);
  420.                 tex.bind(gl);
  421.             }
  422.         }
  423.         gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
  424.         if(null != tex) {
  425.             tex.disable(gl);
  426.         }
  427.         interleavedVBO.enableBuffer(gl, false);
  428.         st.useProgram(gl, false);
  429.     }
  430.  
  431.     static boolean loopEOS = false;
  432.     static boolean origSize;
  433.  
  434.     public static void main(final String[] args) throws IOException, URISyntaxException {
  435.         int width = 320;
  436.         int height = 240;
  437.         int[] positions = {0,100, 400,100, 0,400, 400,400};
  438.         int textureCount = 1;
  439.  
  440.         int vid = GLMediaPlayer.STREAM_ID_AUTO;
  441.         int aid = GLMediaPlayer.STREAM_ID_NONE;
  442.  
  443.         final int windowCount = 4;
  444.  
  445.         final GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
  446.         final GLCapabilities caps = new GLCapabilities(glp);
  447.         caps.setBackgroundOpaque(true);
  448.         caps.setDoubleBuffered(true);
  449.         caps.setAlphaBits(4);
  450.         caps.setSampleBuffers(true);
  451.         caps.setNumSamples(4);
  452.  
  453.         final MovieSimpleDeadlock[] mss = new MovieSimpleDeadlock[windowCount];
  454.         final GLWindow[] windows = new GLWindow[windowCount];
  455.         for(int i=0; i<windowCount; i++) {
  456.             mss[i] = new MovieSimpleDeadlock(null);
  457.             mss[i].initStream(defURI, vid, aid, textureCount);
  458.             System.out.println("Init stream " + System.currentTimeMillis());
  459.  
  460. //            windows[i] = GLWindow.create(caps);
  461. //            windows[i].setTitle("Player "+i);
  462. //            windows[i].setSize(width, height);
  463. //            if (i*2 < positions.length) {
  464. //                windows[i].setPosition(positions[i*2], positions[i*2+1]);
  465. //            }
  466.         }
  467.        
  468.         for(int i=0; i<windowCount; i++) {
  469. //            windows[i].setVisible(true);
  470. //            windows[i].addGLEventListener(mss[i]);
  471. //            final FPSAnimator anim = new FPSAnimator(windows[i], 60);
  472. //            anim.start();
  473.         }
  474.        
  475.         while (true) {
  476.             for(int i=0; i<windowCount; i++) {
  477.                 System.out.println(mss[i].mPlayer.getState());
  478.             }
  479.         }
  480.     }
  481.  
  482. }
Add Comment
Please, Sign In to add comment