• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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