1 /* 2 * Copyright (C) 2011 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 #ifndef NATIVE_WINDOW_RENDERER_H_ 18 #define NATIVE_WINDOW_RENDERER_H_ 19 20 #include <EGL/egl.h> 21 #include <GLES2/gl2.h> 22 #include <stagefright/MediaBuffer.h> 23 #include <stagefright/MetaData.h> 24 #include <utils/RefBase.h> 25 #include <utils/threads.h> 26 27 #include "M4xVSS_API.h" 28 29 // The NativeWindowRenderer draws video frames stored in MediaBuffers to 30 // an ANativeWindow. It can apply "rendering mode" and color effects to 31 // the frames. "Rendering mode" is the option to do resizing, cropping, 32 // or black-bordering when the source and destination aspect ratio are 33 // different. Color effects include sepia, negative, and gradient. 34 // 35 // The input to NativeWindowRenderer is provided by the RenderInput class, 36 // and there can be multiple active RenderInput at the same time. Although 37 // we only expect that happens briefly when one clip is about to finish 38 // and the next clip is about to start. 39 // 40 // We allocate a SurfaceTexture for each RenderInput and the user can use 41 // the getTargetWindow() function to get the corresponding ANativeWindow 42 // for that SurfaceTexture. The intention is that the user can pass that 43 // ANativeWindow to OMXCodec::Create() so the codec can decode directly 44 // to buffers provided by the texture. 45 46 namespace android { 47 48 class SurfaceTexture; 49 class SurfaceTextureClient; 50 class RenderInput; 51 52 class NativeWindowRenderer { 53 public: 54 NativeWindowRenderer(sp<ANativeWindow> nativeWindow, int width, int height); 55 ~NativeWindowRenderer(); 56 57 RenderInput* createRenderInput(); 58 void destroyRenderInput(RenderInput* input); 59 60 private: 61 // No copy constructor and assignment 62 NativeWindowRenderer(const NativeWindowRenderer &); 63 NativeWindowRenderer &operator=(const NativeWindowRenderer &); 64 65 // Initialization and finialization 66 void initializeEGL(); 67 void terminateEGL(); 68 void createPrograms(); 69 void createProgram( 70 GLuint vertexShader, GLuint fragmentShader, GLuint* outPgm); 71 void loadShader( 72 GLenum shaderType, const char* pSource, GLuint* outShader); 73 74 // These functions are executed every frame. 75 void render(RenderInput* input); 76 void queueInternalBuffer(ANativeWindow* anw, MediaBuffer* buffer); 77 void queueExternalBuffer(ANativeWindow* anw, MediaBuffer* buffer, 78 int width, int height); 79 void copyI420Buffer(MediaBuffer* src, uint8_t* dst, 80 int srcWidth, int srcHeight, int stride); 81 void updateProgramAndHandle(uint32_t videoEffect); 82 void calculatePositionCoordinates(M4xVSS_MediaRendering renderingMode, 83 int srcWidth, int srcHeight); 84 85 // These variables are initialized once and doesn't change afterwards. 86 sp<ANativeWindow> mNativeWindow; 87 int mDstWidth, mDstHeight; 88 EGLDisplay mEglDisplay; 89 EGLSurface mEglSurface; 90 EGLContext mEglContext; 91 enum { 92 EFFECT_NORMAL, 93 EFFECT_SEPIA, 94 EFFECT_NEGATIVE, 95 EFFECT_GRADIENT, 96 NUMBER_OF_EFFECTS 97 }; 98 GLuint mProgram[NUMBER_OF_EFFECTS]; 99 100 // We use one shader program for each effect. mLastVideoEffect remembers 101 // the program used for the last frame. when the effect used changes, 102 // we change the program used and update the handles. 103 uint32_t mLastVideoEffect; 104 GLint mPositionHandle; 105 GLint mTexPosHandle; 106 GLint mTexMatrixHandle; 107 108 // This is the vertex coordinates used for the frame texture. 109 // It's calculated according the the rendering mode and the source and 110 // destination aspect ratio. 111 GLfloat mPositionCoordinates[8]; 112 113 // We use a different GL id for each SurfaceTexture. 114 GLuint mNextTextureId; 115 116 // Number of existing RenderInputs, just for debugging. 117 int mActiveInputs; 118 119 // The GL thread functions 120 static int threadStart(void* self); 121 void glThread(); 122 123 // These variables are used to communicate between the GL thread and 124 // other threads. 125 Mutex mLock; 126 Condition mCond; 127 enum { 128 CMD_IDLE, 129 CMD_RENDER_INPUT, 130 CMD_RESERVE_TEXTURE, 131 CMD_DELETE_TEXTURE, 132 CMD_QUIT, 133 }; 134 int mThreadCmd; 135 RenderInput* mThreadRenderInput; 136 GLuint mThreadTextureId; 137 138 // These functions are used to send commands to the GL thread. 139 // sendRequest() also waits for the GL thread acknowledges the 140 // command is finished. 141 void startRequest(int cmd); 142 void sendRequest(); 143 144 friend class RenderInput; 145 }; 146 147 class RenderInput { 148 public: 149 // Returns the ANativeWindow corresponds to the SurfaceTexture. 150 ANativeWindow* getTargetWindow(); 151 152 // Updates video frame size from the MediaSource's metadata. Specifically 153 // we look for kKeyWidth, kKeyHeight, and (optionally) kKeyCropRect. 154 void updateVideoSize(sp<MetaData> meta); 155 156 // Renders the buffer with the given video effect and rending mode. 157 // The video effets are defined in VideoEditorTools.h 158 // Set isExternalBuffer to true only when the buffer given is not 159 // provided by the SurfaceTexture. 160 void render(MediaBuffer *buffer, uint32_t videoEffect, 161 M4xVSS_MediaRendering renderingMode, bool isExternalBuffer); 162 private: 163 RenderInput(NativeWindowRenderer* renderer, GLuint textureId); 164 ~RenderInput(); 165 NativeWindowRenderer* mRenderer; 166 GLuint mTextureId; 167 sp<SurfaceTexture> mST; 168 sp<SurfaceTextureClient> mSTC; 169 int mWidth, mHeight; 170 171 // These are only valid during render() calls 172 uint32_t mVideoEffect; 173 M4xVSS_MediaRendering mRenderingMode; 174 bool mIsExternalBuffer; 175 MediaBuffer* mBuffer; 176 177 friend class NativeWindowRenderer; 178 }; 179 180 } // namespace android 181 182 #endif // NATIVE_WINDOW_RENDERER_H_ 183