1 #ifndef CAMERA_TEST_SURFACE_TEXTURE_H 2 #define CAMERA_TEST_SURFACE_TEXTURE_H 3 4 #include "camera_test.h" 5 6 #ifdef ANDROID_API_JB_OR_LATER 7 #include <gui/Surface.h> 8 #include <gui/GLConsumer.h> 9 #include <gui/SurfaceComposerClient.h> 10 #else 11 #include <surfaceflinger/Surface.h> 12 #include <surfaceflinger/ISurface.h> 13 #include <surfaceflinger/ISurfaceComposer.h> 14 #include <surfaceflinger/ISurfaceComposerClient.h> 15 #include <surfaceflinger/SurfaceComposerClient.h> 16 #endif 17 18 #ifdef ANDROID_API_JB_OR_LATER 19 # define CAMHAL_LOGV ALOGV 20 # define CAMHAL_LOGE ALOGE 21 # define PRINTOVER(arg...) ALOGD(#arg) 22 # define LOG_FUNCTION_NAME ALOGD("%d: %s() ENTER", __LINE__, __FUNCTION__); 23 # define LOG_FUNCTION_NAME_EXIT ALOGD("%d: %s() EXIT", __LINE__, __FUNCTION__); 24 #else 25 # define CAMHAL_LOGV LOGV 26 # define CAMHAL_LOGE LOGE 27 # define PRINTOVER(arg...) LOGD(#arg) 28 # define LOG_FUNCTION_NAME LOGD("%d: %s() ENTER", __LINE__, __FUNCTION__); 29 # define LOG_FUNCTION_NAME_EXIT LOGD("%d: %s() EXIT", __LINE__, __FUNCTION__); 30 #endif 31 32 using namespace android; 33 34 class FrameWaiter : public android::GLConsumer::FrameAvailableListener { 35 public: 36 FrameWaiter(): 37 mPendingFrames(0) { 38 } 39 40 virtual ~FrameWaiter() { 41 onFrameAvailable(); 42 } 43 44 void waitForFrame() { 45 Mutex::Autolock lock(mMutex); 46 while (mPendingFrames == 0) { 47 mCondition.wait(mMutex); 48 } 49 mPendingFrames--; 50 } 51 52 virtual void onFrameAvailable() { 53 Mutex::Autolock lock(mMutex); 54 mPendingFrames++; 55 mCondition.signal(); 56 } 57 58 int mPendingFrames; 59 Mutex mMutex; 60 Condition mCondition; 61 }; 62 63 class GLSurface { 64 public: 65 66 GLSurface(): 67 mEglDisplay(EGL_NO_DISPLAY), 68 mEglSurface(EGL_NO_SURFACE), 69 mEglContext(EGL_NO_CONTEXT) { 70 } 71 72 virtual ~GLSurface() {} 73 74 void initialize(int display); 75 void deinit(); 76 void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader); 77 void createProgram(const char* pVertexSource, const char* pFragmentSource, 78 GLuint* outPgm); 79 80 private: 81 EGLint const* getConfigAttribs(); 82 EGLint const* getContextAttribs(); 83 84 protected: 85 sp<SurfaceComposerClient> mComposerClient; 86 sp<SurfaceControl> mSurfaceControl; 87 88 EGLDisplay mEglDisplay; 89 EGLSurface mEglSurface; 90 EGLContext mEglContext; 91 EGLConfig mGlConfig; 92 }; 93 94 class SurfaceTextureBase { 95 public: 96 virtual ~SurfaceTextureBase() {} 97 98 void initialize(int tex_id, EGLenum tex_target = EGL_NONE); 99 void deinit(); 100 void getId(const char **name); 101 102 virtual sp<GLConsumer> getST(); 103 104 protected: 105 sp<GLConsumer> mST; 106 sp<Surface> mSTC; 107 sp<ANativeWindow> mANW; 108 int mTexId; 109 }; 110 111 class SurfaceTextureGL : public GLSurface, public SurfaceTextureBase { 112 public: 113 virtual ~SurfaceTextureGL() {} 114 115 void initialize(int display, int tex_id); 116 void deinit(); 117 118 // drawTexture draws the GLConsumer over the entire GL viewport. 119 void drawTexture(); 120 121 private: 122 GLuint mPgm; 123 GLint mPositionHandle; 124 GLint mTexSamplerHandle; 125 GLint mTexMatrixHandle; 126 }; 127 128 class ST_BufferSourceThread : public BufferSourceThread { 129 public: 130 ST_BufferSourceThread(int tex_id, sp<Camera> camera) : BufferSourceThread(camera) { 131 mSurfaceTextureBase = new SurfaceTextureBase(); 132 mSurfaceTextureBase->initialize(tex_id); 133 mSurfaceTexture = mSurfaceTextureBase->getST(); 134 mSurfaceTexture->setSynchronousMode(true); 135 mFW = new FrameWaiter(); 136 mSurfaceTexture->setFrameAvailableListener(mFW); 137 #ifndef ANDROID_API_JB_OR_LATER 138 mCamera->setBufferSource(NULL, mSurfaceTexture); 139 #endif 140 } 141 virtual ~ST_BufferSourceThread() { 142 #ifndef ANDROID_API_JB_OR_LATER 143 mCamera->releaseBufferSource(NULL, mSurfaceTexture); 144 #endif 145 mSurfaceTextureBase->deinit(); 146 delete mSurfaceTextureBase; 147 } 148 149 virtual bool threadLoop() { 150 sp<GraphicBuffer> graphic_buffer; 151 152 mFW->waitForFrame(); 153 if (!mDestroying) { 154 float mtx[16] = {0.0}; 155 mSurfaceTexture->updateTexImage(); 156 printf("=== Metadata for buffer %d ===\n", mCounter); 157 #ifndef ANDROID_API_JB_OR_LATER 158 showMetadata(mSurfaceTexture->getMetadata()); 159 #endif 160 printf("\n"); 161 graphic_buffer = mSurfaceTexture->getCurrentBuffer(); 162 mSurfaceTexture->getTransformMatrix(mtx); 163 Rect crop = getCrop(graphic_buffer, mtx); 164 165 mDeferThread->add(graphic_buffer, crop, mCounter++); 166 restartCapture(); 167 return true; 168 } 169 return false; 170 } 171 172 virtual void requestExit() { 173 Thread::requestExit(); 174 175 mDestroying = true; 176 mFW->onFrameAvailable(); 177 } 178 179 virtual void setBuffer(android::ShotParameters ¶ms) { 180 { 181 const char* id = NULL; 182 183 mSurfaceTextureBase->getId(&id); 184 185 if (id) { 186 params.set(KEY_TAP_OUT_SURFACES, id); 187 } else { 188 params.remove(KEY_TAP_OUT_SURFACES); 189 } 190 } 191 } 192 193 private: 194 SurfaceTextureBase *mSurfaceTextureBase; 195 sp<GLConsumer> mSurfaceTexture; 196 sp<FrameWaiter> mFW; 197 }; 198 199 class ST_BufferSourceInput : public BufferSourceInput { 200 public: 201 ST_BufferSourceInput(int tex_id, sp<Camera> camera) : 202 BufferSourceInput(camera), mTexId(tex_id) { 203 mSurfaceTexture = new SurfaceTextureBase(); 204 sp<GLConsumer> surface_texture; 205 mSurfaceTexture->initialize(mTexId); 206 surface_texture = mSurfaceTexture->getST(); 207 surface_texture->setSynchronousMode(true); 208 209 mWindowTapIn = new Surface(surface_texture); 210 #ifndef ANDROID_API_JB_OR_LATER 211 mCamera->setBufferSource(mSurfaceTexture->getST(), NULL); 212 #else 213 mCamera->setBufferSource(mSurfaceTexture->getST()->getBufferQueue(), NULL); 214 #endif 215 } 216 virtual ~ST_BufferSourceInput() { 217 #ifndef ANDROID_API_JB_OR_LATER 218 mCamera->releaseBufferSource(mSurfaceTexture->getST(), NULL); 219 #else 220 mCamera->releaseBufferSource(mSurfaceTexture->getST()->getBufferQueue(), NULL); 221 #endif 222 delete mSurfaceTexture; 223 } 224 225 virtual void setInput(buffer_info_t bufinfo, const char *format) { 226 android::ShotParameters params; 227 mSurfaceTexture->getST()->setDefaultBufferSize(bufinfo.width, bufinfo.height); 228 BufferSourceInput::setInput(bufinfo, format, params); 229 } 230 231 private: 232 int mTexId; 233 SurfaceTextureBase *mSurfaceTexture; 234 }; 235 236 #endif 237