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