1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media.cts; 18 19 import android.media.MediaCodec; 20 import android.util.Log; 21 22 public class NdkInputSurface implements InputSurfaceInterface { 23 24 private static final String TAG = NdkInputSurface.class.getName(); 25 26 private long mNativeWindow; 27 private long mEGLDisplay; 28 private long mEGLConfig; 29 private long mEGLContext; 30 private long mEGLSurface; 31 private int mWidth, mHeight; 32 eglGetDisplay()33 static private native long eglGetDisplay(); eglChooseConfig(long eglDisplay)34 static private native long eglChooseConfig(long eglDisplay); eglCreateContext(long eglDisplay, long eglConfig)35 static private native long eglCreateContext(long eglDisplay, long eglConfig); createEGLSurface(long eglDisplay, long eglConfig, long nativeWindow)36 static private native long createEGLSurface(long eglDisplay, long eglConfig, long nativeWindow); eglMakeCurrent(long eglDisplay, long eglSurface, long eglContext)37 static private native boolean eglMakeCurrent(long eglDisplay, long eglSurface, long eglContext); eglSwapBuffers(long eglDisplay, long eglSurface)38 static private native boolean eglSwapBuffers(long eglDisplay, long eglSurface); eglPresentationTimeANDROID(long eglDisplay, long eglSurface, long nsecs)39 static private native boolean eglPresentationTimeANDROID(long eglDisplay, long eglSurface, long nsecs); eglGetWidth(long eglDisplay, long eglSurface)40 static private native int eglGetWidth(long eglDisplay, long eglSurface); eglGetHeight(long eglDisplay, long eglSurface)41 static private native int eglGetHeight(long eglDisplay, long eglSurface); eglDestroySurface(long eglDisplay, long eglSurface)42 static private native boolean eglDestroySurface(long eglDisplay, long eglSurface); nativeRelease(long eglDisplay, long eglSurface, long eglContext, long nativeWindow)43 static private native void nativeRelease(long eglDisplay, long eglSurface, long eglContext, long nativeWindow); 44 NdkInputSurface(long nativeWindow)45 public NdkInputSurface(long nativeWindow) { 46 47 mNativeWindow = nativeWindow; 48 49 mEGLDisplay = eglGetDisplay(); 50 if (mEGLDisplay == 0) { 51 throw new RuntimeException("unable to get EGL14 display"); 52 } 53 54 mEGLConfig = eglChooseConfig(mEGLDisplay); 55 if (mEGLConfig == 0) { 56 throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config"); 57 } 58 59 mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig); 60 if (mEGLContext == 0) { 61 throw new RuntimeException("null context"); 62 } 63 64 mEGLSurface = createEGLSurface(mEGLDisplay, mEGLConfig, mNativeWindow); 65 if (mEGLSurface == 0) { 66 throw new RuntimeException("surface was null"); 67 } 68 69 mWidth = eglGetWidth(mEGLDisplay, mEGLSurface); 70 mHeight = eglGetHeight(mEGLDisplay, mEGLSurface); 71 72 } 73 74 @Override makeCurrent()75 public void makeCurrent() { 76 if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLContext)) { 77 throw new RuntimeException("eglMakeCurrent failed"); 78 } 79 } 80 81 @Override swapBuffers()82 public boolean swapBuffers() { 83 return eglSwapBuffers(mEGLDisplay, mEGLSurface); 84 } 85 86 @Override setPresentationTime(long nsecs)87 public void setPresentationTime(long nsecs) { 88 eglPresentationTimeANDROID(mEGLDisplay, mEGLSurface, nsecs); 89 } 90 91 @Override configure(MediaCodec codec)92 public void configure(MediaCodec codec) { 93 throw new UnsupportedOperationException(codec.toString()); 94 } 95 96 @Override configure(NdkMediaCodec codec)97 public void configure(NdkMediaCodec codec) { 98 codec.setInputSurface(mNativeWindow); 99 } 100 101 @Override updateSize(int width, int height)102 public void updateSize(int width, int height) { 103 if (width != mWidth || height != mHeight) { 104 Log.d(TAG, "re-create EGLSurface"); 105 releaseEGLSurface(); 106 mEGLSurface = createEGLSurface(mEGLDisplay, mEGLConfig, mNativeWindow); 107 mWidth = eglGetWidth(mEGLDisplay, mEGLSurface); 108 mHeight = eglGetHeight(mEGLDisplay, mEGLSurface); 109 } 110 } 111 releaseEGLSurface()112 private void releaseEGLSurface() { 113 if (mEGLDisplay != 0) { 114 eglDestroySurface(mEGLDisplay, mEGLSurface); 115 mEGLSurface = 0; 116 } 117 } 118 119 @Override release()120 public void release() { 121 122 nativeRelease(mEGLDisplay, mEGLSurface, mEGLContext, mNativeWindow); 123 124 mEGLDisplay = 0; 125 mEGLContext = 0; 126 mEGLSurface = 0; 127 mNativeWindow = 0; 128 129 } 130 131 } 132