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