• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getSurfaceWidth()61 static EGLint getSurfaceWidth() {
62     return 512;
63 }
64 
getSurfaceHeight()65 static EGLint getSurfaceHeight() {
66     return 512;
67 }
68 
calcBufSize(int format,int width,int height)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 
calcOffset(int format,unsigned int width,unsigned int top,unsigned int left)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 
getHalPixFormat(const char * format)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 
getUsageFromANW(int format)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 
writeCroppedNV12(unsigned int offset,unsigned int stride,unsigned int bufWidth,unsigned int bufHeight,const Rect & crop,int fd,unsigned char * buffer)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 
writeCroppedUYVY(unsigned int offset,unsigned int stride,unsigned int bufWidth,unsigned int bufHeight,const Rect & crop,int fd,unsigned char * buffer)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 
copyCroppedNV12(unsigned int offset,unsigned int strideSrc,unsigned int strideDst,unsigned int bufWidth,unsigned int bufHeight,const Rect & crop,void * bufferSrc,void * bufferDst)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 
copyCroppedPacked16(unsigned int offset,unsigned int stride,unsigned int bufWidth,unsigned int bufHeight,const Rect & crop,void * bufferSrc,void * bufferDst)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 
initialize(int display)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 
deinit()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 
getConfigAttribs()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 
getContextAttribs()410 EGLint const* GLSurface::getContextAttribs() {
411     static EGLint sDefaultContextAttribs[] = {
412         EGL_CONTEXT_CLIENT_VERSION, 2,
413         EGL_NONE };
414 
415     return sDefaultContextAttribs;
416 }
417 
loadShader(GLenum shaderType,const char * pSource,GLuint * outShader)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 
createProgram(const char * pVertexSource,const char * pFragmentSource,GLuint * outPgm)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
getST()498 sp<GLConsumer> SurfaceTextureBase::getST() {
499      return mST;
500 }
501 
initialize(int tex_id,EGLenum tex_target)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 
deinit()510 void SurfaceTextureBase::deinit() {
511     mANW.clear();
512     mSTC.clear();
513 
514     mST->abandon();
515     mST.clear();
516 }
517 
getId(const char ** name)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 
initialize(int display,int tex_id)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 
deinit()569 void SurfaceTextureGL::deinit() {
570     SurfaceTextureBase::deinit();
571     GLSurface::deinit();
572 }
573 
574 // drawTexture draws the GLConsumer over the entire GL viewport.
drawTexture()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
handleBuffer(sp<GraphicBuffer> & graphic_buffer,uint8_t * buffer,unsigned int count,const Rect & crop)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 
getCrop(sp<GraphicBuffer> & graphic_buffer,const float * mtx)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 
setInput(buffer_info_t bufinfo,const char * format,ShotParameters & params)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 
showMetadata(sp<IMemory> data)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