Home | History | Annotate | Download | only in CameraHal
      1 #include <stdlib.h>
      2 #include <unistd.h>
      3 #include <sys/types.h>
      4 #include <sys/stat.h>
      5 #include <fcntl.h>
      6 #include <time.h>
      7 #include <semaphore.h>
      8 #include <pthread.h>
      9 #include <string.h>
     10 #include <climits>
     11 #include <math.h>
     12 
     13 #include <gui/GLConsumer.h>
     14 #include <gui/Surface.h>
     15 #include <ui/GraphicBuffer.h>
     16 #include <ui/GraphicBufferMapper.h>
     17 
     18 #include <camera/Camera.h>
     19 #include <camera/ICamera.h>
     20 #include <media/mediarecorder.h>
     21 
     22 #include <binder/IPCThreadState.h>
     23 #include <binder/ProcessState.h>
     24 #include <binder/IServiceManager.h>
     25 #include <cutils/properties.h>
     26 #include <camera/CameraParameters.h>
     27 #include <camera/ShotParameters.h>
     28 #include <camera/CameraMetadata.h>
     29 #include <system/audio.h>
     30 #include <system/camera.h>
     31 
     32 #include <cutils/memory.h>
     33 #include <utils/Log.h>
     34 
     35 #include <sys/wait.h>
     36 
     37 #include "camera_test.h"
     38 #include "camera_test_surfacetexture.h"
     39 
     40 #define ASSERT(X) \
     41     do { \
     42        if(!(X)) { \
     43            printf("error: %s():%d", __FUNCTION__, __LINE__); \
     44            return; \
     45        } \
     46     } while(0);
     47 
     48 #define ALIGN_DOWN(x, n) ((x) & (~((n) - 1)))
     49 #define ALIGN_UP(x, n) ((((x) + (n) - 1)) & (~((n) - 1)))
     50 #define ALIGN_WIDTH 32 // Should be 32...but the calculated dimension causes an ion crash
     51 #define ALIGN_HEIGHT 2 // Should be 2...but the calculated dimension causes an ion crash
     52 
     53 //temporarily define format here
     54 #define HAL_PIXEL_FORMAT_TI_NV12 0x100
     55 #define HAL_PIXEL_FORMAT_TI_Y8 0x103
     56 #define HAL_PIXEL_FORMAT_TI_Y16 0x104
     57 #define HAL_PIXEL_FORMAT_TI_UYVY 0x105
     58 
     59 using namespace android;
     60 
     61 static EGLint getSurfaceWidth() {
     62     return 512;
     63 }
     64 
     65 static EGLint getSurfaceHeight() {
     66     return 512;
     67 }
     68 
     69 static size_t calcBufSize(int format, int width, int height)
     70 {
     71     int buf_size;
     72 
     73     switch (format) {
     74         case HAL_PIXEL_FORMAT_TI_NV12:
     75             buf_size = width * height * 3 /2;
     76             break;
     77         case HAL_PIXEL_FORMAT_TI_Y16:
     78         case HAL_PIXEL_FORMAT_TI_UYVY:
     79             buf_size = width * height * 2;
     80             break;
     81         // add more formats later
     82         default:
     83             buf_size = width * height * 3 /2;
     84             break;
     85     }
     86 
     87     return buf_size;
     88 }
     89 
     90 static unsigned int calcOffset(int format, unsigned int width, unsigned int top, unsigned int left)
     91 {
     92     unsigned int bpp;
     93 
     94     switch (format) {
     95         case HAL_PIXEL_FORMAT_TI_NV12:
     96             bpp = 1;
     97             break;
     98         case HAL_PIXEL_FORMAT_TI_UYVY:
     99         case HAL_PIXEL_FORMAT_TI_Y16:
    100             bpp = 2;
    101             break;
    102         // add more formats later
    103         default:
    104             bpp = 1;
    105             break;
    106     }
    107 
    108     return top * width + left * bpp;
    109 }
    110 
    111 static int getHalPixFormat(const char *format)
    112 {
    113     int pixformat = HAL_PIXEL_FORMAT_TI_NV12;
    114     if ( NULL != format ) {
    115         if ( strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0 ) {
    116             pixformat = HAL_PIXEL_FORMAT_TI_Y16;
    117         } else if ( strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ) {
    118             pixformat = HAL_PIXEL_FORMAT_TI_NV12;
    119         } else if ( strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) == 0 ) {
    120             pixformat = HAL_PIXEL_FORMAT_TI_UYVY;
    121         } else {
    122             pixformat = HAL_PIXEL_FORMAT_TI_NV12;
    123         }
    124     }
    125 
    126     return pixformat;
    127 }
    128 
    129 static int getUsageFromANW(int format)
    130 {
    131     int usage = GRALLOC_USAGE_SW_READ_RARELY |
    132                 GRALLOC_USAGE_SW_WRITE_NEVER;
    133 
    134     switch (format) {
    135         case HAL_PIXEL_FORMAT_TI_NV12:
    136         case HAL_PIXEL_FORMAT_TI_Y16:
    137             // This usage flag indicates to gralloc we want the
    138             // buffers to come from system heap
    139             usage |= GRALLOC_USAGE_PRIVATE_0;
    140             break;
    141         default:
    142             // No special flags needed
    143             break;
    144     }
    145     return usage;
    146 }
    147 
    148 static status_t writeCroppedNV12(unsigned int offset,
    149                                  unsigned int stride,
    150                                  unsigned int bufWidth,
    151                                  unsigned int bufHeight,
    152                                  const Rect &crop,
    153                                  int fd,
    154                                  unsigned char *buffer)
    155 {
    156     unsigned char *luma = NULL, *chroma = NULL, *src = NULL;
    157     unsigned int uvoffset;
    158     int write_size;
    159 
    160     if (!buffer || !crop.isValid()) {
    161         return BAD_VALUE;
    162     }
    163 
    164     src = buffer;
    165     // offset to beginning of uv plane
    166     uvoffset =  stride * bufHeight;
    167     // offset to beginning of valid region of uv plane
    168     uvoffset += (offset - (offset % stride)) / 2 + (offset % stride);
    169 
    170     // start of valid luma region
    171     luma = src + offset;
    172     // start of valid chroma region
    173     chroma = src + uvoffset;
    174 
    175     // write luma line x line
    176     unsigned int height = crop.height();
    177     unsigned int width = crop.width();
    178     write_size = width;
    179     for (unsigned int i = 0; i < height; i++) {
    180         if (write_size != write(fd, luma, width)) {
    181             printf("Bad Write error (%d)%s\n",
    182                     errno, strerror(errno));
    183             return UNKNOWN_ERROR;
    184         }
    185         luma += stride;
    186     }
    187 
    188     // write chroma line x line
    189     height /= 2;
    190     write_size = width;
    191     for (unsigned int i = 0; i < height; i++) {
    192         if (write_size != write(fd, chroma, width)) {
    193             printf("Bad Write error (%d)%s\n",
    194                     errno, strerror(errno));
    195             return UNKNOWN_ERROR;
    196         }
    197         chroma += stride;
    198     }
    199 
    200     return NO_ERROR;
    201 }
    202 
    203 static status_t writeCroppedUYVY(unsigned int offset,
    204                                  unsigned int stride,
    205                                  unsigned int bufWidth,
    206                                  unsigned int bufHeight,
    207                                  const Rect &crop,
    208                                  int fd,
    209                                  unsigned char *buffer)
    210 {
    211     unsigned char *src = NULL;
    212     int write_size;
    213 
    214     if (!buffer) {
    215         return BAD_VALUE;
    216     }
    217 
    218     src = buffer + offset;
    219     int height = crop.height();
    220     int width = crop.width();
    221     write_size = width*2;
    222     for (unsigned int i = 0; i < height; i++) {
    223         if (write_size != write(fd, src, width*2)) {
    224             printf("Bad Write error (%d)%s\n",
    225                     errno, strerror(errno));
    226             return UNKNOWN_ERROR;
    227         }
    228         src += stride*2;
    229     }
    230 
    231     return NO_ERROR;
    232 }
    233 
    234 static status_t copyCroppedNV12(unsigned int offset,
    235                                 unsigned int strideSrc,
    236                                 unsigned int strideDst,
    237                                 unsigned int bufWidth,
    238                                 unsigned int bufHeight,
    239                                 const Rect &crop,
    240                                 void *bufferSrc,
    241                                 void *bufferDst)
    242 {
    243     unsigned char *lumaSrc = NULL, *chromaSrc = NULL;
    244     unsigned char *lumaDst = NULL, *chromaDst = NULL;
    245     unsigned int uvoffset;
    246     int write_size;
    247 
    248     if (!bufferSrc || !bufferDst) {
    249         return BAD_VALUE;
    250     }
    251 
    252     uvoffset = strideSrc * crop.height();
    253     uvoffset += (offset - (offset % strideSrc)) / 2 + (offset % strideSrc);
    254 
    255     lumaSrc = static_cast<unsigned char *>(bufferSrc) + offset;
    256     chromaSrc = static_cast<unsigned char *>(bufferSrc) + uvoffset;
    257 
    258     int height = crop.height();
    259     int width = crop.width();
    260 
    261     uvoffset =  strideDst * height;
    262 
    263     lumaDst = static_cast<unsigned char *>(bufferDst);
    264     chromaDst = static_cast<unsigned char *>(bufferDst) + uvoffset;
    265 
    266     write_size = width;
    267     for (unsigned int i = 0; i < height; i++) {
    268         memcpy(lumaDst, lumaSrc, width);
    269         lumaSrc += strideSrc;
    270         lumaDst += strideDst;
    271     }
    272 
    273     height /= 2;
    274     write_size = width;
    275     for (unsigned int i = 0; i < height; i++) {
    276         memcpy(chromaDst, chromaSrc, width);
    277         chromaSrc += strideSrc;
    278         chromaDst += strideDst;
    279     }
    280 
    281     return NO_ERROR;
    282 }
    283 
    284 static status_t copyCroppedPacked16(unsigned int offset,
    285                                     unsigned int stride,
    286                                     unsigned int bufWidth,
    287                                     unsigned int bufHeight,
    288                                     const Rect &crop,
    289                                     void *bufferSrc,
    290                                     void *bufferDst)
    291 {
    292     unsigned char *src = NULL, *dst = NULL;
    293 
    294     if (!bufferSrc || !bufferDst) {
    295         return BAD_VALUE;
    296     }
    297 
    298     src = static_cast<unsigned char *>(bufferSrc) + offset;
    299     dst = static_cast<unsigned char *>(bufferDst);
    300 
    301     int height = crop.height();
    302     int width = crop.width();
    303     for (unsigned int i = 0; i < height; i++) {
    304         memcpy(dst, src, width*2);
    305         src += stride*2;
    306         dst += width*2;
    307     }
    308 
    309     return NO_ERROR;
    310 }
    311 
    312 void GLSurface::initialize(int display) {
    313     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    314     ASSERT(EGL_SUCCESS == eglGetError());
    315     ASSERT(EGL_NO_DISPLAY != mEglDisplay);
    316 
    317     EGLint majorVersion;
    318     EGLint minorVersion;
    319     ASSERT(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
    320     ASSERT(EGL_SUCCESS == eglGetError());
    321 
    322     EGLint numConfigs = 0;
    323     ASSERT(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
    324                 1, &numConfigs));
    325     ASSERT(EGL_SUCCESS == eglGetError());
    326 
    327     if (display) {
    328         mComposerClient = new SurfaceComposerClient;
    329         ASSERT(NO_ERROR == mComposerClient->initCheck());
    330         mSurfaceControl = mComposerClient->createSurface(
    331                 String8("Test Surface"), 0,
    332                 800, 480, HAL_PIXEL_FORMAT_YCrCb_420_SP, 0);
    333 
    334         ASSERT(mSurfaceControl != NULL);
    335         ASSERT(mSurfaceControl->isValid());
    336 
    337         SurfaceComposerClient::openGlobalTransaction();
    338         ASSERT(NO_ERROR == mSurfaceControl->setLayer(0x7FFFFFFF));
    339         ASSERT(NO_ERROR == mSurfaceControl->show());
    340         SurfaceComposerClient::closeGlobalTransaction();
    341 
    342         sp<ANativeWindow> window = mSurfaceControl->getSurface();
    343         mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
    344                 window.get(), NULL);
    345     } else {
    346         EGLint pbufferAttribs[] = {
    347             EGL_WIDTH, getSurfaceWidth(),
    348             EGL_HEIGHT, getSurfaceHeight(),
    349             EGL_NONE };
    350         mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
    351                 pbufferAttribs);
    352     }
    353     ASSERT(EGL_SUCCESS == eglGetError());
    354     ASSERT(EGL_NO_SURFACE != mEglSurface);
    355 
    356     mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
    357             getContextAttribs());
    358     ASSERT(EGL_SUCCESS == eglGetError());
    359     ASSERT(EGL_NO_CONTEXT != mEglContext);
    360 
    361     ASSERT(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
    362             mEglContext));
    363     ASSERT(EGL_SUCCESS == eglGetError());
    364 
    365     EGLint w, h;
    366     ASSERT(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
    367     ASSERT(EGL_SUCCESS == eglGetError());
    368     ASSERT(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
    369     ASSERT(EGL_SUCCESS == eglGetError());
    370 
    371     glViewport(0, 0, w, h);
    372     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    373 }
    374 
    375 void GLSurface::deinit() {
    376     if (mComposerClient != NULL) {
    377         mComposerClient->dispose();
    378     }
    379 
    380     if (mEglContext != EGL_NO_CONTEXT) {
    381         eglDestroyContext(mEglDisplay, mEglContext);
    382     }
    383 
    384     if (mEglSurface != EGL_NO_SURFACE) {
    385         eglDestroySurface(mEglDisplay, mEglSurface);
    386     }
    387     if (mEglDisplay != EGL_NO_DISPLAY) {
    388         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
    389                EGL_NO_CONTEXT);
    390         eglTerminate(mEglDisplay);
    391     }
    392     ASSERT(EGL_SUCCESS == eglGetError());
    393 }
    394 
    395 EGLint const* GLSurface::getConfigAttribs() {
    396     static EGLint sDefaultConfigAttribs[] = {
    397         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    398         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    399         EGL_RED_SIZE, 8,
    400         EGL_GREEN_SIZE, 8,
    401         EGL_BLUE_SIZE, 8,
    402         EGL_ALPHA_SIZE, 8,
    403         EGL_DEPTH_SIZE, 16,
    404         EGL_STENCIL_SIZE, 8,
    405         EGL_NONE };
    406 
    407     return sDefaultConfigAttribs;
    408 }
    409 
    410 EGLint const* GLSurface::getContextAttribs() {
    411     static EGLint sDefaultContextAttribs[] = {
    412         EGL_CONTEXT_CLIENT_VERSION, 2,
    413         EGL_NONE };
    414 
    415     return sDefaultContextAttribs;
    416 }
    417 
    418 void GLSurface::loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
    419     GLuint shader = glCreateShader(shaderType);
    420     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    421     if (shader) {
    422         glShaderSource(shader, 1, &pSource, NULL);
    423         ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    424         glCompileShader(shader);
    425         ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    426         GLint compiled = 0;
    427         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    428         ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    429         if (!compiled) {
    430             GLint infoLen = 0;
    431             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    432             ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    433             if (infoLen) {
    434                 char* buf = (char*) malloc(infoLen);
    435                 if (buf) {
    436                     glGetShaderInfoLog(shader, infoLen, NULL, buf);
    437                     printf("Shader compile log:\n%s\n", buf);
    438                     free(buf);
    439                 }
    440             } else {
    441                 char* buf = (char*) malloc(0x1000);
    442                 if (buf) {
    443                     glGetShaderInfoLog(shader, 0x1000, NULL, buf);
    444                     printf("Shader compile log:\n%s\n", buf);
    445                     free(buf);
    446                 }
    447             }
    448             glDeleteShader(shader);
    449             shader = 0;
    450         }
    451     }
    452     ASSERT(shader != 0);
    453     *outShader = shader;
    454 }
    455 
    456 void GLSurface::createProgram(const char* pVertexSource, const char* pFragmentSource,
    457             GLuint* outPgm) {
    458     GLuint vertexShader, fragmentShader;
    459     {
    460         loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
    461     }
    462     {
    463         loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
    464     }
    465 
    466     GLuint program = glCreateProgram();
    467     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    468     if (program) {
    469         glAttachShader(program, vertexShader);
    470         ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    471         glAttachShader(program, fragmentShader);
    472         ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    473         glLinkProgram(program);
    474         GLint linkStatus = GL_FALSE;
    475         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    476         if (linkStatus != GL_TRUE) {
    477             GLint bufLength = 0;
    478             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
    479             if (bufLength) {
    480                 char* buf = (char*) malloc(bufLength);
    481                 if (buf) {
    482                     glGetProgramInfoLog(program, bufLength, NULL, buf);
    483                     printf("Program link log:\n%s\n", buf);
    484                     free(buf);
    485                 }
    486             }
    487             glDeleteProgram(program);
    488             program = 0;
    489         }
    490     }
    491     glDeleteShader(vertexShader);
    492     glDeleteShader(fragmentShader);
    493     ASSERT(program != 0);
    494     *outPgm = program;
    495 }
    496 
    497 // GLConsumer specific
    498 sp<GLConsumer> SurfaceTextureBase::getST() {
    499      return mST;
    500 }
    501 
    502 void SurfaceTextureBase::initialize(int tex_id, EGLenum tex_target) {
    503     mTexId = tex_id;
    504     sp<BufferQueue> bq = new BufferQueue();
    505     mST = new GLConsumer(bq, tex_id, tex_target);
    506     mSTC = new Surface(mST);
    507     mANW = mSTC;
    508 }
    509 
    510 void SurfaceTextureBase::deinit() {
    511     mANW.clear();
    512     mSTC.clear();
    513 
    514     mST->abandon();
    515     mST.clear();
    516 }
    517 
    518 void SurfaceTextureBase::getId(const char **name) {
    519     sp<ANativeWindow> windowTapOut = mSTC;
    520 
    521     *name = NULL;
    522     if (windowTapOut.get()) {
    523         windowTapOut->perform(windowTapOut.get(), NATIVE_WINDOW_GET_ID, name);
    524     }
    525 
    526     windowTapOut.clear();
    527 }
    528 
    529 // GLConsumer with GL specific
    530 
    531 void SurfaceTextureGL::initialize(int display, int tex_id) {
    532     GLSurface::initialize(display);
    533     SurfaceTextureBase::initialize(tex_id, GL_TEXTURE_EXTERNAL_OES);
    534 
    535     const char vsrc[] =
    536         "attribute vec4 vPosition;\n"
    537         "varying vec2 texCoords;\n"
    538         "uniform mat4 texMatrix;\n"
    539         "void main() {\n"
    540         "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
    541         "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
    542         "  gl_Position = vPosition;\n"
    543         "}\n";
    544 
    545     const char fsrc[] =
    546         "#extension GL_OES_EGL_image_external : require\n"
    547         "precision mediump float;\n"
    548         "uniform samplerExternalOES texSampler;\n"
    549         "varying vec2 texCoords;\n"
    550         "void main() {\n"
    551         "  gl_FragColor = texture2D(texSampler, texCoords);\n"
    552         "}\n";
    553 
    554     {
    555         createProgram(vsrc, fsrc, &mPgm);
    556     }
    557 
    558     mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
    559     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    560     ASSERT(-1 != mPositionHandle);
    561     mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
    562     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    563     ASSERT(-1 != mTexSamplerHandle);
    564     mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
    565     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    566     ASSERT(-1 != mTexMatrixHandle);
    567 }
    568 
    569 void SurfaceTextureGL::deinit() {
    570     SurfaceTextureBase::deinit();
    571     GLSurface::deinit();
    572 }
    573 
    574 // drawTexture draws the GLConsumer over the entire GL viewport.
    575 void SurfaceTextureGL::drawTexture() {
    576     const GLfloat triangleVertices[] = {
    577         -1.0f, 1.0f,
    578         -1.0f, -1.0f,
    579         1.0f, -1.0f,
    580         1.0f, 1.0f,
    581     };
    582 
    583     glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
    584             triangleVertices);
    585     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    586     glEnableVertexAttribArray(mPositionHandle);
    587     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    588 
    589     glUseProgram(mPgm);
    590     glUniform1i(mTexSamplerHandle, 0);
    591     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    592     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexId);
    593     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    594 
    595     // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
    596     // they're setting the defautls for that target, but when hacking things
    597     // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
    598     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
    599             GL_LINEAR);
    600     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    601     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
    602             GL_LINEAR);
    603     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    604     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
    605             GL_CLAMP_TO_EDGE);
    606     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    607     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
    608             GL_CLAMP_TO_EDGE);
    609     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    610 
    611     GLfloat texMatrix[16];
    612     mST->getTransformMatrix(texMatrix);
    613     glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
    614 
    615     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    616     ASSERT(GLenum(GL_NO_ERROR) == glGetError());
    617 
    618     eglSwapBuffers(mEglDisplay, mEglSurface);
    619 }
    620 
    621 // buffer source stuff
    622 void BufferSourceThread::handleBuffer(sp<GraphicBuffer> &graphic_buffer, uint8_t *buffer,
    623                                         unsigned int count, const Rect &crop) {
    624     int size;
    625     buffer_info_t info;
    626     unsigned int offset = 0;
    627     int fd = -1;
    628     char fn[256];
    629 
    630     if (!graphic_buffer.get()) {
    631         printf("Invalid graphic_buffer!\n");
    632         return;
    633     }
    634 
    635     size = calcBufSize((int)graphic_buffer->getPixelFormat(),
    636                               graphic_buffer->getWidth(),
    637                               graphic_buffer->getHeight());
    638     if (size <= 0) {
    639         printf("Can't get size!\n");
    640         return;
    641     }
    642 
    643     if (!buffer) {
    644         printf("Invalid mapped buffer!\n");
    645         return;
    646     }
    647 
    648     info.size = size;
    649     info.width = graphic_buffer->getWidth();
    650     info.height = graphic_buffer->getHeight();
    651     info.format = graphic_buffer->getPixelFormat();
    652     info.buf = graphic_buffer;
    653     info.crop = crop;
    654 
    655     {
    656         Mutex::Autolock lock(mReturnedBuffersMutex);
    657         if (mReturnedBuffers.size() >= kReturnedBuffersMaxCapacity) mReturnedBuffers.removeAt(0);
    658     }
    659 
    660     // re-calculate size and offset
    661     size = calcBufSize((int) graphic_buffer->getPixelFormat(), crop.width(), crop.height());
    662     offset = calcOffset((int) graphic_buffer->getPixelFormat(), info.width, crop.top, crop.left);
    663 
    664     // Do not write buffer to file if we are streaming capture
    665     // It adds too much latency
    666     if (!mRestartCapture) {
    667         fn[0] = 0;
    668         sprintf(fn, "/sdcard/img%03d.raw", count);
    669         fd = open(fn, O_CREAT | O_WRONLY | O_TRUNC, 0777);
    670         if (fd >= 0) {
    671             if (HAL_PIXEL_FORMAT_TI_NV12 == info.format) {
    672                 writeCroppedNV12(offset, info.width, info.width, info.height,
    673                                  crop, fd, buffer);
    674             } else if (HAL_PIXEL_FORMAT_TI_UYVY == info.format) {
    675                 writeCroppedUYVY(offset, info.width, info.width, info.height,
    676                                  crop, fd, buffer);
    677             } else if (size != write(fd, buffer + offset, size)) {
    678                 printf("Bad Write int a %s error (%d)%s\n", fn, errno, strerror(errno));
    679             }
    680             printf("%s: buffer=%08X, size=%d stored at %s\n"
    681                    "\tRect: top[%d] left[%d] right[%d] bottom[%d] width[%d] height[%d] offset[%d] stride[%d]\n",
    682                         __FUNCTION__, (int)buffer, size, fn,
    683                         crop.top, crop.left, crop.right, crop.bottom,
    684                         crop.width(), crop.height(),
    685                         offset, info.width);
    686             close(fd);
    687         } else {
    688             printf("error opening or creating %s\n", fn);
    689         }
    690     }
    691 }
    692 
    693 Rect BufferSourceThread::getCrop(sp<GraphicBuffer> &graphic_buffer, const float *mtx) {
    694     Rect crop(graphic_buffer->getWidth(), graphic_buffer->getHeight());
    695 
    696     // calculate crop rectangle from tranformation matrix
    697     float sx, sy, tx, ty, h, w;
    698     unsigned int rect_x, rect_y;
    699     /*   sx, 0, 0, 0,
    700          0, sy, 0, 0,
    701          0, 0, 1, 0,
    702          tx, ty, 0, 1 */
    703 
    704     sx = mtx[0];
    705     sy = mtx[5];
    706     tx = mtx[12];
    707     ty = mtx[13];
    708     w = float(graphic_buffer->getWidth());
    709     h = float(graphic_buffer->getHeight());
    710 
    711     unsigned int bottom = (unsigned int)(h - (ty * h + 1));
    712     unsigned int left = (unsigned int)(tx * w -1);
    713     rect_y = (unsigned int)(fabsf(sy) * h);
    714     rect_x = (unsigned int)(fabsf(sx) * w);
    715 
    716     // handle v-flip
    717     if (sy < 0.0f) {
    718         bottom = h - bottom;
    719     }
    720 
    721     // handle h-flip
    722     if (sx < 0.0f) {
    723         left = w - left;
    724     }
    725 
    726     unsigned int top = bottom - rect_y;
    727     unsigned int right = left + rect_x;
    728 
    729     Rect updatedCrop(left, top, right, bottom);
    730     if (updatedCrop.isValid()) {
    731         crop = updatedCrop;
    732     } else {
    733         printf("Crop for buffer %d is not valid: "
    734                "left=%u, top=%u, right=%u, bottom=%u. "
    735                "Will use default.\n",
    736                mCounter,
    737                left, top, right, bottom);
    738     }
    739 
    740     return crop;
    741 }
    742 
    743 void BufferSourceInput::setInput(buffer_info_t bufinfo, const char *format, ShotParameters &params) {
    744     ANativeWindowBuffer* anb;
    745     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    746     int pixformat = HAL_PIXEL_FORMAT_TI_NV12;
    747     size_t tapInMinUndequeued = 0;
    748 
    749     int aligned_width, aligned_height;
    750 
    751     pixformat = bufinfo.format;
    752 
    753     // Aligning is not needed for Bayer
    754     if ( ( pixformat == HAL_PIXEL_FORMAT_TI_Y16 ) ||
    755          ( pixformat == HAL_PIXEL_FORMAT_TI_UYVY ) ) {
    756         aligned_width = bufinfo.crop.right - bufinfo.crop.left;
    757     } else {
    758         aligned_width = ALIGN_UP(bufinfo.crop.right - bufinfo.crop.left, ALIGN_WIDTH);
    759     }
    760     aligned_height = bufinfo.crop.bottom - bufinfo.crop.top;
    761     printf("aligned width: %d height: %d \n", aligned_width, aligned_height);
    762 
    763     if (mWindowTapIn.get() == 0) {
    764         return;
    765     }
    766 
    767     native_window_set_usage(mWindowTapIn.get(),
    768                             getUsageFromANW(pixformat));
    769     mWindowTapIn->perform(mWindowTapIn.get(),
    770                           NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
    771                           &tapInMinUndequeued);;
    772     native_window_set_buffer_count(mWindowTapIn.get(), tapInMinUndequeued);
    773     native_window_set_buffers_geometry(mWindowTapIn.get(),
    774                   aligned_width, aligned_height, bufinfo.format);
    775 
    776     // if buffer dimensions are the same as the aligned dimensions, then we can
    777     // queue the buffer directly to tapin surface. if the dimensions are different
    778     // then the aligned ones, then we have to copy the buffer into our own buffer
    779     // to make sure the stride of the buffer is correct
    780     if ((aligned_width != bufinfo.width) || (aligned_height != bufinfo.height) ||
    781         ( pixformat == HAL_PIXEL_FORMAT_TI_Y16 ) ||
    782         ( pixformat == HAL_PIXEL_FORMAT_TI_UYVY) ) {
    783         void *dest[3] = { 0 };
    784         void *src[3] = { 0 };
    785         Rect bounds(aligned_width, aligned_height);
    786 
    787         mWindowTapIn->dequeueBuffer(mWindowTapIn.get(), &anb);
    788         mapper.lock(anb->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, dest);
    789         // copy buffer to input buffer if available
    790         if (bufinfo.buf.get()) {
    791             bufinfo.buf->lock(GRALLOC_USAGE_SW_READ_OFTEN, src);
    792         }
    793         if (src[0]) {
    794             switch (pixformat) {
    795                 case HAL_PIXEL_FORMAT_TI_Y16:
    796                 case HAL_PIXEL_FORMAT_TI_UYVY:
    797                     copyCroppedPacked16(bufinfo.offset,
    798                                         bufinfo.width,
    799                                         bufinfo.width,
    800                                         bufinfo.height,
    801                                         bufinfo.crop,
    802                                         src[0],
    803                                         dest[0]);
    804                     break;
    805                 case HAL_PIXEL_FORMAT_TI_NV12:
    806                     copyCroppedNV12(bufinfo.offset,
    807                                     bufinfo.width,
    808                                     aligned_width,
    809                                     bufinfo.width,
    810                                     bufinfo.height,
    811                                     bufinfo.crop,
    812                                     src[0],
    813                                     dest[0]);
    814                     break;
    815                 default:
    816                     printf("Pixel format 0x%x not supported\n", pixformat);
    817                     exit(1);
    818                     break;
    819             }
    820         }
    821         if (bufinfo.buf.get()) {
    822             bufinfo.buf->unlock();
    823         }
    824 
    825         mapper.unlock(anb->handle);
    826     } else {
    827         mWindowTapIn->perform(mWindowTapIn.get(), NATIVE_WINDOW_ADD_BUFFER_SLOT, &bufinfo.buf);
    828         anb = bufinfo.buf->getNativeBuffer();
    829     }
    830 
    831     mWindowTapIn->queueBuffer(mWindowTapIn.get(), anb);
    832 
    833     {
    834         sp<ANativeWindow> windowTapIn = mWindowTapIn;
    835         const char* id = NULL;
    836 
    837         if (windowTapIn.get()) {
    838             windowTapIn->perform(windowTapIn.get(), NATIVE_WINDOW_GET_ID, &id);
    839         }
    840 
    841         if (id) {
    842             params.set(KEY_TAP_IN_SURFACE, id);
    843         } else {
    844             params.remove(KEY_TAP_IN_SURFACE);
    845         }
    846 
    847         windowTapIn.clear();
    848     }
    849 }
    850 
    851 void BufferSourceThread::showMetadata(sp<IMemory> data) {
    852     static nsecs_t prevTime = 0;
    853     nsecs_t currTime = 0;
    854 
    855     ssize_t offset;
    856     size_t size;
    857 
    858     if ( NULL == data.get() ) {
    859         printf("No Metadata!");
    860         return;
    861     }
    862 
    863     sp<IMemoryHeap> heap = data->getMemory(&offset, &size);
    864     camera_metadata_t * meta = static_cast<camera_metadata_t *> (heap->base());
    865 
    866     printf("         frame nmber: %d\n", meta->frame_number);
    867     printf("         shot number: %d\n", meta->shot_number);
    868     printf("         analog gain: %d req: %d range: %d~%d dev: %d err: %d\n",
    869            meta->analog_gain,
    870            meta->analog_gain_req,
    871            meta->analog_gain_min,
    872            meta->analog_gain_max,
    873            meta->analog_gain_dev,
    874            meta->analog_gain_error);
    875     printf("       exposure time: %d req: %d range: %d~%d dev: %d err: %d\n",
    876            meta->exposure_time,
    877            meta->exposure_time_req,
    878            meta->exposure_time_min,
    879            meta->exposure_time_max,
    880            meta->exposure_time_dev,
    881            meta->exposure_time_error);
    882     printf("     EV compensation: req: %d dev: %d\n",
    883            meta->exposure_compensation_req,
    884            meta->exposure_dev);
    885     printf("            awb gain: %d\n", meta->analog_gain);
    886     printf("         awb offsets: %d\n", meta->offset_b);
    887     printf("     awb temperature: %d\n", meta->awb_temp);
    888 
    889     printf("   LSC table applied: %d\n", meta->lsc_table_applied);
    890     if ( meta->lsc_table_applied ) {
    891         uint8_t *lscTable = (uint8_t *)meta + meta->lsc_table_offset;
    892         printf("LSC Table Size:%d Data[0:7]: %d:%d:%d:%d:%d:%d:%d:%d\n",
    893                 meta->lsc_table_size,
    894                 lscTable[0],
    895                 lscTable[1],
    896                 lscTable[2],
    897                 lscTable[3],
    898                 lscTable[4],
    899                 lscTable[5],
    900                 lscTable[6],
    901                 lscTable[7]);
    902     }
    903 
    904     printf("    Faces detected: %d\n", meta->number_of_faces);
    905 
    906     currTime = meta->timestamp;
    907     printf("      timestamp (ns): %llu\n", currTime);
    908     if (prevTime) printf("inter-shot time (ms): %llu\n", (currTime - prevTime) / 1000000l);
    909     prevTime = currTime;
    910 }
    911