Home | History | Annotate | Download | only in lvpp
      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