Android Open Source - AndroidVideoSamples Input Surface






From Project

Back to project page AndroidVideoSamples.

License

The source code is released under:

Apache License

If you think the Android project AndroidVideoSamples listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 The Android Open Source Project
 *//from ww  w.ja  va2s .  co  m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.roryhool.commonvideolibrary;

import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.util.Log;
import android.view.Surface;

/**
 * Holds state associated with a Surface used for MediaCodec encoder input.
 * <p>
 * The constructor takes a Surface obtained from MediaCodec.createInputSurface(), and uses that to create an EGL window surface. Calls to eglSwapBuffers() cause a frame of data to be sent to the video encoder.
 */
class InputSurface {
   private static final String TAG = "InputSurface";
   private static final boolean VERBOSE = false;
   private static final int EGL_RECORDABLE_ANDROID = 0x3142;
   private static final int EGL_OPENGL_ES2_BIT = 4;
   private EGLDisplay mEGLDisplay;
   private EGLContext mEGLContext;
   private EGLSurface mEGLSurface;
   private Surface mSurface;

   /**
    * Creates an InputSurface from a Surface.
    */
   public InputSurface( Surface surface ) {
      if ( surface == null ) {
         throw new NullPointerException();
      }
      mSurface = surface;
      eglSetup();
   }

   /**
    * Prepares EGL. We want a GLES 2.0 context and a surface that supports recording.
    */
   private void eglSetup() {
      mEGLDisplay = EGL14.eglGetDisplay( EGL14.EGL_DEFAULT_DISPLAY );
      if ( mEGLDisplay == EGL14.EGL_NO_DISPLAY ) {
         throw new RuntimeException( "unable to get EGL14 display" );
      }
      int[] version = new int[2];
      if ( !EGL14.eglInitialize( mEGLDisplay, version, 0, version, 1 ) ) {
         mEGLDisplay = null;
         throw new RuntimeException( "unable to initialize EGL14" );
      }
      // Configure EGL for pbuffer and OpenGL ES 2.0. We want enough RGB bits
      // to be able to tell if the frame is reasonable.
      int[] attribList = { EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RECORDABLE_ANDROID, 1, EGL14.EGL_NONE };
      EGLConfig[] configs = new EGLConfig[1];
      int[] numConfigs = new int[1];
      if ( !EGL14.eglChooseConfig( mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0 ) ) {
         throw new RuntimeException( "unable to find RGB888+recordable ES2 EGL config" );
      }
      // Configure context for OpenGL ES 2.0.
      int[] attrib_list = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE };
      mEGLContext = EGL14.eglCreateContext( mEGLDisplay, configs[0], EGL14.EGL_NO_CONTEXT, attrib_list, 0 );
      checkEglError( "eglCreateContext" );
      if ( mEGLContext == null ) {
         throw new RuntimeException( "null context" );
      }
      // Create a window surface, and attach it to the Surface we received.
      int[] surfaceAttribs = { EGL14.EGL_NONE };
      mEGLSurface = EGL14.eglCreateWindowSurface( mEGLDisplay, configs[0], mSurface, surfaceAttribs, 0 );
      checkEglError( "eglCreateWindowSurface" );
      if ( mEGLSurface == null ) {
         throw new RuntimeException( "surface was null" );
      }
   }

   /**
    * Discard all resources held by this class, notably the EGL context. Also releases the Surface that was passed to our constructor.
    */
   public void release() {
      if ( EGL14.eglGetCurrentContext().equals( mEGLContext ) ) {
         // Clear the current context and surface to ensure they are discarded immediately.
         EGL14.eglMakeCurrent( mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT );
      }
      EGL14.eglDestroySurface( mEGLDisplay, mEGLSurface );
      EGL14.eglDestroyContext( mEGLDisplay, mEGLContext );
      // EGL14.eglTerminate(mEGLDisplay);
      mSurface.release();
      // null everything out so future attempts to use this object will cause an NPE
      mEGLDisplay = null;
      mEGLContext = null;
      mEGLSurface = null;
      mSurface = null;
   }

   /**
    * Makes our EGL context and surface current.
    */
   public void makeCurrent() {
      if ( !EGL14.eglMakeCurrent( mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext ) ) {
         throw new RuntimeException( "eglMakeCurrent failed" );
      }
   }

   /**
    * Calls eglSwapBuffers. Use this to "publish" the current frame.
    */
   public boolean swapBuffers() {
      return EGL14.eglSwapBuffers( mEGLDisplay, mEGLSurface );
   }

   /**
    * Returns the Surface that the MediaCodec receives buffers from.
    */
   public Surface getSurface() {
      return mSurface;
   }

   /**
    * Sends the presentation time stamp to EGL. Time is expressed in nanoseconds.
    */
   public void setPresentationTime( long nsecs ) {
      EGLExt.eglPresentationTimeANDROID( mEGLDisplay, mEGLSurface, nsecs );
   }

   /**
    * Checks for EGL errors.
    */
   private void checkEglError( String msg ) {
      boolean failed = false;
      int error;
      while ( ( error = EGL14.eglGetError() ) != EGL14.EGL_SUCCESS ) {
         Log.e( TAG, msg + ": EGL error: 0x" + Integer.toHexString( error ) );
         failed = true;
      }
      if ( failed ) {
         throw new RuntimeException( "EGL error encountered (see log)" );
      }
   }
}




Java Source Code List

com.roryhool.commonvideolibrary.CursorHelper.java
com.roryhool.commonvideolibrary.InputSurface.java
com.roryhool.commonvideolibrary.Intents.java
com.roryhool.commonvideolibrary.MediaHelper.java
com.roryhool.commonvideolibrary.OutputSurface.java
com.roryhool.commonvideolibrary.Resolution.java
com.roryhool.commonvideolibrary.SamplerClip.java
com.roryhool.commonvideolibrary.TextureRenderer.java
com.roryhool.commonvideolibrary.UriHelper.java
com.roryhool.commonvideolibrary.VideoResampler.java
com.roryhool.videocreation.JoinActivity.java
com.roryhool.videocreation.MainActivity.java
com.roryhool.videocreation.RenderFromSurfaceActivity.java
com.roryhool.videocreation.SurfaceEncoder.java
com.roryhool.videomanipulation.MainActivity.java
com.roryhool.videomanipulation.ResampleActivity.java
com.roryhool.videomanipulation.RotationActivity.java
com.roryhool.videomanipulation.TrimActivity.java
com.roryhool.videoplayback.ControllerBase.java
com.roryhool.videoplayback.DecodeWithMediaCodecActivity.java
com.roryhool.videoplayback.MainActivity.java
com.roryhool.videoplayback.MediaCodecDecodeController.java
com.roryhool.videoplayback.MediaPlayerController.java
com.roryhool.videoplayback.PlayWithMediaPlayerActivity.java
com.roryhool.videoplayback.PlaybackTimer.java
com.roryhool.videoplayback.ResizeAnimation.java
com.roryhool.videoplayback.ScaledTextureView.java
com.roryhool.videoplayback.VideoPlayerView.java