19133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang/* 29133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * Copyright (C) 2011 The Android Open Source Project 39133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * 49133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 59133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * you may not use this file except in compliance with the License. 69133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * You may obtain a copy of the License at 79133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * 89133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 99133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * 109133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software 119133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 129133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * See the License for the specific language governing permissions and 149133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang * limitations under the License. 159133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang */ 169133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 179133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#ifndef NATIVE_WINDOW_RENDERER_H_ 189133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#define NATIVE_WINDOW_RENDERER_H_ 199133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 209133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <EGL/egl.h> 219133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <GLES2/gl2.h> 229133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <stagefright/MediaBuffer.h> 239133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <stagefright/MetaData.h> 249133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <utils/RefBase.h> 259133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include <utils/threads.h> 269133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 279133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#include "M4xVSS_API.h" 289133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 299133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// The NativeWindowRenderer draws video frames stored in MediaBuffers to 309133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// an ANativeWindow. It can apply "rendering mode" and color effects to 319133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// the frames. "Rendering mode" is the option to do resizing, cropping, 329133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// or black-bordering when the source and destination aspect ratio are 339133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// different. Color effects include sepia, negative, and gradient. 349133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// 359133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// The input to NativeWindowRenderer is provided by the RenderInput class, 369133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// and there can be multiple active RenderInput at the same time. Although 379133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// we only expect that happens briefly when one clip is about to finish 389133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// and the next clip is about to start. 399133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// 409133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// We allocate a SurfaceTexture for each RenderInput and the user can use 419133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// the getTargetWindow() function to get the corresponding ANativeWindow 429133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// for that SurfaceTexture. The intention is that the user can pass that 439133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// ANativeWindow to OMXCodec::Create() so the codec can decode directly 449133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang// to buffers provided by the texture. 459133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 469133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changnamespace android { 479133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 489133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changclass SurfaceTexture; 499133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changclass SurfaceTextureClient; 509133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changclass RenderInput; 519133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 529133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changclass NativeWindowRenderer { 539133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changpublic: 549133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang NativeWindowRenderer(sp<ANativeWindow> nativeWindow, int width, int height); 559133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang ~NativeWindowRenderer(); 569133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 579133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang RenderInput* createRenderInput(); 589133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void destroyRenderInput(RenderInput* input); 599133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 609133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changprivate: 619133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // No copy constructor and assignment 629133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang NativeWindowRenderer(const NativeWindowRenderer &); 639133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang NativeWindowRenderer &operator=(const NativeWindowRenderer &); 649133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 659133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Initialization and finialization 669133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void initializeEGL(); 679133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void terminateEGL(); 689133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void createPrograms(); 699133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void createProgram( 709133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLuint vertexShader, GLuint fragmentShader, GLuint* outPgm); 719133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void loadShader( 729133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLenum shaderType, const char* pSource, GLuint* outShader); 739133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 749133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // These functions are executed every frame. 759133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void render(RenderInput* input); 769133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void queueInternalBuffer(ANativeWindow* anw, MediaBuffer* buffer); 779133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void queueExternalBuffer(ANativeWindow* anw, MediaBuffer* buffer, 789133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int width, int height); 79d928e772c68a948e3353358eee7a834dc4fb6e43Chih-Chung Chang void copyI420Buffer(MediaBuffer* src, uint8_t* dst, 809133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int srcWidth, int srcHeight, int stride); 819133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void updateProgramAndHandle(uint32_t videoEffect); 829133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void calculatePositionCoordinates(M4xVSS_MediaRendering renderingMode, 839133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int srcWidth, int srcHeight); 849133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 859133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // These variables are initialized once and doesn't change afterwards. 869133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang sp<ANativeWindow> mNativeWindow; 879133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int mDstWidth, mDstHeight; 889133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EGLDisplay mEglDisplay; 899133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EGLSurface mEglSurface; 909133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EGLContext mEglContext; 919133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang enum { 929133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EFFECT_NORMAL, 939133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EFFECT_SEPIA, 949133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EFFECT_NEGATIVE, 959133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang EFFECT_GRADIENT, 969133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang NUMBER_OF_EFFECTS 979133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang }; 989133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLuint mProgram[NUMBER_OF_EFFECTS]; 999133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1009133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // We use one shader program for each effect. mLastVideoEffect remembers 1019133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // the program used for the last frame. when the effect used changes, 1029133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // we change the program used and update the handles. 1039133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang uint32_t mLastVideoEffect; 1049133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLint mPositionHandle; 1059133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLint mTexPosHandle; 1069133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLint mTexMatrixHandle; 1079133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1089133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // This is the vertex coordinates used for the frame texture. 1099133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // It's calculated according the the rendering mode and the source and 1109133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // destination aspect ratio. 1119133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLfloat mPositionCoordinates[8]; 1129133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1139133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // We use a different GL id for each SurfaceTexture. 1149133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLuint mNextTextureId; 1159133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1169133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Number of existing RenderInputs, just for debugging. 1179133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int mActiveInputs; 1189133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1199133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // The GL thread functions 1209133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang static int threadStart(void* self); 1219133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void glThread(); 1229133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1239133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // These variables are used to communicate between the GL thread and 1249133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // other threads. 1259133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang Mutex mLock; 1269133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang Condition mCond; 1279133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang enum { 1289133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang CMD_IDLE, 1299133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang CMD_RENDER_INPUT, 1309133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang CMD_RESERVE_TEXTURE, 1319133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang CMD_DELETE_TEXTURE, 1329133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang CMD_QUIT, 1339133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang }; 1349133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int mThreadCmd; 1359133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang RenderInput* mThreadRenderInput; 1369133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLuint mThreadTextureId; 1379133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1389133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // These functions are used to send commands to the GL thread. 1399133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // sendRequest() also waits for the GL thread acknowledges the 1409133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // command is finished. 1419133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void startRequest(int cmd); 1429133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void sendRequest(); 1439133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1449133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang friend class RenderInput; 1459133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang}; 1469133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1479133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changclass RenderInput { 1489133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changpublic: 1499133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Returns the ANativeWindow corresponds to the SurfaceTexture. 1509133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang ANativeWindow* getTargetWindow(); 1519133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1529133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Updates video frame size from the MediaSource's metadata. Specifically 1539133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // we look for kKeyWidth, kKeyHeight, and (optionally) kKeyCropRect. 1549133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void updateVideoSize(sp<MetaData> meta); 1559133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1569133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Renders the buffer with the given video effect and rending mode. 1579133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // The video effets are defined in VideoEditorTools.h 1589133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // Set isExternalBuffer to true only when the buffer given is not 1599133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // provided by the SurfaceTexture. 1609133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang void render(MediaBuffer *buffer, uint32_t videoEffect, 1619133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang M4xVSS_MediaRendering renderingMode, bool isExternalBuffer); 1629133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Changprivate: 1639133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang RenderInput(NativeWindowRenderer* renderer, GLuint textureId); 1649133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang ~RenderInput(); 1659133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang NativeWindowRenderer* mRenderer; 1669133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang GLuint mTextureId; 1679133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang sp<SurfaceTexture> mST; 1689133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang sp<SurfaceTextureClient> mSTC; 1699133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang int mWidth, mHeight; 1709133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1719133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang // These are only valid during render() calls 1729133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang uint32_t mVideoEffect; 1739133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang M4xVSS_MediaRendering mRenderingMode; 1749133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang bool mIsExternalBuffer; 1759133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang MediaBuffer* mBuffer; 1769133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1779133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang friend class NativeWindowRenderer; 1789133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang}; 1799133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1809133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang} // namespace android 1819133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang 1829133a10ed22acc8b2154ab187f301945bf51a1f9Chih-Chung Chang#endif // NATIVE_WINDOW_RENDERER_H_ 183