Home | History | Annotate | Download | only in test
      1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include <stdlib.h>
     31 #include <unistd.h>
     32 #include <fcntl.h>
     33 #include <time.h>
     34 #include <semaphore.h>
     35 #include <pthread.h>
     36 
     37 #include <sys/types.h>
     38 #include <sys/stat.h>
     39 #include <sys/wait.h>
     40 
     41 #include <ui/DisplayInfo.h>
     42 #include <gui/Surface.h>
     43 #include <gui/SurfaceComposerClient.h>
     44 #include <gui/ISurfaceComposer.h>
     45 
     46 #include <system/camera.h>
     47 
     48 #include <camera/Camera.h>
     49 #include <camera/ICamera.h>
     50 #include <camera/CameraParameters.h>
     51 #include <media/mediarecorder.h>
     52 
     53 #include <utils/RefBase.h>
     54 #include <utils/Mutex.h>
     55 #include <utils/Condition.h>
     56 #include <binder/IPCThreadState.h>
     57 #include <binder/ProcessState.h>
     58 #include <binder/IServiceManager.h>
     59 #include <cutils/properties.h>
     60 #include <cutils/memory.h>
     61 #include <SkImageDecoder.h>
     62 #include <SkImageEncoder.h>
     63 #include <MediaCodec.h>
     64 #include <OMX_IVCommon.h>
     65 #include <foundation/AMessage.h>
     66 #include <media/ICrypto.h>
     67 #include <MediaMuxer.h>
     68 #include <foundation/ABuffer.h>
     69 #include <MediaErrors.h>
     70 #include <gralloc_priv.h>
     71 #include <math.h>
     72 
     73 #include "qcamera_test.h"
     74 #include "cam_types.h"
     75 #include "mm_camera_dbg.h"
     76 
     77 #define VIDEO_BUF_ALLIGN(size, allign) \
     78   (((size) + (allign-1)) & (typeof(size))(~(allign-1)))
     79 
     80 namespace qcamera {
     81 
     82 using namespace android;
     83 
     84 int CameraContext::JpegIdx = 0;
     85 int CameraContext::mPiPIdx = 0;
     86 const char CameraContext::KEY_ZSL[] = "zsl";
     87 
     88 /*===========================================================================
     89  * FUNCTION   : previewCallback
     90  *
     91  * DESCRIPTION: preview callback preview mesages are enabled
     92  *
     93  * PARAMETERS :
     94  *   @mem : preview buffer
     95  *
     96  * RETURN     : None
     97  *==========================================================================*/
     98 void CameraContext::previewCallback(const sp<IMemory>& mem)
     99 {
    100     printf("PREVIEW Callback %p", mem->pointer());
    101     uint8_t *ptr = (uint8_t*) mem->pointer();
    102     if (NULL != ptr) {
    103         printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
    104                 ptr[0],
    105                 ptr[1],
    106                 ptr[2],
    107                 ptr[3],
    108                 ptr[4],
    109                 ptr[5],
    110                 ptr[6],
    111                 ptr[7],
    112                 ptr[8],
    113                 ptr[9]);
    114     } else {
    115         ALOGE(" no preview for NULL CB\n");
    116     }
    117 }
    118 
    119 /*===========================================================================
    120  * FUNCTION   : useLock
    121  *
    122  * DESCRIPTION: Mutex lock for CameraContext
    123  *
    124  * PARAMETERS : none
    125  *
    126  * RETURN     : none
    127  *==========================================================================*/
    128 void CameraContext::useLock()
    129 {
    130     Mutex::Autolock l(mLock);
    131     while (mInUse) {
    132         mCond.wait(mLock);
    133     }
    134     mInUse = true;
    135 }
    136 
    137 /*===========================================================================
    138  * FUNCTION   : signalFinished
    139  *
    140  * DESCRIPTION: Mutex unlock CameraContext
    141  *
    142  * PARAMETERS : none
    143  *
    144  * RETURN     : none
    145  *==========================================================================*/
    146 void CameraContext::signalFinished()
    147 {
    148     Mutex::Autolock l(mLock);
    149     mInUse = false;
    150     mCond.signal();
    151 }
    152 
    153 /*===========================================================================
    154  * FUNCTION   : saveFile
    155  *
    156  * DESCRIPTION: helper function for saving buffers on filesystem
    157  *
    158  * PARAMETERS :
    159  *   @mem : buffer to save to filesystem
    160  *   @path: File path
    161  *
    162  * RETURN     : status_t type of status
    163  *              NO_ERROR  -- success
    164  *              none-zero failure code
    165  *==========================================================================*/
    166 status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path)
    167 {
    168     unsigned char *buff = NULL;
    169     ssize_t size;
    170     int fd = -1;
    171 
    172     if (mem == NULL) {
    173         return BAD_VALUE;
    174     }
    175 
    176     fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0655);
    177     if(fd < 0) {
    178         printf("Unable to open file %s %s\n", path.string(), strerror(fd));
    179         return -errno;
    180     }
    181 
    182     size = (ssize_t)mem->size();
    183     if (size <= 0) {
    184         printf("IMemory object is of zero size\n");
    185         close(fd);
    186         return BAD_VALUE;
    187     }
    188 
    189     buff = (unsigned char *)mem->pointer();
    190     if (!buff) {
    191         printf("Buffer pointer is invalid\n");
    192         close(fd);
    193         return BAD_VALUE;
    194     }
    195 
    196     if (size != write(fd, buff, (size_t)size)) {
    197         printf("Bad Write error (%d)%s\n", errno, strerror(errno));
    198         close(fd);
    199         return INVALID_OPERATION;
    200     }
    201 
    202     printf("%s: buffer=%p, size=%lld stored at %s\n",
    203             __FUNCTION__, buff, (long long int) size, path.string());
    204 
    205     if (fd >= 0)
    206         close(fd);
    207 
    208     return NO_ERROR;
    209 }
    210 
    211 /*===========================================================================
    212  * FUNCTION   : PiPCopyToOneFile
    213  *
    214  * DESCRIPTION: Copy the smaller picture to the bigger one
    215  *
    216  * PARAMETERS :
    217  *   @bitmap0 : Decoded image buffer 0
    218  *   @bitmap1 : Decoded image buffer 1
    219  *
    220  * RETURN     : decoded picture in picture in SkBitmap
    221  *==========================================================================*/
    222 SkBitmap * CameraContext::PiPCopyToOneFile(
    223     SkBitmap *bitmap0, SkBitmap *bitmap1)
    224 {
    225     size_t size0;
    226     size_t size1;
    227     SkBitmap *src;
    228     SkBitmap *dst;
    229     unsigned int dstOffset;
    230     unsigned int srcOffset;
    231 
    232     if (bitmap0 == NULL || bitmap1 == NULL) {
    233         ALOGE(" bitmap0 : %p, bitmap1 : %p\n",  bitmap0, bitmap1);
    234         return NULL;
    235     }
    236 
    237     size0 = bitmap0->getSize();
    238     if (size0 <= 0) {
    239         printf("Decoded image 0 is of zero size\n");
    240         return NULL;
    241     }
    242 
    243     size1 = bitmap1->getSize();
    244         if (size1 <= 0) {
    245             printf("Decoded image 1 is of zero size\n");
    246             return NULL;
    247         }
    248 
    249     if (size0 > size1) {
    250         dst = bitmap0;
    251         src = bitmap1;
    252     } else if (size1 > size0){
    253         dst = bitmap1;
    254         src = bitmap0;
    255     } else {
    256         printf("Picture size should be with different size!\n");
    257         return NULL;
    258     }
    259 
    260     for (unsigned int i = 0; i < (unsigned int)src->height(); i++) {
    261         dstOffset = i * (unsigned int)dst->width() * mfmtMultiplier;
    262         srcOffset = i * (unsigned int)src->width() * mfmtMultiplier;
    263         memcpy(((unsigned char *)dst->getPixels()) + dstOffset,
    264                 ((unsigned char *)src->getPixels()) + srcOffset,
    265                 (unsigned int)src->width() * mfmtMultiplier);
    266     }
    267 
    268     return dst;
    269 }
    270 
    271 /*===========================================================================
    272  * FUNCTION   : decodeJPEG
    273  *
    274  * DESCRIPTION: decode jpeg input buffer.
    275  *
    276  * PARAMETERS :
    277  *   @mem     : buffer to decode
    278  *   @skBM    : decoded buffer
    279  *
    280  * RETURN     : status_t type of status
    281  *              NO_ERROR  -- success
    282  *              none-zero failure code
    283 
    284  *==========================================================================*/
    285 status_t CameraContext::decodeJPEG(const sp<IMemory>& mem, SkBitmap *skBM)
    286 {
    287 #ifndef USE_SDK_20_OR_HIGHER
    288     SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
    289     const void *buff = NULL;
    290     size_t size;
    291 
    292     buff = (const void *)mem->pointer();
    293     size= mem->size();
    294 
    295     switch(prefConfig) {
    296         case SkBitmap::kARGB_8888_Config:
    297         {
    298             mfmtMultiplier = 4;
    299         }
    300             break;
    301 
    302         case SkBitmap::kARGB_4444_Config:
    303         {
    304             mfmtMultiplier = 2;
    305         }
    306         break;
    307 
    308         case SkBitmap::kRGB_565_Config:
    309         {
    310             mfmtMultiplier = 2;
    311         }
    312         break;
    313 
    314         case SkBitmap::kIndex8_Config:
    315         {
    316             mfmtMultiplier = 4;
    317         }
    318         break;
    319 
    320         case SkBitmap::kA8_Config:
    321         {
    322             mfmtMultiplier = 4;
    323         }
    324         break;
    325 
    326         default:
    327         {
    328             mfmtMultiplier = 0;
    329             printf("Decode format is not correct!\n");
    330         }
    331         break;
    332     }
    333 
    334     if (SkImageDecoder::DecodeMemory(buff, size, skBM, prefConfig,
    335             SkImageDecoder::kDecodePixels_Mode) == false) {
    336         printf("%s():%d:: Failed during jpeg decode\n",__FUNCTION__,__LINE__);
    337         return BAD_VALUE;
    338     }
    339 #else
    340     SkColorType prefConfig = kRGBA_8888_SkColorType;
    341     const void *buff = NULL;
    342     size_t size;
    343 
    344     buff = (const void *)mem->pointer();
    345     size= mem->size();
    346 
    347     switch(prefConfig) {
    348         case kRGBA_8888_SkColorType:
    349         {
    350             mfmtMultiplier = 4;
    351         }
    352         break;
    353 
    354         case kBGRA_8888_SkColorType:
    355         {
    356             mfmtMultiplier = 4;
    357         }
    358         break;
    359 
    360         case kARGB_4444_SkColorType:
    361         {
    362             mfmtMultiplier = 2;
    363         }
    364         break;
    365 
    366         case kRGB_565_SkColorType:
    367         {
    368             mfmtMultiplier = 2;
    369         }
    370         break;
    371 
    372         case kAlpha_8_SkColorType:
    373         {
    374             mfmtMultiplier = 4;
    375         }
    376         break;
    377 
    378         default:
    379         {
    380             mfmtMultiplier = 0;
    381             printf("Decode format is not correct!\n");
    382         }
    383         break;
    384     }
    385 
    386     if (SkImageDecoder::DecodeMemory(buff, size, skBM, prefConfig,
    387             SkImageDecoder::kDecodePixels_Mode) == false) {
    388         printf("%s():%d:: Failed during jpeg decode\n",__FUNCTION__,__LINE__);
    389         return BAD_VALUE;
    390     }
    391 
    392 #endif
    393     return NO_ERROR;
    394 }
    395 
    396 /*===========================================================================
    397  * FUNCTION   : encodeJPEG
    398  *
    399  * DESCRIPTION: encode the decoded input buffer.
    400  *
    401  * PARAMETERS :
    402  *   @stream  : SkWStream
    403  *   @bitmap  : SkBitmap decoded image to encode
    404  *   @path    : File path
    405  *
    406  * RETURN     : status_t type of status
    407  *              NO_ERROR  -- success
    408  *              none-zero failure code
    409 
    410  *==========================================================================*/
    411 status_t CameraContext::encodeJPEG(SkWStream * stream,
    412     const SkBitmap *bitmap, String8 path)
    413 {
    414     int qFactor = 100;
    415 
    416     if (!SkEncodeImage(stream, *bitmap, SkEncodedImageFormat::kJPEG, qFactor)) {
    417         ALOGE(" SkEncodeImage failed\n");
    418         return BAD_VALUE;
    419     }
    420 
    421     FILE *fh = fopen(path.string(), "r+");
    422     if ( !fh ) {
    423         printf("Could not open file %s\n", path.string());
    424         return BAD_VALUE;
    425     }
    426 
    427     fseek(fh, 0, SEEK_END);
    428     size_t len = (size_t)ftell(fh);
    429     rewind(fh);
    430 
    431     if( !len ) {
    432         printf("File %s is empty !\n", path.string());
    433         fclose(fh);
    434         return BAD_VALUE;
    435     }
    436 
    437     unsigned char *buff = (unsigned char*)malloc(len);
    438     if (!buff) {
    439         printf("Cannot allocate memory for buffer reading!\n");
    440         return BAD_VALUE;
    441     }
    442 
    443     size_t readSize = fread(buff, 1, len, fh);
    444     if (readSize != len) {
    445         printf("Reading error\n");
    446         return BAD_VALUE;
    447     }
    448 
    449     status_t ret = ReadSectionsFromBuffer(buff, len, READ_ALL);
    450     if (ret != NO_ERROR) {
    451         printf("Cannot read sections from buffer\n");
    452         DiscardData();
    453         DiscardSections();
    454         return BAD_VALUE;
    455     }
    456     free(buff);
    457     rewind(fh);
    458 
    459     unsigned char temp = 0xff;
    460     size_t writeSize = fwrite(&temp, sizeof(unsigned char), 1, fh);
    461     if (1 != writeSize) {
    462         printf("Writing error\n");
    463     }
    464     temp = 0xd8;
    465     fwrite(&temp, sizeof(unsigned char), 1, fh);
    466 
    467     for (size_t i = 0; i < mSectionsRead; i++) {
    468         switch((mSections[i].Type)) {
    469 
    470         case 0x123:
    471             fwrite(mSections[i].Data, sizeof(unsigned char),
    472                 mSections[i].Size, fh);
    473             break;
    474 
    475         case 0xe0:
    476             temp = 0xff;
    477             fwrite(&temp, sizeof(unsigned char), 1, fh);
    478             temp = 0xe1;
    479             fwrite(&temp, sizeof(unsigned char), 1, fh);
    480             fwrite(mJEXIFSection.Data, sizeof(unsigned char),
    481                 mJEXIFSection.Size, fh);
    482             break;
    483 
    484         default:
    485             temp = 0xff;
    486             fwrite(&temp, sizeof(unsigned char), 1, fh);
    487             fwrite(&mSections[i].Type, sizeof(unsigned char), 1, fh);
    488             fwrite(mSections[i].Data, sizeof(unsigned char),
    489                 mSections[i].Size, fh);
    490             break;
    491         }
    492     }
    493     fseek(fh, 0, SEEK_END);
    494     len = (size_t)ftell(fh);
    495     rewind(fh);
    496     printf("%s: buffer=%p, size=%zu stored at %s\n",
    497             __FUNCTION__, bitmap->getPixels(), len, path.string());
    498 
    499     free(mJEXIFSection.Data);
    500     DiscardData();
    501     DiscardSections();
    502     fclose(fh);
    503     ret = NO_ERROR;
    504 
    505     return ret;
    506 }
    507 
    508 /*===========================================================================
    509  * FUNCTION   : readSectionsFromBuffer
    510  *
    511  * DESCRIPTION: read all jpeg sections of input buffer.
    512  *
    513  * PARAMETERS :
    514  *   @mem : buffer to read from Metadata Sections
    515  *   @buffer_size: buffer size
    516  *   @ReadMode: Read mode - all, jpeg or exif
    517  *
    518  * RETURN     : status_t type of status
    519  *              NO_ERROR  -- success
    520  *              none-zero failure code
    521  *==========================================================================*/
    522 status_t CameraContext::ReadSectionsFromBuffer (unsigned char *buffer,
    523         size_t buffer_size, ReadMode_t ReadMode)
    524 {
    525     int a;
    526     size_t pos = 0;
    527     int HaveCom = 0;
    528     mSectionsAllocated = 10;
    529 
    530     mSections = (Sections_t *)malloc(sizeof(Sections_t) * mSectionsAllocated);
    531     if (!mSections) {
    532         printf(" not enough memory\n");
    533         return BAD_VALUE;
    534     }
    535 
    536     if (!buffer) {
    537         printf("Input buffer is null\n");
    538         return BAD_VALUE;
    539     }
    540 
    541     if (buffer_size < 1) {
    542         printf("Input size is 0\n");
    543         return BAD_VALUE;
    544     }
    545 
    546     a = (int) buffer[pos++];
    547 
    548     if (a != 0xff || buffer[pos++] != M_SOI){
    549         printf("No valid image\n");
    550         return BAD_VALUE;
    551     }
    552 
    553     for(;;){
    554         size_t itemlen;
    555         int marker = 0;
    556         size_t ll,lh;
    557         unsigned char * Data;
    558 
    559         CheckSectionsAllocated();
    560 
    561         // The call to CheckSectionsAllocated() may reallocate mSections
    562         // so need to check for NULL again.
    563         if (mSections == NULL) {
    564             printf(" not enough memory\n");
    565             return BAD_VALUE;
    566         }
    567 
    568         for (a = 0; a <= 16; a++){
    569             marker = buffer[pos++];
    570             if (marker != 0xff) break;
    571 
    572             if (a >= 16){
    573                 fprintf(stderr,"too many padding bytes\n");
    574                 return BAD_VALUE;
    575             }
    576         }
    577 
    578         mSections[mSectionsRead].Type = marker;
    579 
    580         // Read the length of the section.
    581         lh = buffer[pos++];
    582         ll = buffer[pos++];
    583 
    584         itemlen = (lh << 8) | ll;
    585 
    586         if (itemlen < 2) {
    587             ALOGE("invalid marker");
    588             return BAD_VALUE;
    589         }
    590 
    591         mSections[mSectionsRead].Size = itemlen;
    592 
    593         Data = (unsigned char *)malloc(itemlen);
    594         if (Data == NULL) {
    595             ALOGE("Could not allocate memory");
    596             return NO_MEMORY;
    597         }
    598         mSections[mSectionsRead].Data = Data;
    599 
    600         // Store first two pre-read bytes.
    601         Data[0] = (unsigned char)lh;
    602         Data[1] = (unsigned char)ll;
    603 
    604         if (pos+itemlen-2 > buffer_size) {
    605             ALOGE("Premature end of file?");
    606             return BAD_VALUE;
    607         }
    608 
    609         memcpy(Data+2, buffer+pos, itemlen-2); // Read the whole section.
    610         pos += itemlen-2;
    611 
    612         mSectionsRead += 1;
    613 
    614         switch(marker){
    615 
    616             case M_SOS:   // stop before hitting compressed data
    617                 // If reading entire image is requested, read the rest of the
    618                 // data.
    619                 if (ReadMode & READ_IMAGE){
    620                     size_t size;
    621                     // Determine how much file is left.
    622                     size = buffer_size - pos;
    623 
    624                     if (size < 1) {
    625                         ALOGE("could not read the rest of the image");
    626                         return BAD_VALUE;
    627                     }
    628                     Data = (unsigned char *)malloc(size);
    629                     if (Data == NULL) {
    630                         ALOGE("%d: could not allocate data for entire "
    631                                 "image size: %d", __LINE__, size);
    632                         return BAD_VALUE;
    633                     }
    634 
    635                     memcpy(Data, buffer+pos, size);
    636 
    637                     CheckSectionsAllocated();
    638 
    639                     // The call to CheckSectionsAllocated()
    640                     // may reallocate mSections
    641                     // so need to check for NULL again.
    642                     if (mSections == NULL) {
    643                         printf(" not enough memory\n");
    644                         return BAD_VALUE;
    645                     }
    646 
    647                     mSections[mSectionsRead].Data = Data;
    648                     mSections[mSectionsRead].Size = size;
    649                     mSections[mSectionsRead].Type = PSEUDO_IMAGE_MARKER;
    650                     mSectionsRead ++;
    651                     mHaveAll = 1;
    652                 }
    653                 return NO_ERROR;
    654 
    655             case M_EOI:   // in case it's a tables-only JPEG stream
    656                 ALOGE("No image in jpeg!\n");
    657                 return BAD_VALUE;
    658 
    659             case M_COM: // Comment section
    660                 if (HaveCom || ((ReadMode & READ_METADATA) == 0)){
    661                     // Discard this section.
    662                     free(mSections[--mSectionsRead].Data);
    663                 }
    664                 break;
    665 
    666             case M_JFIF:
    667                 // Regular jpegs always have this tag, exif images have the
    668                 // exif marker instead, althogh ACDsee will write images
    669                 // with both markers.
    670                 // this program will re-create this marker on absence of exif
    671                 // marker.
    672                 // hence no need to keep the copy from the file.
    673                 if (ReadMode & READ_METADATA){
    674                     if (memcmp(Data+2, "JFIF", 4) == 0) {
    675                         break;
    676                     }
    677                     free(mSections[--mSectionsRead].Data);
    678                 }
    679                 break;
    680 
    681             case M_EXIF:
    682                 // There can be different section using the same marker.
    683                 if (ReadMode & READ_METADATA){
    684                     if (memcmp(Data+2, "Exif", 4) == 0){
    685                         break;
    686                     }else if (memcmp(Data+2, "http:", 5) == 0){
    687                         // Change tag for internal purposes.
    688                         mSections[mSectionsRead-1].Type = M_XMP;
    689                         break;
    690                     }
    691                 }
    692                 // Oterwise, discard this section.
    693                 free(mSections[--mSectionsRead].Data);
    694                 break;
    695 
    696             case M_IPTC:
    697                 if (ReadMode & READ_METADATA){
    698                     // Note: We just store the IPTC section.
    699                     // Its relatively straightforward
    700                     // and we don't act on any part of it,
    701                     // so just display it at parse time.
    702                 }else{
    703                     free(mSections[--mSectionsRead].Data);
    704                 }
    705                 break;
    706 
    707             case M_SOF0:
    708             case M_SOF1:
    709             case M_SOF2:
    710             case M_SOF3:
    711             case M_SOF5:
    712             case M_SOF6:
    713             case M_SOF7:
    714             case M_SOF9:
    715             case M_SOF10:
    716             case M_SOF11:
    717             case M_SOF13:
    718             case M_SOF14:
    719             case M_SOF15:
    720                 break;
    721             default:
    722                 // Skip any other sections.
    723                 break;
    724         }
    725     }
    726     return NO_ERROR;
    727 }
    728 
    729 /*===========================================================================
    730  * FUNCTION   : CheckSectionsAllocated
    731  *
    732  * DESCRIPTION: Check allocated jpeg sections.
    733  *
    734  * PARAMETERS : none
    735  *
    736  * RETURN     : none
    737 
    738  *==========================================================================*/
    739 void CameraContext::CheckSectionsAllocated(void)
    740 {
    741     if (mSectionsRead > mSectionsAllocated){
    742         ALOGE("allocation screw up");
    743     }
    744     if (mSectionsRead >= mSectionsAllocated){
    745         mSectionsAllocated += mSectionsAllocated +1;
    746         mSections = (Sections_t *)realloc(mSections,
    747             sizeof(Sections_t) * mSectionsAllocated);
    748         if (mSections == NULL){
    749             ALOGE("could not allocate data for entire image");
    750         }
    751     }
    752 }
    753 
    754 /*===========================================================================
    755  * FUNCTION   : findSection
    756  *
    757  * DESCRIPTION: find the desired Section of the JPEG buffer.
    758  *
    759  * PARAMETERS :
    760  *  @SectionType: Section type
    761  *
    762  * RETURN     : return the found section
    763 
    764  *==========================================================================*/
    765 CameraContext::Sections_t *CameraContext::FindSection(int SectionType)
    766 {
    767     for (unsigned int a = 0; a < mSectionsRead; a++) {
    768         if (mSections[a].Type == SectionType){
    769             return &mSections[a];
    770         }
    771     }
    772     // Could not be found.
    773     return NULL;
    774 }
    775 
    776 
    777 /*===========================================================================
    778  * FUNCTION   : DiscardData
    779  *
    780  * DESCRIPTION: DiscardData
    781  *
    782  * PARAMETERS : none
    783  *
    784  * RETURN     : none
    785 
    786  *==========================================================================*/
    787 void CameraContext::DiscardData()
    788 {
    789     for (unsigned int a = 0; a < mSectionsRead; a++) {
    790         free(mSections[a].Data);
    791     }
    792 
    793     mSectionsRead = 0;
    794     mHaveAll = 0;
    795 }
    796 
    797 /*===========================================================================
    798  * FUNCTION   : DiscardSections
    799  *
    800  * DESCRIPTION: Discard allocated sections
    801  *
    802  * PARAMETERS : none
    803  *
    804  * RETURN     : none
    805 
    806  *==========================================================================*/
    807 void CameraContext::DiscardSections()
    808 {
    809     free(mSections);
    810     mSectionsAllocated = 0;
    811     mHaveAll = 0;
    812 }
    813 
    814 /*===========================================================================
    815  * FUNCTION   : notify
    816  *
    817  * DESCRIPTION: notify callback
    818  *
    819  * PARAMETERS :
    820  *   @msgType : type of callback
    821  *   @ext1: extended parameters
    822  *   @ext2: extended parameters
    823  *
    824  * RETURN     : None
    825  *==========================================================================*/
    826 void CameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2)
    827 {
    828     printf("Notify cb: %d %d %d\n", msgType, ext1, ext2);
    829 
    830     if (( msgType & CAMERA_MSG_PREVIEW_FRAME)
    831 #ifndef VANILLA_HAL
    832             && (ext1 == CAMERA_FRAME_DATA_FD)
    833 #endif
    834        )
    835     {
    836         int fd = dup(ext2);
    837         printf("notify Preview Frame fd: %d dup fd: %d\n", ext2, fd);
    838         close(fd);
    839     }
    840 
    841     if ( msgType & CAMERA_MSG_FOCUS ) {
    842         printf("AutoFocus %s \n",
    843                (ext1) ? "OK" : "FAIL");
    844     }
    845 
    846     if ( msgType & CAMERA_MSG_SHUTTER ) {
    847         printf("Shutter done \n");
    848     }
    849 
    850     if ( msgType & CAMERA_MSG_ERROR) {
    851         printf("Camera Test CAMERA_MSG_ERROR\n");
    852         stopPreview();
    853         closeCamera();
    854     }
    855 }
    856 
    857 /*===========================================================================
    858  * FUNCTION   : postData
    859  *
    860  * DESCRIPTION: handles data callbacks
    861  *
    862  * PARAMETERS :
    863  *   @msgType : type of callback
    864  *   @dataPtr: buffer data
    865  *   @metadata: additional metadata where available
    866  *
    867  * RETURN     : None
    868  *==========================================================================*/
    869 void CameraContext::postData(int32_t msgType,
    870                              const sp<IMemory>& dataPtr,
    871                              camera_frame_metadata_t *metadata)
    872 {
    873     mInterpr->PiPLock();
    874     Size currentPictureSize = mSupportedPictureSizes.itemAt(
    875         mCurrentPictureSizeIdx);
    876     unsigned char *buff = NULL;
    877     size_t size;
    878     status_t ret = 0;
    879 
    880     memset(&mJEXIFSection, 0, sizeof(mJEXIFSection)),
    881 
    882     printf("Data cb: %d\n", msgType);
    883 
    884     if ( msgType & CAMERA_MSG_PREVIEW_FRAME ) {
    885         previewCallback(dataPtr);
    886     }
    887 
    888     if ( msgType & CAMERA_MSG_RAW_IMAGE ) {
    889         printf("RAW done \n");
    890     }
    891 
    892     if (msgType & CAMERA_MSG_POSTVIEW_FRAME) {
    893         printf("Postview frame \n");
    894     }
    895 
    896     if (msgType & CAMERA_MSG_COMPRESSED_IMAGE ) {
    897         String8 jpegPath;
    898         jpegPath = jpegPath.format(QCAMERA_DUMP_FRM_LOCATION"img_%d.jpg",
    899                 JpegIdx);
    900         if (!mPiPCapture) {
    901             // Normal capture case
    902             printf("JPEG done\n");
    903             saveFile(dataPtr, jpegPath);
    904             JpegIdx++;
    905         } else {
    906             // PiP capture case
    907             SkFILEWStream *wStream;
    908             ret = decodeJPEG(dataPtr, &skBMtmp);
    909             if (NO_ERROR != ret) {
    910                 printf("Error in decoding JPEG!\n");
    911                 mInterpr->PiPUnlock();
    912                 return;
    913             }
    914 
    915             mWidthTmp = currentPictureSize.width;
    916             mHeightTmp = currentPictureSize.height;
    917             PiPPtrTmp = dataPtr;
    918             // If there are two jpeg buffers
    919             if (mPiPIdx == 1) {
    920                 printf("PiP done\n");
    921 
    922                 // Find the the capture with higher width and height and read
    923                 // its jpeg sections
    924                 if ((mInterpr->camera[0]->mWidthTmp * mInterpr->camera[0]->mHeightTmp) >
    925                         (mInterpr->camera[1]->mWidthTmp * mInterpr->camera[1]->mHeightTmp)) {
    926                     buff = (unsigned char *)PiPPtrTmp->pointer();
    927                     size= PiPPtrTmp->size();
    928                 } else if ((mInterpr->camera[0]->mWidthTmp * mInterpr->camera[0]->mHeightTmp) <
    929                         (mInterpr->camera[1]->mWidthTmp * mInterpr->camera[1]->mHeightTmp)) {
    930                     buff = (unsigned char *)PiPPtrTmp->pointer();
    931                     size= PiPPtrTmp->size();
    932                 } else {
    933                     printf("Cannot take PiP. Images are with the same width"
    934                             " and height size!!!\n");
    935                     mInterpr->PiPUnlock();
    936                     return;
    937                 }
    938 
    939                 if (buff != NULL && size != 0) {
    940                     ret = ReadSectionsFromBuffer(buff, size, READ_ALL);
    941                     if (ret != NO_ERROR) {
    942                         printf("Cannot read sections from buffer\n");
    943                         DiscardData();
    944                         DiscardSections();
    945                         mInterpr->PiPUnlock();
    946                         return;
    947                     }
    948 
    949                     mJEXIFTmp = FindSection(M_EXIF);
    950                     if (!mJEXIFTmp) {
    951                         ALOGE("skBMDec is null\n");
    952                         DiscardData();
    953                         DiscardSections();
    954                         return;
    955                     }
    956                     mJEXIFSection = *mJEXIFTmp;
    957                     mJEXIFSection.Data = (unsigned char*)malloc(mJEXIFTmp->Size);
    958                     if (!mJEXIFSection.Data) {
    959                         ALOGE(" Not enough memory\n");
    960                         DiscardData();
    961                         DiscardSections();
    962                         return;
    963                     }
    964                     memcpy(mJEXIFSection.Data,
    965                         mJEXIFTmp->Data, mJEXIFTmp->Size);
    966                     DiscardData();
    967                     DiscardSections();
    968 
    969                     wStream = new SkFILEWStream(jpegPath.string());
    970                     skBMDec = PiPCopyToOneFile(&mInterpr->camera[0]->skBMtmp,
    971                             &mInterpr->camera[1]->skBMtmp);
    972                     if (!skBMDec) {
    973                         ALOGE("skBMDec is null\n");
    974                         delete wStream;
    975                         return;
    976                     }
    977 
    978                     if (encodeJPEG(wStream, skBMDec, jpegPath) != false) {
    979                         printf("%s():%d:: Failed during jpeg encode\n",
    980                                 __FUNCTION__,__LINE__);
    981                         mInterpr->PiPUnlock();
    982                         return;
    983                     }
    984                     mPiPIdx = 0;
    985                     JpegIdx++;
    986                     delete wStream;
    987                 }
    988             } else {
    989                 mPiPIdx++;
    990             }
    991             disablePiPCapture();
    992         }
    993     }
    994 
    995     if ((msgType & CAMERA_MSG_PREVIEW_METADATA) && (NULL != metadata)) {
    996         printf("Face detected %d \n", metadata->number_of_faces);
    997     }
    998     mInterpr->PiPUnlock();
    999 
   1000 }
   1001 
   1002 /*===========================================================================
   1003  * FUNCTION   : postDataTimestamp
   1004  *
   1005  * DESCRIPTION: handles recording callbacks
   1006  *
   1007  * PARAMETERS :
   1008  *   @timestamp : timestamp of buffer
   1009  *   @msgType : type of buffer
   1010  *   @dataPtr : buffer data
   1011  *
   1012  * RETURN     : None
   1013  *==========================================================================*/
   1014 void CameraContext::postDataTimestamp(nsecs_t timestamp,
   1015                                       int32_t msgType,
   1016                                       const sp<IMemory>& dataPtr)
   1017 {
   1018     printf("Recording cb: %d %lld %p\n",
   1019             msgType, (long long int)timestamp, dataPtr.get());
   1020 }
   1021 
   1022 /*===========================================================================
   1023  * FUNCTION   : dataCallbackTimestamp
   1024  *
   1025  * DESCRIPTION: handles recording callbacks. Used for ViV recording
   1026  *
   1027  * PARAMETERS :
   1028  *   @timestamp : timestamp of buffer
   1029  *   @msgType : type of buffer
   1030  *   @dataPtr : buffer data
   1031  *
   1032  * RETURN     : None
   1033  *==========================================================================*/
   1034 void CameraContext::dataCallbackTimestamp(nsecs_t timestamp,
   1035         int32_t msgType,
   1036         const sp<IMemory>& dataPtr)
   1037 {
   1038     mInterpr->ViVLock();
   1039     // Not needed check. Just avoiding warnings of not used variables.
   1040     if (timestamp > 0)
   1041         timestamp = 0;
   1042     // Not needed check. Just avoiding warnings of not used variables.
   1043     if (msgType > 0)
   1044         msgType = 0;
   1045     size_t i = 0;
   1046     void * srcBuff = NULL;
   1047     void * dstBuff = NULL;
   1048 
   1049     size_t srcYStride = 0, dstYStride = 0;
   1050     size_t srcUVStride = 0, dstUVStride = 0;
   1051     size_t srcYScanLines = 0, dstYScanLines = 0;
   1052     size_t srcUVScanLines = 0, dstUVScanLines = 0;
   1053     size_t srcOffset = 0, dstOffset = 0;
   1054     size_t srcBaseOffset = 0;
   1055     size_t dstBaseOffset = 0;
   1056     Size currentVideoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
   1057     status_t err = NO_ERROR;
   1058     ANativeWindowBuffer* anb = NULL;
   1059 
   1060     dstBuff = (void *) dataPtr->pointer();
   1061     if (NULL == dstBuff) {
   1062         printf("Cannot access destination buffer!!!\n");
   1063         mInterpr->ViVUnlock();
   1064         return;
   1065     }
   1066 
   1067     if (mCameraIndex == mInterpr->mViVVid.sourceCameraID) {
   1068         srcYStride = calcStride(currentVideoSize.width);
   1069         srcUVStride = calcStride(currentVideoSize.width);
   1070         srcYScanLines = calcYScanLines(currentVideoSize.height);
   1071         srcUVScanLines = calcUVScanLines(currentVideoSize.height);
   1072         mInterpr->mViVBuff.srcWidth = (size_t)currentVideoSize.width;
   1073         mInterpr->mViVBuff.srcHeight = (size_t)currentVideoSize.height;
   1074 
   1075 
   1076         mInterpr->mViVBuff.YStride = srcYStride;
   1077         mInterpr->mViVBuff.UVStride = srcUVStride;
   1078         mInterpr->mViVBuff.YScanLines = srcYScanLines;
   1079         mInterpr->mViVBuff.UVScanLines = srcUVScanLines;
   1080 
   1081         memcpy( mInterpr->mViVBuff.buff, dstBuff,
   1082             mInterpr->mViVBuff.buffSize);
   1083 
   1084         mInterpr->mViVVid.isBuffValid = true;
   1085     } else if (mCameraIndex == mInterpr->mViVVid.destinationCameraID) {
   1086         if(mInterpr->mViVVid.isBuffValid == true) {
   1087             dstYStride = calcStride(currentVideoSize.width);
   1088             dstUVStride = calcStride(currentVideoSize.width);
   1089             dstYScanLines = calcYScanLines(currentVideoSize.height);
   1090             dstUVScanLines = calcUVScanLines(currentVideoSize.height);
   1091 
   1092             srcYStride = mInterpr->mViVBuff.YStride;
   1093             srcUVStride = mInterpr->mViVBuff.UVStride;
   1094             srcYScanLines = mInterpr->mViVBuff.YScanLines;
   1095             srcUVScanLines = mInterpr->mViVBuff.UVScanLines;
   1096 
   1097 
   1098             for (i = 0; i < mInterpr->mViVBuff.srcHeight; i++) {
   1099                 srcOffset = i*srcYStride;
   1100                 dstOffset = i*dstYStride;
   1101                 memcpy((unsigned char *) dstBuff + dstOffset,
   1102                     (unsigned char *) mInterpr->mViVBuff.buff +
   1103                     srcOffset, mInterpr->mViVBuff.srcWidth);
   1104             }
   1105             srcBaseOffset = srcYStride * srcYScanLines;
   1106             dstBaseOffset = dstYStride * dstYScanLines;
   1107             for (i = 0; i < mInterpr->mViVBuff.srcHeight / 2; i++) {
   1108                 srcOffset = i*srcUVStride + srcBaseOffset;
   1109                 dstOffset = i*dstUVStride + dstBaseOffset;
   1110                 memcpy((unsigned char *) dstBuff + dstOffset,
   1111                     (unsigned char *) mInterpr->mViVBuff.buff +
   1112                     srcOffset, mInterpr->mViVBuff.srcWidth);
   1113             }
   1114 
   1115             err = native_window_dequeue_buffer_and_wait(
   1116                 mInterpr->mViVVid.ANW.get(),&anb);
   1117             if (err != NO_ERROR) {
   1118                 printf("Cannot dequeue anb for sensor %d!!!\n", mCameraIndex);
   1119                 mInterpr->ViVUnlock();
   1120                 return;
   1121             }
   1122             mInterpr->mViVVid.graphBuf = new GraphicBuffer(anb, false);
   1123             if(NULL == mInterpr->mViVVid.graphBuf.get()) {
   1124                 printf("Invalid Graphic buffer\n");
   1125                 mInterpr->ViVUnlock();
   1126                 return;
   1127             }
   1128             err = mInterpr->mViVVid.graphBuf->lock(
   1129                 GRALLOC_USAGE_SW_WRITE_OFTEN,
   1130                 (void**)(&mInterpr->mViVVid.mappedBuff));
   1131             if (err != NO_ERROR) {
   1132                 printf("Graphic buffer could not be locked %d!!!\n", err);
   1133                 mInterpr->ViVUnlock();
   1134                 return;
   1135             }
   1136 
   1137             srcYStride = dstYStride;
   1138             srcUVStride = dstUVStride;
   1139             srcYScanLines = dstYScanLines;
   1140             srcUVScanLines = dstUVScanLines;
   1141             srcBuff = dstBuff;
   1142 
   1143             for (i = 0; i < (size_t)currentVideoSize.height; i++) {
   1144                 srcOffset = i*srcYStride;
   1145                 dstOffset = i*dstYStride;
   1146                 memcpy((unsigned char *) mInterpr->mViVVid.mappedBuff +
   1147                     dstOffset, (unsigned char *) srcBuff +
   1148                     srcOffset, (size_t)currentVideoSize.width);
   1149             }
   1150 
   1151             srcBaseOffset = srcYStride * srcYScanLines;
   1152             dstBaseOffset = dstUVStride * (size_t)currentVideoSize.height;
   1153 
   1154             for (i = 0; i < (size_t)currentVideoSize.height / 2; i++) {
   1155                 srcOffset = i*srcUVStride + srcBaseOffset;
   1156                 dstOffset = i*dstUVStride + dstBaseOffset;
   1157                 memcpy((unsigned char *) mInterpr->mViVVid.mappedBuff +
   1158                     dstOffset, (unsigned char *) srcBuff +
   1159                     srcOffset, (size_t)currentVideoSize.width);
   1160             }
   1161 
   1162 
   1163             mInterpr->mViVVid.graphBuf->unlock();
   1164 
   1165             err = mInterpr->mViVVid.ANW->queueBuffer(
   1166                 mInterpr->mViVVid.ANW.get(), anb, -1);
   1167             if(err)
   1168                 printf("Failed to enqueue buffer to recorder!!!\n");
   1169         }
   1170     }
   1171     mCamera->releaseRecordingFrame(dataPtr);
   1172 
   1173     mInterpr->ViVUnlock();
   1174 }
   1175 
   1176 /*===========================================================================
   1177  * FUNCTION   : ViVEncoderThread
   1178  *
   1179  * DESCRIPTION: Creates a separate thread for ViV recording
   1180  *
   1181  * PARAMETERS : None
   1182  *
   1183  * RETURN     : None
   1184  *==========================================================================*/
   1185 status_t Interpreter::ViVEncoderThread()
   1186 {
   1187     int ret = NO_ERROR;
   1188     pthread_attr_t attr;
   1189     pthread_attr_init(&attr);
   1190 
   1191     ret = pthread_create(&mViVEncThread, &attr, ThreadWrapper, this);
   1192     ret = pthread_attr_destroy(&attr);
   1193 
   1194     return ret;
   1195 }
   1196 
   1197 /*===========================================================================
   1198  * FUNCTION   : ThreadWrapper
   1199  *
   1200  * DESCRIPTION: Helper function for for ViV recording thread
   1201  *
   1202  * PARAMETERS : Interpreter context
   1203  *
   1204  * RETURN     : None
   1205  *==========================================================================*/
   1206 void *Interpreter::ThreadWrapper(void *context) {
   1207     Interpreter *writer = static_cast<Interpreter *>(context);
   1208     writer->ViVEncode();
   1209     return NULL;
   1210 }
   1211 
   1212 /*===========================================================================
   1213  * FUNCTION   : ViVEncode
   1214  *
   1215  * DESCRIPTION: Thread for ViV encode. Buffers from video codec are sent to
   1216  *              muxer and saved in a file.
   1217  *
   1218  * PARAMETERS : Interpreter context
   1219  *
   1220  * RETURN     : None
   1221  *==========================================================================*/
   1222 void Interpreter::ViVEncode()
   1223 {
   1224     status_t err = NO_ERROR;
   1225     ssize_t trackIdx = -1;
   1226     uint32_t debugNumFrames = 0;
   1227 
   1228     size_t bufIndex, offset, size;
   1229     int64_t ptsUsec;
   1230     uint32_t flags;
   1231     bool DoRecording = true;
   1232 
   1233 
   1234     err = mTestContext->mViVVid.codec->getOutputBuffers(
   1235         &mTestContext->mViVVid.buffers);
   1236     if (err != NO_ERROR) {
   1237         printf("Unable to get output buffers (err=%d)\n", err);
   1238     }
   1239 
   1240     while (DoRecording) {
   1241         err = mTestContext->mViVVid.codec->dequeueOutputBuffer(
   1242             &bufIndex,
   1243             &offset,
   1244             &size,
   1245             &ptsUsec,
   1246             &flags, -1);
   1247 
   1248         switch (err) {
   1249 
   1250         case NO_ERROR:
   1251             // got a buffer
   1252             if ((flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) != 0) {
   1253                 // ignore this -- we passed the CSD into MediaMuxer when
   1254                 // we got the format change notification
   1255                 size = 0;
   1256             }
   1257             if (size != 0) {
   1258                 // If the virtual display isn't providing us with timestamps,
   1259                 // use the current time.
   1260                 if (ptsUsec == 0) {
   1261                     ptsUsec = systemTime(SYSTEM_TIME_MONOTONIC) / 1000;
   1262                 }
   1263 
   1264                 // The MediaMuxer docs are unclear, but it appears that we
   1265                 // need to pass either the full set of BufferInfo flags, or
   1266                 // (flags & BUFFER_FLAG_SYNCFRAME).
   1267                 err = mTestContext->mViVVid.muxer->writeSampleData(
   1268                     mTestContext->mViVVid.buffers[bufIndex],
   1269                     (size_t)trackIdx,
   1270                     ptsUsec,
   1271                     flags);
   1272                 if (err != NO_ERROR) {
   1273                     fprintf(stderr, "Failed writing data to muxer (err=%d)\n",
   1274                             err);
   1275                 }
   1276                 debugNumFrames++;
   1277             }
   1278             err = mTestContext->mViVVid.codec->releaseOutputBuffer(bufIndex);
   1279             if (err != NO_ERROR) {
   1280                 fprintf(stderr, "Unable to release output buffer (err=%d)\n",
   1281                         err);
   1282             }
   1283             if ((flags & MediaCodec::BUFFER_FLAG_EOS) != 0) {
   1284                 // Not expecting EOS from SurfaceFlinger.  Go with it.
   1285                 printf("Received end-of-stream\n");
   1286                 //DoRecording = false;
   1287             }
   1288             break;
   1289         case -EAGAIN:                       // INFO_TRY_AGAIN_LATER
   1290             ALOGV("Got -EAGAIN, looping");
   1291             break;
   1292         case INFO_FORMAT_CHANGED:           // INFO_OUTPUT_FORMAT_CHANGED
   1293         {
   1294             // format includes CSD, which we must provide to muxer
   1295             sp<AMessage> newFormat;
   1296             mTestContext->mViVVid.codec->getOutputFormat(&newFormat);
   1297             trackIdx = mTestContext->mViVVid.muxer->addTrack(newFormat);
   1298             err = mTestContext->mViVVid.muxer->start();
   1299             if (err != NO_ERROR) {
   1300                 printf("Unable to start muxer (err=%d)\n", err);
   1301             }
   1302         }
   1303         break;
   1304         case INFO_OUTPUT_BUFFERS_CHANGED:   // INFO_OUTPUT_BUFFERS_CHANGED
   1305             // not expected for an encoder; handle it anyway
   1306             ALOGV("Encoder buffers changed");
   1307             err = mTestContext->mViVVid.codec->getOutputBuffers(
   1308                 &mTestContext->mViVVid.buffers);
   1309             if (err != NO_ERROR) {
   1310                 printf("Unable to get new output buffers (err=%d)\n", err);
   1311             }
   1312         break;
   1313         case INVALID_OPERATION:
   1314             DoRecording = false;
   1315         break;
   1316         default:
   1317             printf("Got weird result %d from dequeueOutputBuffer\n", err);
   1318         break;
   1319         }
   1320     }
   1321 
   1322     return;
   1323 }
   1324 
   1325 /*===========================================================================
   1326  * FUNCTION   : calcBufferSize
   1327  *
   1328  * DESCRIPTION: Temp buffer size calculation. Temp buffer is used to store
   1329  *              the buffer from the camera with smaller resolution. It is
   1330  *              copied to the buffer from camera with higher resolution.
   1331  *
   1332  * PARAMETERS :
   1333  *   @width   : video size width
   1334  *   @height  : video size height
   1335  *
   1336  * RETURN     : size_t
   1337  *==========================================================================*/
   1338 size_t CameraContext::calcBufferSize(int width, int height)
   1339 {
   1340     size_t size = 0;
   1341     size_t UVAlignment;
   1342     size_t YPlane, UVPlane, YStride, UVStride, YScanlines, UVScanlines;
   1343     if (!width || !height) {
   1344         return size;
   1345     }
   1346     UVAlignment = 4096;
   1347     YStride = calcStride(width);
   1348     UVStride = calcStride(width);
   1349     YScanlines = calcYScanLines(height);
   1350     UVScanlines = calcUVScanLines(height);
   1351     YPlane = YStride * YScanlines;
   1352     UVPlane = UVStride * UVScanlines + UVAlignment;
   1353     size = YPlane + UVPlane;
   1354     size = VIDEO_BUF_ALLIGN(size, 4096);
   1355 
   1356     return size;
   1357 }
   1358 
   1359 /*===========================================================================
   1360  * FUNCTION   : calcStride
   1361  *
   1362  * DESCRIPTION: Temp buffer stride calculation.
   1363  *
   1364  * PARAMETERS :
   1365  *   @width   : video size width
   1366  *
   1367  * RETURN     : size_t
   1368  *==========================================================================*/
   1369 size_t CameraContext::calcStride(int width)
   1370 {
   1371     size_t alignment, stride = 0;
   1372     if (!width) {
   1373         return stride;
   1374     }
   1375     alignment = 128;
   1376     stride = VIDEO_BUF_ALLIGN((size_t)width, alignment);
   1377 
   1378     return stride;
   1379 }
   1380 
   1381 /*===========================================================================
   1382  * FUNCTION   : calcYScanLines
   1383  *
   1384  * DESCRIPTION: Temp buffer scanlines calculation for Y plane.
   1385  *
   1386  * PARAMETERS :
   1387  *   @width   : video size height
   1388  *
   1389  * RETURN     : size_t
   1390  *==========================================================================*/
   1391 size_t CameraContext::calcYScanLines(int height)
   1392 {
   1393     size_t alignment, scanlines = 0;
   1394         if (!height) {
   1395             return scanlines;
   1396         }
   1397     alignment = 32;
   1398     scanlines = VIDEO_BUF_ALLIGN((size_t)height, alignment);
   1399 
   1400     return scanlines;
   1401 }
   1402 
   1403 /*===========================================================================
   1404  * FUNCTION   : calcUVScanLines
   1405  *
   1406  * DESCRIPTION: Temp buffer scanlines calculation for UV plane.
   1407  *
   1408  * PARAMETERS :
   1409  *   @width   : video size height
   1410  *
   1411  * RETURN     : size_t
   1412  *==========================================================================*/
   1413 size_t CameraContext::calcUVScanLines(int height)
   1414 {
   1415     size_t alignment, scanlines = 0;
   1416     if (!height) {
   1417         return scanlines;
   1418     }
   1419     alignment = 16;
   1420     scanlines = VIDEO_BUF_ALLIGN((size_t)((height + 1) >> 1), alignment);
   1421 
   1422     return scanlines;
   1423 }
   1424 
   1425 /*===========================================================================
   1426  * FUNCTION   : printSupportedParams
   1427  *
   1428  * DESCRIPTION: dump common supported parameters
   1429  *
   1430  * PARAMETERS : None
   1431  *
   1432  * RETURN     : None
   1433  *==========================================================================*/
   1434 void CameraContext::printSupportedParams()
   1435 {
   1436     const char *camera_ids = mParams.get("camera-indexes");
   1437     const char *pic_sizes = mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES);
   1438     const char *pic_formats = mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS);
   1439     const char *preview_sizes = mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
   1440     const char *video_sizes = mParams.get(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES);
   1441     const char *preview_formats = mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
   1442     const char *frame_rates = mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
   1443     const char *thumb_sizes = mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES);
   1444     const char *wb_modes = mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
   1445     const char *effects = mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS);
   1446     const char *scene_modes = mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES);
   1447     const char *focus_modes = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
   1448     const char *antibanding_modes = mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING);
   1449     const char *flash_modes = mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
   1450     int focus_areas = mParams.getInt(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS);
   1451     const char *fps_ranges = mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE);
   1452     const char *focus_distances = mParams.get(CameraParameters::KEY_FOCUS_DISTANCES);
   1453 
   1454     printf("\n\r\tSupported Cameras: %s",
   1455            (camera_ids != NULL)? camera_ids : "NULL");
   1456     printf("\n\r\tSupported Picture Sizes: %s",
   1457            (pic_sizes != NULL)? pic_sizes : "NULL");
   1458     printf("\n\r\tSupported Picture Formats: %s",
   1459            (pic_formats != NULL)? pic_formats : "NULL");
   1460     printf("\n\r\tSupported Preview Sizes: %s",
   1461            (preview_sizes != NULL)? preview_sizes : "NULL");
   1462     printf("\n\r\tSupported Video Sizes: %s",
   1463             (video_sizes != NULL)? video_sizes : "NULL");
   1464     printf("\n\r\tSupported Preview Formats: %s",
   1465            (preview_formats != NULL)? preview_formats : "NULL");
   1466     printf("\n\r\tSupported Preview Frame Rates: %s",
   1467            (frame_rates != NULL)? frame_rates : "NULL");
   1468     printf("\n\r\tSupported Thumbnail Sizes: %s",
   1469            (thumb_sizes != NULL)? thumb_sizes : "NULL");
   1470     printf("\n\r\tSupported Whitebalance Modes: %s",
   1471            (wb_modes != NULL)? wb_modes : "NULL");
   1472     printf("\n\r\tSupported Effects: %s",
   1473            (effects != NULL)? effects : "NULL");
   1474     printf("\n\r\tSupported Scene Modes: %s",
   1475            (scene_modes != NULL)? scene_modes : "NULL");
   1476     printf("\n\r\tSupported Focus Modes: %s",
   1477            (focus_modes != NULL)? focus_modes : "NULL");
   1478     printf("\n\r\tSupported Antibanding Options: %s",
   1479            (antibanding_modes != NULL)? antibanding_modes : "NULL");
   1480     printf("\n\r\tSupported Flash Modes: %s",
   1481            (flash_modes != NULL)? flash_modes : "NULL");
   1482     printf("\n\r\tSupported Focus Areas: %d", focus_areas);
   1483     printf("\n\r\tSupported FPS ranges : %s",
   1484            (fps_ranges != NULL)? fps_ranges : "NULL");
   1485     printf("\n\r\tFocus Distances: %s \n",
   1486            (focus_distances != NULL)? focus_distances : "NULL");
   1487 }
   1488 
   1489 /*===========================================================================
   1490  * FUNCTION   : createPreviewSurface
   1491  *
   1492  * DESCRIPTION: helper function for creating preview surfaces
   1493  *
   1494  * PARAMETERS :
   1495  *   @width : preview width
   1496  *   @height: preview height
   1497  *   @pixFormat : surface pixelformat
   1498  *
   1499  * RETURN     : status_t type of status
   1500  *              NO_ERROR  -- success
   1501  *              none-zero failure code
   1502  *==========================================================================*/
   1503 status_t CameraContext::createPreviewSurface(int width, int height, int32_t pixFormat)
   1504 {
   1505     int ret = NO_ERROR;
   1506     DisplayInfo dinfo;
   1507     sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
   1508                         ISurfaceComposer::eDisplayIdMain));
   1509     SurfaceComposerClient::getDisplayInfo(display, &dinfo);
   1510     uint32_t previewWidth, previewHeight;
   1511 
   1512     if ((0 >= width) || (0 >= height)) {
   1513         printf("Bad preview surface size %dx%d\n", width, height);
   1514         return BAD_VALUE;
   1515     }
   1516 
   1517     if ((int)dinfo.w < width) {
   1518         previewWidth = dinfo.w;
   1519     } else {
   1520         previewWidth = (unsigned int)width;
   1521     }
   1522 
   1523     if ((int)dinfo.h < height) {
   1524         previewHeight = dinfo.h;
   1525     } else {
   1526         previewHeight = (unsigned int)height;
   1527     }
   1528 
   1529     mClient = new SurfaceComposerClient();
   1530 
   1531     if ( NULL == mClient.get() ) {
   1532         printf("Unable to establish connection to Surface Composer \n");
   1533         return NO_INIT;
   1534     }
   1535 
   1536     mSurfaceControl = mClient->createSurface(String8("QCamera_Test"),
   1537                                              previewWidth,
   1538                                              previewHeight,
   1539                                              pixFormat,
   1540                                              0);
   1541     if ( NULL == mSurfaceControl.get() ) {
   1542         printf("Unable to create preview surface \n");
   1543         return NO_INIT;
   1544     }
   1545 
   1546     mPreviewSurface = mSurfaceControl->getSurface();
   1547     if ( NULL != mPreviewSurface.get() ) {
   1548         mClient->openGlobalTransaction();
   1549         ret |= mSurfaceControl->setLayer(0x7fffffff);
   1550         if ( mCameraIndex == 0 )
   1551             ret |= mSurfaceControl->setPosition(0, 0);
   1552         else
   1553             ret |= mSurfaceControl->setPosition((float)(dinfo.w - previewWidth),
   1554                     (float)(dinfo.h - previewHeight));
   1555 
   1556         ret |= mSurfaceControl->setSize(previewWidth, previewHeight);
   1557         ret |= mSurfaceControl->show();
   1558         mClient->closeGlobalTransaction();
   1559 
   1560         if ( NO_ERROR != ret ) {
   1561             printf("Preview surface configuration failed! \n");
   1562         }
   1563     } else {
   1564         ret = NO_INIT;
   1565     }
   1566 
   1567     return ret;
   1568 }
   1569 
   1570 /*===========================================================================
   1571  * FUNCTION   : destroyPreviewSurface
   1572  *
   1573  * DESCRIPTION: closes previously open preview surface
   1574  *
   1575  * PARAMETERS : None
   1576  *
   1577  * RETURN     : status_t type of status
   1578  *              NO_ERROR  -- success
   1579  *              none-zero failure code
   1580  *==========================================================================*/
   1581 status_t CameraContext::destroyPreviewSurface()
   1582 {
   1583     if ( NULL != mPreviewSurface.get() ) {
   1584         mPreviewSurface.clear();
   1585     }
   1586 
   1587     if ( NULL != mSurfaceControl.get() ) {
   1588         mSurfaceControl->clear();
   1589         mSurfaceControl.clear();
   1590     }
   1591 
   1592     if ( NULL != mClient.get() ) {
   1593         mClient->dispose();
   1594         mClient.clear();
   1595     }
   1596 
   1597     return NO_ERROR;
   1598 }
   1599 
   1600 /*===========================================================================
   1601  * FUNCTION   : CameraContext
   1602  *
   1603  * DESCRIPTION: camera context constructor
   1604  *
   1605  * PARAMETERS : None
   1606  *
   1607  * RETURN     : None
   1608  *==========================================================================*/
   1609 CameraContext::CameraContext(int cameraIndex) :
   1610     mCameraIndex(cameraIndex),
   1611     mResizePreview(true),
   1612     mHardwareActive(false),
   1613     mPreviewRunning(false),
   1614     mRecordRunning(false),
   1615     mVideoFd(-1),
   1616     mVideoIdx(0),
   1617     mRecordingHint(false),
   1618     mDoPrintMenu(true),
   1619     mPiPCapture(false),
   1620     mfmtMultiplier(1),
   1621     mSectionsRead(false),
   1622     mSectionsAllocated(0),
   1623     mSections(NULL),
   1624     mJEXIFTmp(NULL),
   1625     mHaveAll(false),
   1626     mCamera(NULL),
   1627     mClient(NULL),
   1628     mSurfaceControl(NULL),
   1629     mPreviewSurface(NULL),
   1630     mInUse(false)
   1631 {
   1632     mRecorder = new MediaRecorder(String16("camera"));
   1633 }
   1634 
   1635 /*===========================================================================
   1636  * FUNCTION     : setTestCtxInstance
   1637  *
   1638  * DESCRIPTION  : Sends TestContext instance to CameraContext
   1639  *
   1640  * PARAMETERS   :
   1641  *    @instance : TestContext instance
   1642  *
   1643  * RETURN     : None
   1644  *==========================================================================*/
   1645 void CameraContext::setTestCtxInstance(TestContext  *instance)
   1646 {
   1647     mInterpr = instance;
   1648 }
   1649 
   1650 /*===========================================================================
   1651  * FUNCTION     : setTestCtxInst
   1652  *
   1653  * DESCRIPTION  : Sends TestContext instance to Interpreter
   1654  *
   1655  * PARAMETERS   :
   1656  *    @instance : TestContext instance
   1657  *
   1658  * RETURN     : None
   1659  *==========================================================================*/
   1660 void Interpreter::setTestCtxInst(TestContext  *instance)
   1661 {
   1662     mTestContext = instance;
   1663 }
   1664 
   1665 /*===========================================================================
   1666  * FUNCTION   : ~CameraContext
   1667  *
   1668  * DESCRIPTION: camera context destructor
   1669  *
   1670  * PARAMETERS : None
   1671  *
   1672  * RETURN     : None
   1673  *==========================================================================*/
   1674 CameraContext::~CameraContext()
   1675 {
   1676     stopPreview();
   1677     closeCamera();
   1678 }
   1679 
   1680 /*===========================================================================
   1681  * FUNCTION   : openCamera
   1682  *
   1683  * DESCRIPTION: connects to and initializes camera
   1684  *
   1685  * PARAMETERS : None
   1686  *
   1687  * RETURN     : status_t type of status
   1688  *              NO_ERROR  -- success
   1689  *              none-zero failure code
   1690  *==========================================================================*/
   1691 status_t  CameraContext::openCamera()
   1692 {
   1693     useLock();
   1694     const char *ZSLStr = NULL;
   1695     size_t ZSLStrSize = 0;
   1696 
   1697     if ( NULL != mCamera.get() ) {
   1698         printf("Camera already open! \n");
   1699         signalFinished();
   1700         return NO_ERROR;
   1701     }
   1702 
   1703     printf("openCamera(camera_index=%d)\n", mCameraIndex);
   1704 
   1705 #ifndef USE_JB_MR1
   1706 
   1707     String16 packageName("CameraTest");
   1708 
   1709     mCamera = Camera::connect(mCameraIndex,
   1710                               packageName,
   1711                               Camera::USE_CALLING_UID);
   1712 
   1713 #else
   1714 
   1715     mCamera = Camera::connect(mCameraIndex);
   1716 
   1717 #endif
   1718 
   1719     if ( NULL == mCamera.get() ) {
   1720         printf("Unable to connect to CameraService\n");
   1721         signalFinished();
   1722         return NO_INIT;
   1723     }
   1724 
   1725     mParams = mCamera->getParameters();
   1726     mParams.getSupportedPreviewSizes(mSupportedPreviewSizes);
   1727     mParams.getSupportedPictureSizes(mSupportedPictureSizes);
   1728     mParams.getSupportedVideoSizes(mSupportedVideoSizes);
   1729 
   1730     mCurrentPictureSizeIdx = mSupportedPictureSizes.size() / 2;
   1731     mCurrentPreviewSizeIdx = mSupportedPreviewSizes.size() / 2;
   1732     mCurrentVideoSizeIdx   = mSupportedVideoSizes.size() / 2;
   1733 
   1734     mCamera->setListener(this);
   1735     mHardwareActive = true;
   1736 
   1737     mInterpr->setViVSize((Size) mSupportedVideoSizes.itemAt(
   1738         mCurrentVideoSizeIdx),
   1739         mCameraIndex);
   1740 
   1741     ZSLStr = mParams.get(CameraContext::KEY_ZSL);
   1742     if (NULL != ZSLStr) {
   1743         ZSLStrSize = strlen(ZSLStr);
   1744         if (!strncmp(ZSLStr, "on", ZSLStrSize)) {
   1745             mInterpr->mIsZSLOn = true;
   1746         } else if (!strncmp(ZSLStr, "off", ZSLStrSize)) {
   1747             mInterpr->mIsZSLOn = false;
   1748         } else {
   1749             printf("zsl value is not valid!\n");
   1750         }
   1751     } else {
   1752         printf("zsl is NULL\n");
   1753     }
   1754 
   1755     signalFinished();
   1756 
   1757     return NO_ERROR;
   1758 }
   1759 
   1760 /*===========================================================================
   1761  * FUNCTION   : onAsBinder
   1762  *
   1763  * DESCRIPTION: onAsBinder
   1764  *
   1765  * PARAMETERS : None
   1766  *
   1767  * RETURN     : Pointer to IBinder
   1768  *==========================================================================*/
   1769 IBinder* CameraContext::onAsBinder() {
   1770     return NULL;
   1771 }
   1772 
   1773 /*===========================================================================
   1774  * FUNCTION   : getNumberOfCameras
   1775  *
   1776  * DESCRIPTION: returns the number of supported camera by the system
   1777  *
   1778  * PARAMETERS : None
   1779  *
   1780  * RETURN     : supported camera count
   1781  *==========================================================================*/
   1782 int CameraContext::getNumberOfCameras()
   1783 {
   1784     int ret = -1;
   1785 
   1786     if ( NULL != mCamera.get() ) {
   1787         ret = mCamera->getNumberOfCameras();
   1788     }
   1789 
   1790     return ret;
   1791 }
   1792 
   1793 /*===========================================================================
   1794  * FUNCTION   : closeCamera
   1795  *
   1796  * DESCRIPTION: closes a previously the initialized camera reference
   1797  *
   1798  * PARAMETERS : None
   1799  *
   1800  * RETURN     : status_t type of status
   1801  *              NO_ERROR  -- success
   1802  *              none-zero failure code
   1803  *==========================================================================*/
   1804 status_t CameraContext::closeCamera()
   1805 {
   1806     useLock();
   1807     if ( NULL == mCamera.get() ) {
   1808         return NO_INIT;
   1809     }
   1810 
   1811     mCamera->disconnect();
   1812     mCamera.clear();
   1813 
   1814     mRecorder->init();
   1815     mRecorder->close();
   1816     mRecorder->release();
   1817     mRecorder.clear();
   1818 
   1819     mHardwareActive = false;
   1820     mPreviewRunning = false;
   1821     mRecordRunning = false;
   1822 
   1823     signalFinished();
   1824     return NO_ERROR;
   1825 }
   1826 
   1827 /*===========================================================================
   1828  * FUNCTION   : startPreview
   1829  *
   1830  * DESCRIPTION: starts camera preview
   1831  *
   1832  * PARAMETERS : None
   1833  *
   1834  * RETURN     : status_t type of status
   1835  *              NO_ERROR  -- success
   1836  *              none-zero failure code
   1837  *==========================================================================*/
   1838 status_t CameraContext::startPreview()
   1839 {
   1840     useLock();
   1841 
   1842     int ret = NO_ERROR;
   1843     int previewWidth, previewHeight;
   1844     Size calculatedPreviewSize;
   1845     Size currentPreviewSize = mSupportedPreviewSizes.itemAt(
   1846         mCurrentPreviewSizeIdx);
   1847     Size currentPictureSize = mSupportedPictureSizes.itemAt(
   1848         mCurrentPictureSizeIdx);
   1849     Size currentVideoSize   = mSupportedVideoSizes.itemAt(
   1850         mCurrentVideoSizeIdx);
   1851 
   1852 #ifndef USE_JB_MR1
   1853 
   1854     sp<IGraphicBufferProducer> gbp;
   1855 
   1856 #endif
   1857 
   1858     if (!mHardwareActive ) {
   1859         printf("Camera not active! \n");
   1860         return NO_INIT;
   1861     }
   1862 
   1863     if (mPreviewRunning) {
   1864         printf("Preview is already running! \n");
   1865         signalFinished();
   1866         return NO_ERROR;
   1867     }
   1868 
   1869     if (mResizePreview) {
   1870         mPreviewRunning = false;
   1871 
   1872         if ( mRecordingHint ) {
   1873             calculatedPreviewSize =
   1874                 getPreviewSizeFromVideoSizes(currentVideoSize);
   1875             previewWidth = calculatedPreviewSize.width;
   1876             previewHeight = calculatedPreviewSize.height;
   1877         } else {
   1878             previewWidth = currentPreviewSize.width;
   1879             previewHeight = currentPreviewSize.height;
   1880         }
   1881 
   1882         ret = createPreviewSurface(previewWidth,
   1883                                    previewHeight,
   1884                                    HAL_PIXEL_FORMAT_YCrCb_420_SP);
   1885         if (  NO_ERROR != ret ) {
   1886             printf("Error while creating preview surface\n");
   1887             return ret;
   1888         }
   1889 
   1890         // set rdi mode if system prop is set for front camera
   1891         if (mCameraIndex == 1) {
   1892             char value[32];
   1893             property_get("persist.camera.rdimode", value, "0");
   1894             int rdimode = atoi(value);
   1895             printf("rdi mode = %d\n", rdimode);
   1896             if (rdimode == 1) {
   1897                 mParams.set("rdi-mode", "enable");
   1898             } else {
   1899                 mParams.set("rdi-mode", "disable");
   1900             }
   1901         } else {
   1902             mParams.set("rdi-mode", "disable");
   1903         }
   1904 
   1905         //mParams.set("rdi-mode", "enable");
   1906         mParams.set("recording-hint", "true");
   1907         mParams.setPreviewSize(previewWidth, previewHeight);
   1908         mParams.setPictureSize(currentPictureSize.width,
   1909             currentPictureSize.height);
   1910         mParams.setVideoSize(
   1911             currentVideoSize.width, currentVideoSize.height);
   1912 
   1913         ret |= mCamera->setParameters(mParams.flatten());
   1914 
   1915 #ifndef USE_JB_MR1
   1916 
   1917         gbp = mPreviewSurface->getIGraphicBufferProducer();
   1918         ret |= mCamera->setPreviewTarget(gbp);
   1919 
   1920 #else
   1921 
   1922         ret |= mCamera->setPreviewDisplay(mPreviewSurface);
   1923 
   1924 #endif
   1925         mResizePreview = false;
   1926     }
   1927 
   1928     if ( !mPreviewRunning ) {
   1929         ret |= mCamera->startPreview();
   1930         if ( NO_ERROR != ret ) {
   1931             printf("Preview start failed! \n");
   1932             return ret;
   1933         }
   1934 
   1935         mPreviewRunning = true;
   1936     }
   1937 
   1938     signalFinished();
   1939 
   1940     return ret;
   1941 }
   1942 
   1943 /*===========================================================================
   1944  * FUNCTION   : getPreviewSizeFromVideoSizes
   1945  *
   1946  * DESCRIPTION: Get the preview size from video size. Find all resolutions with
   1947  *              the same aspect ratio and choose the same or the closest
   1948  *              from them.
   1949  *
   1950  * PARAMETERS :
   1951  *   @currentVideoSize: current video size
   1952 
   1953  *
   1954  * RETURN     : PreviewSize
   1955  *==========================================================================*/
   1956 Size CameraContext::getPreviewSizeFromVideoSizes(Size currentVideoSize)
   1957 {
   1958 
   1959     Size tmpPreviewSize;
   1960     Size PreviewSize;
   1961     Size PreviewSizes[mSupportedPreviewSizes.size()];
   1962     double tolerance = 0.00001;
   1963     double videoRatio;
   1964     double previewRatio;
   1965     size_t i = 0;
   1966     size_t j = 0;
   1967     int delta;
   1968 
   1969     // Find all the resolutions with the same aspect ratio and choose the
   1970     // same or the closest resolution from them. Choose the closest resolution
   1971     // in case same aspect ratio is not found
   1972     if (currentVideoSize.width * currentVideoSize.height > 0 &&
   1973             mSupportedPreviewSizes.size() > 0) {
   1974         videoRatio = (float)currentVideoSize.width /
   1975             (float)currentVideoSize.height;
   1976         for (i=0; i<mSupportedPreviewSizes.size(); i++) {
   1977             tmpPreviewSize = mSupportedPreviewSizes.itemAt(i);
   1978             previewRatio = (float)tmpPreviewSize.width /
   1979                 (float)tmpPreviewSize.height;
   1980             if (fabs(videoRatio - previewRatio) < tolerance) {
   1981                 PreviewSizes[j] = tmpPreviewSize;
   1982                 j++;
   1983             }
   1984         }
   1985 
   1986         if ( j > 0 ) {
   1987             delta = abs((currentVideoSize.width *currentVideoSize.height)-
   1988                 (PreviewSizes[0].width * PreviewSizes[0].height));
   1989             PreviewSize = PreviewSizes[0];
   1990             for (i=0; i<j; i++) {
   1991                 if(abs(currentVideoSize.width * currentVideoSize.height) -
   1992                     (PreviewSizes[i].width * PreviewSizes[i].height) <
   1993                     delta) {
   1994                     PreviewSize = PreviewSizes[i];
   1995                     delta = abs((currentVideoSize.width *
   1996                         currentVideoSize.height) -
   1997                         (PreviewSizes[i].width * PreviewSizes[i].height));
   1998                 }
   1999             }
   2000         } else {
   2001             // Choose the closest resolution in case same aspect ratio is
   2002             // not found
   2003             tmpPreviewSize = mSupportedPreviewSizes.itemAt(j);
   2004             PreviewSize = tmpPreviewSize;
   2005             delta = abs(
   2006                     (currentVideoSize.width * currentVideoSize.height)-
   2007                     (tmpPreviewSize.width * tmpPreviewSize.height));
   2008             for (i=0; i<mSupportedPreviewSizes.size(); i++) {
   2009                 tmpPreviewSize = mSupportedPreviewSizes.itemAt(i);
   2010                 if(abs(
   2011                         (currentVideoSize.width * currentVideoSize.height)-
   2012                         (tmpPreviewSize.width * tmpPreviewSize.height)) <
   2013                         delta) {
   2014                     PreviewSize = tmpPreviewSize;
   2015                     delta = abs(
   2016                             (currentVideoSize.width * currentVideoSize.height)-
   2017                             (tmpPreviewSize.width * tmpPreviewSize.height));
   2018                 }
   2019             }
   2020         }
   2021     } else {
   2022         memset(&PreviewSize, 0, sizeof(PreviewSize));
   2023     }
   2024     return PreviewSize;
   2025 }
   2026 
   2027 /*===========================================================================
   2028  * FUNCTION   : autoFocus
   2029  *
   2030  * DESCRIPTION: Triggers autofocus
   2031  *
   2032  * PARAMETERS : None
   2033  *
   2034  * RETURN     : status_t type of status
   2035  *              NO_ERROR  -- success
   2036  *              none-zero failure code
   2037  *==========================================================================*/
   2038 status_t CameraContext::autoFocus()
   2039 {
   2040     useLock();
   2041     status_t ret = NO_ERROR;
   2042 
   2043     if ( mPreviewRunning ) {
   2044         ret = mCamera->autoFocus();
   2045     }
   2046 
   2047     signalFinished();
   2048     return ret;
   2049 }
   2050 
   2051 /*===========================================================================
   2052  * FUNCTION   : enablePreviewCallbacks
   2053  *
   2054  * DESCRIPTION: Enables preview callback messages
   2055  *
   2056  * PARAMETERS : None
   2057  *
   2058  * RETURN     : status_t type of status
   2059  *              NO_ERROR  -- success
   2060  *              none-zero failure code
   2061  *==========================================================================*/
   2062 status_t CameraContext::enablePreviewCallbacks()
   2063 {
   2064     useLock();
   2065     if ( mHardwareActive ) {
   2066         mCamera->setPreviewCallbackFlags(
   2067             CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
   2068     }
   2069 
   2070     signalFinished();
   2071     return NO_ERROR;
   2072 }
   2073 
   2074 /*===========================================================================
   2075  * FUNCTION   : takePicture
   2076  *
   2077  * DESCRIPTION: triggers image capture
   2078  *
   2079  * PARAMETERS : None
   2080  *
   2081  * RETURN     : status_t type of status
   2082  *              NO_ERROR  -- success
   2083  *              none-zero failure code
   2084  *==========================================================================*/
   2085 status_t CameraContext::takePicture()
   2086 {
   2087     status_t ret = NO_ERROR;
   2088     useLock();
   2089     if ( mPreviewRunning ) {
   2090         ret = mCamera->takePicture(
   2091             CAMERA_MSG_COMPRESSED_IMAGE|
   2092             CAMERA_MSG_RAW_IMAGE);
   2093         if (!mRecordingHint && !mInterpr->mIsZSLOn) {
   2094             mPreviewRunning = false;
   2095         }
   2096     } else {
   2097         printf("Please resume/start the preview before taking a picture!\n");
   2098     }
   2099     signalFinished();
   2100     return ret;
   2101 }
   2102 
   2103 /*===========================================================================
   2104  * FUNCTION   : configureRecorder
   2105  *
   2106  * DESCRIPTION: Configure video recorder
   2107  *
   2108  * PARAMETERS : None
   2109  *
   2110  * RETURN     : status_t type of status
   2111  *              NO_ERROR  -- success
   2112  *              none-zero failure code
   2113  *==========================================================================*/
   2114 status_t CameraContext::configureRecorder()
   2115 {
   2116     useLock();
   2117     status_t ret = NO_ERROR;
   2118 
   2119     mResizePreview = true;
   2120     mParams.set("recording-hint", "true");
   2121     mRecordingHint = true;
   2122     mCamera->setParameters(mParams.flatten());
   2123 
   2124     Size videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
   2125     ret = mRecorder->setParameters(
   2126         String8("video-param-encoding-bitrate=64000"));
   2127     if ( ret != NO_ERROR ) {
   2128         LOGE("Could not configure recorder (%d)", ret);
   2129         return ret;
   2130     }
   2131 
   2132     ret = mRecorder->setCamera(
   2133         mCamera->remote(), mCamera->getRecordingProxy());
   2134     if ( ret != NO_ERROR ) {
   2135         LOGE("Could not set camera (%d)", ret);
   2136         return ret;
   2137     }
   2138     ret = mRecorder->setVideoSource(VIDEO_SOURCE_CAMERA);
   2139     if ( ret != NO_ERROR ) {
   2140         LOGE("Could not set video soruce (%d)", ret);
   2141         return ret;
   2142     }
   2143     ret = mRecorder->setAudioSource(AUDIO_SOURCE_DEFAULT);
   2144     if ( ret != NO_ERROR ) {
   2145         LOGE("Could not set audio source (%d)", ret);
   2146         return ret;
   2147     }
   2148     ret = mRecorder->setOutputFormat(OUTPUT_FORMAT_DEFAULT);
   2149     if ( ret != NO_ERROR ) {
   2150         LOGE("Could not set output format (%d)", ret);
   2151         return ret;
   2152     }
   2153 
   2154     ret = mRecorder->setVideoEncoder(VIDEO_ENCODER_DEFAULT);
   2155     if ( ret != NO_ERROR ) {
   2156         LOGE("Could not set video encoder (%d)", ret);
   2157         return ret;
   2158     }
   2159 
   2160     char fileName[100];
   2161 
   2162     snprintf(fileName, sizeof(fileName) / sizeof(char),
   2163             "/sdcard/vid_cam%d_%dx%d_%d.mpeg", mCameraIndex,
   2164             videoSize.width, videoSize.height, mVideoIdx++);
   2165 
   2166     if ( mVideoFd < 0 ) {
   2167         mVideoFd = open(fileName, O_CREAT | O_RDWR );
   2168     }
   2169 
   2170     if ( mVideoFd < 0 ) {
   2171         LOGE("Could not open video file for writing %s!", fileName);
   2172         return UNKNOWN_ERROR;
   2173     }
   2174 
   2175     ret = mRecorder->setOutputFile(mVideoFd, 0, 0);
   2176     if ( ret != NO_ERROR ) {
   2177         LOGE("Could not set output file (%d)", ret);
   2178         return ret;
   2179     }
   2180 
   2181     ret = mRecorder->setVideoSize(videoSize.width, videoSize.height);
   2182     if ( ret  != NO_ERROR ) {
   2183         LOGE("Could not set video size %dx%d", videoSize.width,
   2184             videoSize.height);
   2185         return ret;
   2186     }
   2187 
   2188     ret = mRecorder->setVideoFrameRate(30);
   2189     if ( ret != NO_ERROR ) {
   2190         LOGE("Could not set video frame rate (%d)", ret);
   2191         return ret;
   2192     }
   2193 
   2194     ret = mRecorder->setAudioEncoder(AUDIO_ENCODER_DEFAULT);
   2195     if ( ret != NO_ERROR ) {
   2196         LOGE("Could not set audio encoder (%d)", ret);
   2197         return ret;
   2198     }
   2199 
   2200     signalFinished();
   2201     return ret;
   2202 }
   2203 
   2204 /*===========================================================================
   2205  * FUNCTION   : unconfigureViVRecording
   2206  *
   2207  * DESCRIPTION: Unconfigures video in video recording
   2208  *
   2209  * PARAMETERS : None
   2210  *
   2211  * RETURN     : status_t type of status
   2212  *              NO_ERROR  -- success
   2213  *              none-zero failure code
   2214  *==========================================================================*/
   2215 status_t CameraContext::unconfigureRecorder()
   2216 {
   2217     useLock();
   2218 
   2219     if ( !mRecordRunning ) {
   2220         mResizePreview = true;
   2221         mParams.set("recording-hint", "false");
   2222         mRecordingHint = false;
   2223         mCamera->setParameters(mParams.flatten());
   2224     }
   2225 
   2226     signalFinished();
   2227     return NO_ERROR;
   2228 }
   2229 
   2230 /*===========================================================================
   2231  * FUNCTION   : configureViVRecording
   2232  *
   2233  * DESCRIPTION: Configures video in video recording
   2234  *
   2235  * PARAMETERS : None
   2236  *
   2237  * RETURN     : status_t type of status
   2238  *              NO_ERROR  -- success
   2239  *              none-zero failure code
   2240  *==========================================================================*/
   2241 status_t CameraContext::configureViVRecording()
   2242 {
   2243     status_t ret = NO_ERROR;
   2244 
   2245     mResizePreview = true;
   2246     mParams.set("recording-hint", "true");
   2247     mRecordingHint = true;
   2248     mCamera->setParameters(mParams.flatten());
   2249     mCamera->setRecordingProxyListener(this);
   2250 
   2251     signalFinished();
   2252     return ret;
   2253 }
   2254 
   2255 /*===========================================================================
   2256  * FUNCTION   : startRecording
   2257  *
   2258  * DESCRIPTION: triggers start recording
   2259  *
   2260  * PARAMETERS : None
   2261  *
   2262  * RETURN     : status_t type of status
   2263  *              NO_ERROR  -- success
   2264  *              none-zero failure code
   2265  *==========================================================================*/
   2266 status_t CameraContext::startRecording()
   2267 {
   2268     useLock();
   2269     status_t ret = NO_ERROR;
   2270 
   2271 
   2272     if ( mPreviewRunning ) {
   2273 
   2274         mCamera->unlock();
   2275 
   2276         ret = mRecorder->prepare();
   2277         if ( ret != NO_ERROR ) {
   2278             LOGE("Could not prepare recorder");
   2279             return ret;
   2280         }
   2281 
   2282         ret = mRecorder->start();
   2283         if ( ret != NO_ERROR ) {
   2284             LOGE("Could not start recorder");
   2285             return ret;
   2286         }
   2287 
   2288         mRecordRunning = true;
   2289     }
   2290     signalFinished();
   2291     return ret;
   2292 }
   2293 
   2294 /*===========================================================================
   2295  * FUNCTION   : stopRecording
   2296  *
   2297  * DESCRIPTION: triggers start recording
   2298  *
   2299  * PARAMETERS : None
   2300  *
   2301  * RETURN     : status_t type of status
   2302  *              NO_ERROR  -- success
   2303  *              none-zero failure code
   2304  *==========================================================================*/
   2305 status_t CameraContext::stopRecording()
   2306 {
   2307     useLock();
   2308     status_t ret = NO_ERROR;
   2309 
   2310     if ( mRecordRunning ) {
   2311             mRecorder->stop();
   2312             close(mVideoFd);
   2313             mVideoFd = -1;
   2314 
   2315         mRecordRunning = false;
   2316     }
   2317 
   2318     signalFinished();
   2319 
   2320     return ret;
   2321 }
   2322 
   2323 /*===========================================================================
   2324  * FUNCTION   : startViVRecording
   2325  *
   2326  * DESCRIPTION: Starts video in video recording
   2327  *
   2328  * PARAMETERS : None
   2329  *
   2330  * RETURN     : status_t type of status
   2331  *              NO_ERROR  -- success
   2332  *              none-zero failure code
   2333  *==========================================================================*/
   2334 status_t CameraContext::startViVRecording()
   2335 {
   2336     useLock();
   2337     status_t ret;
   2338 
   2339     if (mInterpr->mViVVid.VideoSizes[0].width *
   2340             mInterpr->mViVVid.VideoSizes[0].height >=
   2341             mInterpr->mViVVid.VideoSizes[1].width *
   2342             mInterpr->mViVVid.VideoSizes[1].height) {
   2343         mInterpr->mViVBuff.buffSize = calcBufferSize(
   2344             mInterpr->mViVVid.VideoSizes[1].width,
   2345             mInterpr->mViVVid.VideoSizes[1].height);
   2346         if (mInterpr->mViVBuff.buff == NULL) {
   2347             mInterpr->mViVBuff.buff =
   2348                 (void *)malloc(mInterpr->mViVBuff.buffSize);
   2349         }
   2350         mInterpr->mViVVid.sourceCameraID = 1;
   2351         mInterpr->mViVVid.destinationCameraID = 0;
   2352 
   2353     } else {
   2354         mInterpr->mViVBuff.buffSize = calcBufferSize(
   2355             mInterpr->mViVVid.VideoSizes[0].width,
   2356             mInterpr->mViVVid.VideoSizes[0].height);
   2357         if (mInterpr->mViVBuff.buff == NULL) {
   2358             mInterpr->mViVBuff.buff =
   2359                 (void *)malloc(mInterpr->mViVBuff.buffSize);
   2360         }
   2361         mInterpr->mViVVid.sourceCameraID = 0;
   2362         mInterpr->mViVVid.destinationCameraID = 1;
   2363     }
   2364 
   2365     ret = mCamera->startRecording();
   2366 
   2367     signalFinished();
   2368     return ret;
   2369 }
   2370 
   2371 /*===========================================================================
   2372  * FUNCTION   : stopViVRecording
   2373  *
   2374  * DESCRIPTION: Stops video in video recording
   2375  *
   2376  * PARAMETERS : None
   2377  *
   2378  * RETURN     : status_t type of status
   2379  *              NO_ERROR  -- success
   2380  *              none-zero failure code
   2381  *==========================================================================*/
   2382 status_t CameraContext::stopViVRecording()
   2383 {
   2384     useLock();
   2385     status_t ret = NO_ERROR;
   2386 
   2387     mCamera->stopRecording();
   2388 
   2389     signalFinished();
   2390     return ret;
   2391 }
   2392 
   2393 /*===========================================================================
   2394  * FUNCTION   : stopPreview
   2395  *
   2396  * DESCRIPTION: stops camera preview
   2397  *
   2398  * PARAMETERS : None
   2399  *
   2400  * RETURN     : status_t type of status
   2401  *              NO_ERROR  -- success
   2402  *              none-zero failure code
   2403  *==========================================================================*/
   2404 status_t CameraContext::stopPreview()
   2405 {
   2406     useLock();
   2407     status_t ret = NO_ERROR;
   2408 
   2409     if ( mHardwareActive ) {
   2410         mCamera->stopPreview();
   2411         ret = destroyPreviewSurface();
   2412     }
   2413 
   2414     mPreviewRunning  = false;
   2415     mResizePreview = true;
   2416 
   2417     signalFinished();
   2418 
   2419     return ret;
   2420 }
   2421 
   2422 /*===========================================================================
   2423  * FUNCTION   : resumePreview
   2424  *
   2425  * DESCRIPTION: resumes camera preview after image capture
   2426  *
   2427  * PARAMETERS : None
   2428  *
   2429  * RETURN     : status_t type of status
   2430  *              NO_ERROR  -- success
   2431  *              none-zero failure code
   2432  *==========================================================================*/
   2433 status_t CameraContext::resumePreview()
   2434 {
   2435     useLock();
   2436     status_t ret = NO_ERROR;
   2437 
   2438     if ( mHardwareActive ) {
   2439         ret = mCamera->startPreview();
   2440         mPreviewRunning = true;
   2441     } else {
   2442         ret = NO_INIT;
   2443     }
   2444 
   2445     signalFinished();
   2446     return ret;
   2447 }
   2448 
   2449 /*===========================================================================
   2450  * FUNCTION   : nextPreviewSize
   2451  *
   2452  * DESCRIPTION: Iterates through all supported preview sizes.
   2453  *
   2454  * PARAMETERS : None
   2455  *
   2456  * RETURN     : status_t type of status
   2457  *              NO_ERROR  -- success
   2458  *              none-zero failure code
   2459  *==========================================================================*/
   2460 status_t CameraContext::nextPreviewSize()
   2461 {
   2462     useLock();
   2463     if ( mHardwareActive ) {
   2464         mCurrentPreviewSizeIdx += 1;
   2465         mCurrentPreviewSizeIdx %= mSupportedPreviewSizes.size();
   2466         Size previewSize = mSupportedPreviewSizes.itemAt(
   2467             mCurrentPreviewSizeIdx);
   2468         mParams.setPreviewSize(previewSize.width,
   2469                                previewSize.height);
   2470         mResizePreview = true;
   2471 
   2472         if ( mPreviewRunning ) {
   2473             mCamera->stopPreview();
   2474             mCamera->setParameters(mParams.flatten());
   2475             mCamera->startPreview();
   2476         } else {
   2477             mCamera->setParameters(mParams.flatten());
   2478         }
   2479     }
   2480 
   2481     signalFinished();
   2482     return NO_ERROR;
   2483 }
   2484 
   2485 
   2486 /*===========================================================================
   2487  * FUNCTION   : setPreviewSize
   2488  *
   2489  * DESCRIPTION: Sets exact preview size if supported
   2490  *
   2491  * PARAMETERS : format size in the form of WIDTHxHEIGHT
   2492  *
   2493  * RETURN     : status_t type of status
   2494  *              NO_ERROR  -- success
   2495  *              none-zero failure code
   2496  *==========================================================================*/
   2497 status_t CameraContext::setPreviewSize(const char *format)
   2498 {
   2499     useLock();
   2500     if ( mHardwareActive ) {
   2501         int newHeight;
   2502         int newWidth;
   2503         sscanf(format, "%dx%d", &newWidth, &newHeight);
   2504 
   2505         unsigned int i;
   2506         for (i = 0; i < mSupportedPreviewSizes.size(); ++i) {
   2507             Size previewSize = mSupportedPreviewSizes.itemAt(i);
   2508             if ( newWidth == previewSize.width &&
   2509                  newHeight == previewSize.height )
   2510             {
   2511                 break;
   2512             }
   2513 
   2514         }
   2515         if ( i == mSupportedPreviewSizes.size())
   2516         {
   2517             printf("Preview size %dx%d not supported !\n",
   2518                 newWidth, newHeight);
   2519             return INVALID_OPERATION;
   2520         }
   2521 
   2522         mParams.setPreviewSize(newWidth,
   2523                                newHeight);
   2524         mResizePreview = true;
   2525 
   2526         if ( mPreviewRunning ) {
   2527             mCamera->stopPreview();
   2528             mCamera->setParameters(mParams.flatten());
   2529             mCamera->startPreview();
   2530         } else {
   2531             mCamera->setParameters(mParams.flatten());
   2532         }
   2533     }
   2534 
   2535     signalFinished();
   2536     return NO_ERROR;
   2537 }
   2538 
   2539 /*===========================================================================
   2540  * FUNCTION   : getCurrentPreviewSize
   2541  *
   2542  * DESCRIPTION: queries the currently configured preview size
   2543  *
   2544  * PARAMETERS :
   2545  *  @previewSize : preview size currently configured
   2546  *
   2547  * RETURN     : status_t type of status
   2548  *              NO_ERROR  -- success
   2549  *              none-zero failure code
   2550  *==========================================================================*/
   2551 status_t CameraContext::getCurrentPreviewSize(Size &previewSize)
   2552 {
   2553     useLock();
   2554     if ( mHardwareActive ) {
   2555         previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
   2556     }
   2557     signalFinished();
   2558     return NO_ERROR;
   2559 }
   2560 
   2561 /*===========================================================================
   2562  * FUNCTION   : nextPictureSize
   2563  *
   2564  * DESCRIPTION: Iterates through all supported picture sizes.
   2565  *
   2566  * PARAMETERS : None
   2567  *
   2568  * RETURN     : status_t type of status
   2569  *              NO_ERROR  -- success
   2570  *              none-zero failure code
   2571  *==========================================================================*/
   2572 status_t CameraContext::nextPictureSize()
   2573 {
   2574     useLock();
   2575     if ( mHardwareActive ) {
   2576         mCurrentPictureSizeIdx += 1;
   2577         mCurrentPictureSizeIdx %= mSupportedPictureSizes.size();
   2578         Size pictureSize = mSupportedPictureSizes.itemAt(
   2579             mCurrentPictureSizeIdx);
   2580         mParams.setPictureSize(pictureSize.width,
   2581             pictureSize.height);
   2582         mCamera->setParameters(mParams.flatten());
   2583     }
   2584     signalFinished();
   2585     return NO_ERROR;
   2586 }
   2587 
   2588 /*===========================================================================
   2589  * FUNCTION   : setPictureSize
   2590  *
   2591  * DESCRIPTION: Sets exact preview size if supported
   2592  *
   2593  * PARAMETERS : format size in the form of WIDTHxHEIGHT
   2594  *
   2595  * RETURN     : status_t type of status
   2596  *              NO_ERROR  -- success
   2597  *              none-zero failure code
   2598  *==========================================================================*/
   2599 status_t CameraContext::setPictureSize(const char *format)
   2600 {
   2601     useLock();
   2602     if ( mHardwareActive ) {
   2603         int newHeight;
   2604         int newWidth;
   2605         sscanf(format, "%dx%d", &newWidth, &newHeight);
   2606 
   2607         unsigned int i;
   2608         for (i = 0; i < mSupportedPictureSizes.size(); ++i) {
   2609             Size PictureSize = mSupportedPictureSizes.itemAt(i);
   2610             if ( newWidth == PictureSize.width &&
   2611                  newHeight == PictureSize.height )
   2612             {
   2613                 break;
   2614             }
   2615 
   2616         }
   2617         if ( i == mSupportedPictureSizes.size())
   2618         {
   2619             printf("Preview size %dx%d not supported !\n",
   2620                 newWidth, newHeight);
   2621             return INVALID_OPERATION;
   2622         }
   2623 
   2624         mParams.setPictureSize(newWidth,
   2625                                newHeight);
   2626         mCamera->setParameters(mParams.flatten());
   2627     }
   2628 
   2629     signalFinished();
   2630     return NO_ERROR;
   2631 }
   2632 
   2633 /*===========================================================================
   2634  * FUNCTION   : nextVideoSize
   2635  *
   2636  * DESCRIPTION: Select the next available video size
   2637  *
   2638  * PARAMETERS : none
   2639  *
   2640  * RETURN     : status_t type of status
   2641  *              NO_ERROR  -- success
   2642  *              none-zero failure code
   2643  *==========================================================================*/
   2644 status_t CameraContext::nextVideoSize()
   2645 {
   2646     useLock();
   2647     if ( mHardwareActive ) {
   2648         mCurrentVideoSizeIdx += 1;
   2649         mCurrentVideoSizeIdx %= mSupportedVideoSizes.size();
   2650         Size videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
   2651         mParams.setVideoSize(videoSize.width,
   2652                              videoSize.height);
   2653         mCamera->setParameters(mParams.flatten());
   2654         mInterpr->setViVSize((Size) mSupportedVideoSizes.itemAt(
   2655             mCurrentVideoSizeIdx), mCameraIndex);
   2656     }
   2657     signalFinished();
   2658     return NO_ERROR;
   2659 }
   2660 
   2661 /*===========================================================================
   2662  * FUNCTION   : setVideoSize
   2663  *
   2664  * DESCRIPTION: Set video size
   2665  *
   2666  * PARAMETERS :
   2667  *   @format  : format
   2668  *
   2669  * RETURN     : status_t type of status
   2670  *              NO_ERROR  -- success
   2671  *              none-zero failure code
   2672  *==========================================================================*/
   2673 status_t CameraContext::setVideoSize(const char *format)
   2674 {
   2675     useLock();
   2676     if ( mHardwareActive ) {
   2677         int newHeight;
   2678         int newWidth;
   2679         sscanf(format, "%dx%d", &newWidth, &newHeight);
   2680 
   2681         unsigned int i;
   2682         for (i = 0; i < mSupportedVideoSizes.size(); ++i) {
   2683             Size PictureSize = mSupportedVideoSizes.itemAt(i);
   2684             if ( newWidth == PictureSize.width &&
   2685                  newHeight == PictureSize.height )
   2686             {
   2687                 break;
   2688             }
   2689 
   2690         }
   2691         if ( i == mSupportedVideoSizes.size())
   2692         {
   2693             printf("Preview size %dx%d not supported !\n",
   2694                 newWidth, newHeight);
   2695             return INVALID_OPERATION;
   2696         }
   2697 
   2698         mParams.setVideoSize(newWidth,
   2699                              newHeight);
   2700         mCamera->setParameters(mParams.flatten());
   2701     }
   2702 
   2703     signalFinished();
   2704     return NO_ERROR;
   2705 }
   2706 
   2707 /*===========================================================================
   2708  * FUNCTION    : getCurrentVideoSize
   2709  *
   2710  * DESCRIPTION : Get current video size
   2711  *
   2712  * PARAMETERS  :
   2713  *   @videoSize: video Size
   2714  *
   2715  * RETURN      : status_t type of status
   2716  *               NO_ERROR  -- success
   2717  *               none-zero failure code
   2718  *==========================================================================*/
   2719 status_t CameraContext::getCurrentVideoSize(Size &videoSize)
   2720 {
   2721     useLock();
   2722     if ( mHardwareActive ) {
   2723         videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
   2724     }
   2725     signalFinished();
   2726     return NO_ERROR;
   2727 }
   2728 
   2729 /*===========================================================================
   2730  * FUNCTION   : getCurrentPictureSize
   2731  *
   2732  * DESCRIPTION: queries the currently configured picture size
   2733  *
   2734  * PARAMETERS :
   2735  *  @pictureSize : picture size currently configured
   2736  *
   2737  * RETURN     : status_t type of status
   2738  *              NO_ERROR  -- success
   2739  *              none-zero failure code
   2740  *==========================================================================*/
   2741 status_t CameraContext::getCurrentPictureSize(Size &pictureSize)
   2742 {
   2743     useLock();
   2744     if ( mHardwareActive ) {
   2745         pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
   2746     }
   2747     signalFinished();
   2748     return NO_ERROR;
   2749 }
   2750 
   2751 }; //namespace qcamera ends here
   2752 
   2753 using namespace qcamera;
   2754 
   2755 /*===========================================================================
   2756  * FUNCTION   : printMenu
   2757  *
   2758  * DESCRIPTION: prints the available camera options
   2759  *
   2760  * PARAMETERS :
   2761  *  @currentCamera : camera context currently being used
   2762  *
   2763  * RETURN     : None
   2764  *==========================================================================*/
   2765 void CameraContext::printMenu(sp<CameraContext> currentCamera)
   2766 {
   2767     if ( !mDoPrintMenu ) return;
   2768     Size currentPictureSize, currentPreviewSize, currentVideoSize;
   2769     const char *zsl_mode = mParams.get(CameraContext::KEY_ZSL);
   2770 
   2771     assert(currentCamera.get());
   2772 
   2773     currentCamera->getCurrentPictureSize(currentPictureSize);
   2774     currentCamera->getCurrentPreviewSize(currentPreviewSize);
   2775     currentCamera->getCurrentVideoSize(currentVideoSize);
   2776 
   2777     printf("\n\n=========== FUNCTIONAL TEST MENU ===================\n\n");
   2778 
   2779     printf(" \n\nSTART / STOP / GENERAL SERVICES \n");
   2780     printf(" -----------------------------\n");
   2781     printf("   %c. Switch camera - Current Index: %d\n",
   2782             Interpreter::SWITCH_CAMERA_CMD,
   2783             currentCamera->getCameraIndex());
   2784     printf("   %c. Resume Preview after capture \n",
   2785             Interpreter::RESUME_PREVIEW_CMD);
   2786     printf("   %c. Quit \n",
   2787             Interpreter::EXIT_CMD);
   2788     printf("   %c. Camera Capability Dump",
   2789             Interpreter::DUMP_CAPS_CMD);
   2790 
   2791     printf(" \n\n PREVIEW SUB MENU \n");
   2792     printf(" -----------------------------\n");
   2793     printf("   %c. Start Preview\n",
   2794             Interpreter::START_PREVIEW_CMD);
   2795     printf("   %c. Stop Preview\n",
   2796             Interpreter::STOP_PREVIEW_CMD);
   2797     printf("   %c. Preview size:  %dx%d\n",
   2798             Interpreter::CHANGE_PREVIEW_SIZE_CMD,
   2799             currentPreviewSize.width,
   2800             currentPreviewSize.height);
   2801     printf("   %c. Video size:  %dx%d\n",
   2802             Interpreter::CHANGE_VIDEO_SIZE_CMD,
   2803             currentVideoSize.width,
   2804             currentVideoSize.height);
   2805     printf("   %c. Start Recording\n",
   2806             Interpreter::START_RECORD_CMD);
   2807     printf("   %c. Stop Recording\n",
   2808             Interpreter::STOP_RECORD_CMD);
   2809     printf("   %c. Start ViV Recording\n",
   2810             Interpreter::START_VIV_RECORD_CMD);
   2811     printf("   %c. Stop ViV Recording\n",
   2812             Interpreter::STOP_VIV_RECORD_CMD);
   2813     printf("   %c. Enable preview frames\n",
   2814             Interpreter::ENABLE_PRV_CALLBACKS_CMD);
   2815     printf("   %c. Trigger autofocus \n",
   2816             Interpreter::AUTOFOCUS_CMD);
   2817 
   2818     printf(" \n\n IMAGE CAPTURE SUB MENU \n");
   2819     printf(" -----------------------------\n");
   2820     printf("   %c. Take picture/Full Press\n",
   2821             Interpreter::TAKEPICTURE_CMD);
   2822     printf("   %c. Take picture in picture\n",
   2823             Interpreter::TAKEPICTURE_IN_PICTURE_CMD);
   2824     printf("   %c. Picture size:  %dx%d\n",
   2825             Interpreter::CHANGE_PICTURE_SIZE_CMD,
   2826             currentPictureSize.width,
   2827             currentPictureSize.height);
   2828     printf("   %c. zsl:  %s\n", Interpreter::ZSL_CMD,
   2829         (zsl_mode != NULL) ? zsl_mode : "NULL");
   2830 
   2831     printf("\n   Choice: ");
   2832 }
   2833 
   2834 /*===========================================================================
   2835  * FUNCTION   : enablePrintPreview
   2836  *
   2837  * DESCRIPTION: Enables printing the preview
   2838  *
   2839  * PARAMETERS : None
   2840  *
   2841  * RETURN     : None
   2842  *==========================================================================*/
   2843 void CameraContext::enablePrintPreview()
   2844 {
   2845     mDoPrintMenu = true;
   2846 }
   2847 
   2848 /*===========================================================================
   2849  * FUNCTION   : disablePrintPreview
   2850  *
   2851  * DESCRIPTION: Disables printing the preview
   2852  *
   2853  * PARAMETERS : None
   2854  *
   2855  * RETURN     : None
   2856  *==========================================================================*/
   2857 void CameraContext::disablePrintPreview()
   2858 {
   2859     mDoPrintMenu = false;
   2860 }
   2861 
   2862 /*===========================================================================
   2863  * FUNCTION   : enablePiPCapture
   2864  *
   2865  * DESCRIPTION: Enables picture in picture capture
   2866  *
   2867  * PARAMETERS : None
   2868  *
   2869  * RETURN     : None
   2870  *==========================================================================*/
   2871 void CameraContext::enablePiPCapture()
   2872 {
   2873     mPiPCapture = true;
   2874 }
   2875 
   2876 /*===========================================================================
   2877  * FUNCTION   : disablePiPCapture
   2878  *
   2879  * DESCRIPTION: Disables picture in picture capture
   2880  *
   2881  * PARAMETERS : None
   2882  *
   2883  * RETURN     : None
   2884  *==========================================================================*/
   2885 void CameraContext::disablePiPCapture()
   2886 {
   2887     mPiPCapture = false;
   2888 }
   2889 
   2890 /*===========================================================================
   2891  * FUNCTION   : getZSL
   2892  *
   2893  * DESCRIPTION: get ZSL value of current camera
   2894  *
   2895  * PARAMETERS : None
   2896  *
   2897  * RETURN     : current zsl value
   2898  *==========================================================================*/
   2899 const char *CameraContext::getZSL()
   2900 {
   2901     return mParams.get(CameraContext::KEY_ZSL);
   2902 }
   2903 
   2904 /*===========================================================================
   2905  * FUNCTION   : setZSL
   2906  *
   2907  * DESCRIPTION: set ZSL value of current camera
   2908  *
   2909  * PARAMETERS : zsl value to be set
   2910  *
   2911  * RETURN     : None
   2912  *==========================================================================*/
   2913 void CameraContext::setZSL(const char *value)
   2914 {
   2915     mParams.set(CameraContext::KEY_ZSL, value);
   2916     mCamera->setParameters(mParams.flatten());
   2917 }
   2918 
   2919 /*===========================================================================
   2920  * FUNCTION   : configureViVCodec
   2921  *
   2922  * DESCRIPTION: Configures video in video codec
   2923  *
   2924  * PARAMETERS : none
   2925  *
   2926  * RETURN     : status_t type of status
   2927  *              NO_ERROR  -- success
   2928  *              none-zero failure code
   2929  *==========================================================================*/
   2930 status_t Interpreter::configureViVCodec()
   2931 {
   2932     status_t ret = NO_ERROR;
   2933     char fileName[100];
   2934     sp<AMessage> format = new AMessage;
   2935     sp<ALooper> looper = new ALooper;
   2936 
   2937     if (mTestContext->mViVVid.VideoSizes[0].width *
   2938             mTestContext->mViVVid.VideoSizes[0].height >=
   2939             mTestContext->mViVVid.VideoSizes[1].width *
   2940             mTestContext->mViVVid.VideoSizes[1].height) {
   2941         snprintf(fileName, sizeof(fileName) / sizeof(char), "/sdcard/ViV_vid_%dx%d_%d.mp4",
   2942             mTestContext->mViVVid.VideoSizes[0].width,
   2943             mTestContext->mViVVid.VideoSizes[0].height,
   2944             mTestContext->mViVVid.ViVIdx++);
   2945         format->setInt32("width", mTestContext->mViVVid.VideoSizes[0].width);
   2946         format->setInt32("height", mTestContext->mViVVid.VideoSizes[0].height);
   2947     } else {
   2948         snprintf(fileName, sizeof(fileName) / sizeof(char), "/sdcard/ViV_vid_%dx%d_%d.mp4",
   2949             mTestContext->mViVVid.VideoSizes[1].width,
   2950             mTestContext->mViVVid.VideoSizes[1].height,
   2951             mTestContext->mViVVid.ViVIdx++);
   2952         format->setInt32("width", mTestContext->mViVVid.VideoSizes[1].width);
   2953         format->setInt32("height", mTestContext->mViVVid.VideoSizes[1].height);
   2954     }
   2955     int fd = open(fileName, O_CREAT | O_RDWR );
   2956     if (fd < 0) {
   2957         LOGE("Error opening file");
   2958         return UNKNOWN_ERROR;
   2959     }
   2960     mTestContext->mViVVid.muxer = new MediaMuxer(
   2961         fd, MediaMuxer::OUTPUT_FORMAT_MPEG_4);
   2962 
   2963     format->setString("mime", "video/avc");
   2964     format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
   2965 
   2966     format->setInt32("bitrate", 1000000);
   2967     format->setFloat("frame-rate", 30);
   2968     format->setInt32("i-frame-interval", 10);
   2969 
   2970     looper->setName("ViV_recording_looper");
   2971     looper->start();
   2972     ALOGV("Creating codec");
   2973     mTestContext->mViVVid.codec = MediaCodec::CreateByType(
   2974         looper, "video/avc", true);
   2975     if (mTestContext->mViVVid.codec == NULL) {
   2976         fprintf(stderr, "ERROR: unable to create video/avc codec instance\n");
   2977         return UNKNOWN_ERROR;
   2978     }
   2979     ret = mTestContext->mViVVid.codec->configure(format, NULL, NULL,
   2980             MediaCodec::CONFIGURE_FLAG_ENCODE);
   2981     if (ret != NO_ERROR) {
   2982         mTestContext->mViVVid.codec->release();
   2983         mTestContext->mViVVid.codec.clear();
   2984 
   2985         fprintf(stderr, "ERROR: unable to configure codec (err=%d)\n", ret);
   2986         return ret;
   2987     }
   2988 
   2989     ALOGV("Creating buffer producer");
   2990     ret = mTestContext->mViVVid.codec->createInputSurface(
   2991         &mTestContext->mViVVid.bufferProducer);
   2992     if (ret != NO_ERROR) {
   2993         mTestContext->mViVVid.codec->release();
   2994         mTestContext->mViVVid.codec.clear();
   2995 
   2996         fprintf(stderr,
   2997             "ERROR: unable to create encoder input surface (err=%d)\n", ret);
   2998         return ret;
   2999     }
   3000 
   3001     ret = mTestContext->mViVVid.codec->start();
   3002     if (ret != NO_ERROR) {
   3003         mTestContext->mViVVid.codec->release();
   3004         mTestContext->mViVVid.codec.clear();
   3005 
   3006         fprintf(stderr, "ERROR: unable to start codec (err=%d)\n", ret);
   3007         return ret;
   3008     }
   3009     ALOGV("Codec prepared");
   3010 
   3011     mTestContext->mViVVid.surface = new Surface(
   3012         mTestContext->mViVVid.bufferProducer);
   3013     mTestContext->mViVVid.ANW = mTestContext->mViVVid.surface;
   3014     ret = native_window_api_connect(mTestContext->mViVVid.ANW.get(),
   3015         NATIVE_WINDOW_API_CPU);
   3016     if (mTestContext->mViVVid.VideoSizes[0].width *
   3017         mTestContext->mViVVid.VideoSizes[0].height >=
   3018         mTestContext->mViVVid.VideoSizes[1].width *
   3019         mTestContext->mViVVid.VideoSizes[1].height) {
   3020         native_window_set_buffers_format(mTestContext->mViVVid.ANW.get(),
   3021                 HAL_PIXEL_FORMAT_NV12_ENCODEABLE);
   3022         native_window_set_buffers_dimensions(mTestContext->mViVVid.ANW.get(),
   3023                 mTestContext->mViVVid.VideoSizes[0].width,
   3024                 mTestContext->mViVVid.VideoSizes[0].height);
   3025     } else {
   3026         native_window_set_buffers_format(mTestContext->mViVVid.ANW.get(),
   3027                 HAL_PIXEL_FORMAT_NV12_ENCODEABLE);
   3028         native_window_set_buffers_dimensions(mTestContext->mViVVid.ANW.get(),
   3029                 mTestContext->mViVVid.VideoSizes[1].width,
   3030                 mTestContext->mViVVid.VideoSizes[1].height);
   3031     }
   3032     native_window_set_usage(mTestContext->mViVVid.ANW.get(),
   3033         GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
   3034     native_window_set_buffer_count(mTestContext->mViVVid.ANW.get(),
   3035         mTestContext->mViVVid.buff_cnt);
   3036 
   3037     ViVEncoderThread();
   3038 
   3039     return ret;
   3040 }
   3041 
   3042 /*===========================================================================
   3043  * FUNCTION   : unconfigureViVCodec
   3044  *
   3045  * DESCRIPTION: Unconfigures video in video codec
   3046  *
   3047  * PARAMETERS : none
   3048  *
   3049  * RETURN     : status_t type of status
   3050  *              NO_ERROR  -- success
   3051  *              none-zero failure code
   3052  *==========================================================================*/
   3053 status_t Interpreter::unconfigureViVCodec()
   3054 {
   3055     status_t ret = NO_ERROR;
   3056 
   3057     ret = native_window_api_disconnect(mTestContext->mViVVid.ANW.get(),
   3058         NATIVE_WINDOW_API_CPU);
   3059     mTestContext->mViVVid.bufferProducer = NULL;
   3060     mTestContext->mViVVid.codec->stop();
   3061     pthread_join(mViVEncThread, NULL);
   3062     mTestContext->mViVVid.muxer->stop();
   3063     mTestContext->mViVVid.codec->release();
   3064     mTestContext->mViVVid.codec.clear();
   3065     mTestContext->mViVVid.muxer.clear();
   3066     mTestContext->mViVVid.surface.clear();
   3067   return ret;
   3068 }
   3069 
   3070 /*===========================================================================
   3071  * FUNCTION   : Interpreter
   3072  *
   3073  * DESCRIPTION: Interpreter constructor
   3074  *
   3075  * PARAMETERS : none
   3076  *
   3077  * RETURN     : none
   3078  *==========================================================================*/
   3079 Interpreter::Interpreter(const char *file)
   3080     : mCmdIndex(0)
   3081     , mScript(NULL)
   3082 {
   3083     if (!file){
   3084         printf("no File Given\n");
   3085         mUseScript = false;
   3086         return;
   3087     }
   3088 
   3089     FILE *fh = fopen(file, "r");
   3090     if ( !fh ) {
   3091         printf("Could not open file %s\n", file);
   3092         mUseScript = false;
   3093         return;
   3094     }
   3095 
   3096     fseek(fh, 0, SEEK_END);
   3097     size_t len = (size_t)ftell(fh);
   3098     rewind(fh);
   3099 
   3100     if( !len ) {
   3101         printf("Script file %s is empty !\n", file);
   3102         fclose(fh);
   3103         return;
   3104     }
   3105 
   3106     mScript = new char[len + 1];
   3107     if ( !mScript ) {
   3108         fclose(fh);
   3109         return;
   3110     }
   3111 
   3112     fread(mScript, sizeof(char), len, fh);
   3113     mScript[len] = '\0'; // ensure null terminated;
   3114     fclose(fh);
   3115 
   3116 
   3117     char *p1;
   3118     char *p2;
   3119     p1 = p2 = mScript;
   3120 
   3121     do {
   3122         switch (*p1) {
   3123         case '\0':
   3124         case '|':
   3125             p1++;
   3126             break;
   3127         case SWITCH_CAMERA_CMD:
   3128         case RESUME_PREVIEW_CMD:
   3129         case START_PREVIEW_CMD:
   3130         case STOP_PREVIEW_CMD:
   3131         case CHANGE_PREVIEW_SIZE_CMD:
   3132         case CHANGE_PICTURE_SIZE_CMD:
   3133         case START_RECORD_CMD:
   3134         case STOP_RECORD_CMD:
   3135         case START_VIV_RECORD_CMD:
   3136         case STOP_VIV_RECORD_CMD:
   3137         case DUMP_CAPS_CMD:
   3138         case AUTOFOCUS_CMD:
   3139         case TAKEPICTURE_CMD:
   3140         case TAKEPICTURE_IN_PICTURE_CMD:
   3141         case ENABLE_PRV_CALLBACKS_CMD:
   3142         case EXIT_CMD:
   3143         case ZSL_CMD:
   3144         case DELAY:
   3145             p2 = p1;
   3146             while( (p2 != (mScript + len)) && (*p2 != '|')) {
   3147                 p2++;
   3148             }
   3149             *p2 = '\0';
   3150             if (p2 == (p1 + 1))
   3151                 mCommands.push_back(Command(
   3152                     static_cast<Interpreter::Commands_e>(*p1)));
   3153             else
   3154                 mCommands.push_back(Command(
   3155                     static_cast<Interpreter::Commands_e>(*p1), (p1 + 1)));
   3156             p1 = p2;
   3157             break;
   3158         default:
   3159             printf("Invalid cmd %c \n", *p1);
   3160             do {
   3161                 p1++;
   3162 
   3163             } while(*p1 != '|' && p1 != (mScript + len));
   3164 
   3165         }
   3166     } while(p1 != (mScript + len));
   3167     mUseScript = true;
   3168 }
   3169 
   3170 /*===========================================================================
   3171  * FUNCTION   : ~Interpreter
   3172  *
   3173  * DESCRIPTION: Interpreter destructor
   3174  *
   3175  * PARAMETERS : none
   3176  *
   3177  * RETURN     : none
   3178  *==========================================================================*/
   3179 Interpreter::~Interpreter()
   3180 {
   3181     if ( mScript )
   3182         delete[] mScript;
   3183 
   3184     mCommands.clear();
   3185 }
   3186 
   3187 /*===========================================================================
   3188  * FUNCTION        : getCommand
   3189  *
   3190  * DESCRIPTION     : Get a command from interpreter
   3191  *
   3192  * PARAMETERS      :
   3193  *   @currentCamera: Current camera context
   3194  *
   3195  * RETURN          : command
   3196  *==========================================================================*/
   3197 Interpreter::Command Interpreter::getCommand(
   3198     sp<CameraContext> currentCamera)
   3199 {
   3200     if( mUseScript ) {
   3201         return mCommands[mCmdIndex++];
   3202     } else {
   3203         currentCamera->printMenu(currentCamera);
   3204         return Interpreter::Command(
   3205             static_cast<Interpreter::Commands_e>(getchar()));
   3206     }
   3207 }
   3208 
   3209 /*===========================================================================
   3210  * FUNCTION        : TestContext
   3211  *
   3212  * DESCRIPTION     : TestContext constructor
   3213  *
   3214  * PARAMETERS      : None
   3215  *
   3216  * RETURN          : None
   3217  *==========================================================================*/
   3218 TestContext::TestContext()
   3219 {
   3220     int i = 0;
   3221     mTestRunning = false;
   3222     mInterpreter = NULL;
   3223     mViVVid.ViVIdx = 0;
   3224     mViVVid.buff_cnt = 9;
   3225     mViVVid.graphBuf = 0;
   3226     mViVVid.mappedBuff = NULL;
   3227     mViVVid.isBuffValid = false;
   3228     mViVVid.sourceCameraID = -1;
   3229     mViVVid.destinationCameraID = -1;
   3230     mPiPinUse = false;
   3231     mViVinUse = false;
   3232     mIsZSLOn = false;
   3233     memset(&mViVBuff, 0, sizeof(ViVBuff_t));
   3234 
   3235     ProcessState::self()->startThreadPool();
   3236 
   3237     do {
   3238         camera[i] = new CameraContext(i);
   3239         if ( NULL == camera[i].get() ) {
   3240             break;
   3241         }
   3242         camera[i]->setTestCtxInstance(this);
   3243 
   3244         //by default open only back camera
   3245         if (i==0) {
   3246             status_t stat = camera[i]->openCamera();
   3247             if ( NO_ERROR != stat ) {
   3248                 printf("Error encountered Openging camera id : %d\n", i);
   3249                 break;
   3250             }
   3251         }
   3252         mAvailableCameras.add(camera[i]);
   3253         i++;
   3254     } while ( i < camera[0]->getNumberOfCameras() ) ;
   3255 
   3256     if (i < camera[0]->getNumberOfCameras() ) {
   3257         for (size_t j = 0; j < mAvailableCameras.size(); j++) {
   3258             camera[j] = mAvailableCameras.itemAt(j);
   3259             camera[j]->closeCamera();
   3260             camera[j].clear();
   3261         }
   3262 
   3263         mAvailableCameras.clear();
   3264     }
   3265 }
   3266 
   3267 /*===========================================================================
   3268  * FUNCTION        : ~TestContext
   3269  *
   3270  * DESCRIPTION     : TestContext destructor
   3271  *
   3272  * PARAMETERS      : None
   3273  *
   3274  * RETURN          : None
   3275  *==========================================================================*/
   3276 TestContext::~TestContext()
   3277 {
   3278     delete mInterpreter;
   3279 
   3280     for (size_t j = 0; j < mAvailableCameras.size(); j++) {
   3281         camera[j] = mAvailableCameras.itemAt(j);
   3282         camera[j]->closeCamera();
   3283         camera[j].clear();
   3284     }
   3285 
   3286     mAvailableCameras.clear();
   3287 }
   3288 
   3289 /*===========================================================================
   3290  * FUNCTION        : GetCamerasNum
   3291  *
   3292  * DESCRIPTION     : Get the number of available cameras
   3293  *
   3294  * PARAMETERS      : None
   3295  *
   3296  * RETURN          : Number of cameras
   3297  *==========================================================================*/
   3298 size_t TestContext::GetCamerasNum()
   3299 {
   3300     return mAvailableCameras.size();
   3301 }
   3302 
   3303 /*===========================================================================
   3304  * FUNCTION        : AddScriptFromFile
   3305  *
   3306  * DESCRIPTION     : Add script from file
   3307  *
   3308  * PARAMETERS      :
   3309  *   @scriptFile   : Script file
   3310  *
   3311  * RETURN          : status_t type of status
   3312  *                   NO_ERROR  -- success
   3313  *                   none-zero failure code
   3314  *==========================================================================*/
   3315 status_t TestContext::AddScriptFromFile(const char *scriptFile)
   3316 {
   3317     mInterpreter = new Interpreter(scriptFile);
   3318     mInterpreter->setTestCtxInst(this);
   3319 
   3320     return NO_ERROR;
   3321 }
   3322 
   3323 /*===========================================================================
   3324  * FUNCTION        : releasePiPBuff
   3325  *
   3326  * DESCRIPTION     : Release video in video temp buffer
   3327  *
   3328  * PARAMETERS      : None
   3329  *
   3330  * RETURN          : None
   3331  *==========================================================================*/
   3332 void Interpreter::releasePiPBuff() {
   3333     free(mTestContext->mViVBuff.buff);
   3334     mTestContext->mViVBuff.buff = NULL;
   3335 }
   3336 
   3337 /*===========================================================================
   3338  * FUNCTION   : functionalTest
   3339  *
   3340  * DESCRIPTION: queries and executes client supplied commands for testing a
   3341  *              particular camera.
   3342  *
   3343  * PARAMETERS :
   3344  *  @availableCameras : List with all cameras supported
   3345  *
   3346  * RETURN     : status_t type of status
   3347  *              NO_ERROR  -- continue testing
   3348  *              none-zero -- quit test
   3349  *==========================================================================*/
   3350 status_t TestContext::FunctionalTest()
   3351 {
   3352     status_t stat = NO_ERROR;
   3353     const char *ZSLStr = NULL;
   3354     size_t ZSLStrSize = 0;
   3355 
   3356     assert(mAvailableCameras.size());
   3357 
   3358     if ( !mInterpreter ) {
   3359         mInterpreter = new Interpreter();
   3360         mInterpreter->setTestCtxInst(this);
   3361     }
   3362 
   3363     if (mAvailableCameras.size() == 0) {
   3364         printf("no cameras supported... exiting test app\n");
   3365     } else {
   3366         mTestRunning = true;
   3367     }
   3368 
   3369     while (mTestRunning) {
   3370         sp<CameraContext> currentCamera =
   3371             mAvailableCameras.itemAt(mCurrentCameraIndex);
   3372         Interpreter::Command command =
   3373             mInterpreter->getCommand(currentCamera);
   3374         currentCamera->enablePrintPreview();
   3375 
   3376         switch (command.cmd) {
   3377         case Interpreter::SWITCH_CAMERA_CMD:
   3378         {
   3379             mCurrentCameraIndex++;
   3380             mCurrentCameraIndex %= mAvailableCameras.size();
   3381             currentCamera = mAvailableCameras.itemAt(mCurrentCameraIndex);
   3382             stat = currentCamera->openCamera();
   3383         }
   3384             break;
   3385 
   3386         case Interpreter::RESUME_PREVIEW_CMD:
   3387         {
   3388             stat = currentCamera->resumePreview();
   3389         }
   3390             break;
   3391 
   3392         case Interpreter::START_PREVIEW_CMD:
   3393         {
   3394             stat = currentCamera->startPreview();
   3395         }
   3396             break;
   3397 
   3398         case Interpreter::STOP_PREVIEW_CMD:
   3399         {
   3400             stat = currentCamera->stopPreview();
   3401         }
   3402             break;
   3403 
   3404         case Interpreter::CHANGE_VIDEO_SIZE_CMD:
   3405         {
   3406             if ( command.arg )
   3407                 stat = currentCamera->setVideoSize(command.arg);
   3408             else
   3409                 stat = currentCamera->nextVideoSize();
   3410         }
   3411         break;
   3412 
   3413         case Interpreter::CHANGE_PREVIEW_SIZE_CMD:
   3414         {
   3415             if ( command.arg )
   3416                 stat = currentCamera->setPreviewSize(command.arg);
   3417             else
   3418                 stat = currentCamera->nextPreviewSize();
   3419         }
   3420             break;
   3421 
   3422         case Interpreter::CHANGE_PICTURE_SIZE_CMD:
   3423         {
   3424             if ( command.arg )
   3425                 stat = currentCamera->setPictureSize(command.arg);
   3426             else
   3427                 stat = currentCamera->nextPictureSize();
   3428         }
   3429             break;
   3430 
   3431         case Interpreter::DUMP_CAPS_CMD:
   3432         {
   3433             currentCamera->printSupportedParams();
   3434         }
   3435             break;
   3436 
   3437         case Interpreter::AUTOFOCUS_CMD:
   3438         {
   3439             stat = currentCamera->autoFocus();
   3440         }
   3441             break;
   3442 
   3443         case Interpreter::TAKEPICTURE_CMD:
   3444         {
   3445             stat = currentCamera->takePicture();
   3446         }
   3447             break;
   3448 
   3449         case Interpreter::TAKEPICTURE_IN_PICTURE_CMD:
   3450         {
   3451             if (mAvailableCameras.size() == 2) {
   3452                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
   3453                 for (size_t i = 0; i < mAvailableCameras.size(); i++) {
   3454                     mCurrentCameraIndex = i;
   3455                     currentCamera = mAvailableCameras.itemAt(mCurrentCameraIndex);
   3456                     currentCamera->enablePiPCapture();
   3457                     stat = currentCamera->takePicture();
   3458                 }
   3459                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
   3460             } else {
   3461                 printf("Number of available sensors should be 2\n");
   3462             }
   3463         }
   3464         break;
   3465 
   3466         case Interpreter::ENABLE_PRV_CALLBACKS_CMD:
   3467         {
   3468             stat = currentCamera->enablePreviewCallbacks();
   3469         }
   3470             break;
   3471 
   3472         case Interpreter::START_RECORD_CMD:
   3473         {
   3474             stat = currentCamera->stopPreview();
   3475             stat = currentCamera->configureRecorder();
   3476             stat = currentCamera->startPreview();
   3477             stat = currentCamera->startRecording();
   3478         }
   3479             break;
   3480 
   3481         case Interpreter::STOP_RECORD_CMD:
   3482         {
   3483             stat = currentCamera->stopRecording();
   3484 
   3485             stat = currentCamera->stopPreview();
   3486             stat = currentCamera->unconfigureRecorder();
   3487             stat = currentCamera->startPreview();
   3488         }
   3489             break;
   3490 
   3491         case Interpreter::START_VIV_RECORD_CMD:
   3492         {
   3493 
   3494             if (mAvailableCameras.size() == 2) {
   3495                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
   3496                 stat = mInterpreter->configureViVCodec();
   3497                 for ( size_t i = 0; i < mAvailableCameras.size(); i++ ) {
   3498                     mCurrentCameraIndex = i;
   3499                     currentCamera = mAvailableCameras.itemAt(
   3500                         mCurrentCameraIndex);
   3501                     stat = currentCamera->stopPreview();
   3502                     stat = currentCamera->configureViVRecording();
   3503                     stat = currentCamera->startPreview();
   3504                     stat = currentCamera->startViVRecording();
   3505                 }
   3506                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
   3507             } else {
   3508                 printf("Number of available sensors should be 2\n");
   3509             }
   3510 
   3511         }
   3512             break;
   3513 
   3514         case Interpreter::STOP_VIV_RECORD_CMD:
   3515         {
   3516             if (mAvailableCameras.size() == 2) {
   3517                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
   3518                 for ( size_t i = 0; i < mAvailableCameras.size(); i++ ) {
   3519                     mCurrentCameraIndex = i;
   3520                     currentCamera = mAvailableCameras.itemAt(
   3521                         mCurrentCameraIndex);
   3522                     stat = currentCamera->stopViVRecording();
   3523                     stat = currentCamera->stopPreview();
   3524                     stat = currentCamera->unconfigureRecorder();
   3525                     stat = currentCamera->startPreview();
   3526                 }
   3527                 stat = mInterpreter->unconfigureViVCodec();
   3528                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
   3529 
   3530                 mInterpreter->releasePiPBuff();
   3531             } else {
   3532                 printf("Number of available sensors should be 2\n");
   3533             }
   3534         }
   3535         break;
   3536 
   3537         case Interpreter::EXIT_CMD:
   3538         {
   3539             currentCamera->stopPreview();
   3540             mTestRunning = false;
   3541         }
   3542             break;
   3543 
   3544         case Interpreter::DELAY:
   3545         {
   3546             if ( command.arg ) {
   3547                 int delay = atoi(command.arg);
   3548                 if (0 < delay) {
   3549                     usleep(1000U * (unsigned int)delay);
   3550                 }
   3551             }
   3552         }
   3553             break;
   3554 
   3555         case Interpreter::ZSL_CMD:
   3556         {
   3557             currentCamera = mAvailableCameras.itemAt(
   3558                     mCurrentCameraIndex);
   3559             ZSLStr = currentCamera->getZSL();
   3560 
   3561             if (NULL != ZSLStr) {
   3562                 ZSLStrSize = strlen(ZSLStr);
   3563                 if (!strncmp(ZSLStr, "off", ZSLStrSize)) {
   3564                     currentCamera->setZSL("on");
   3565                     mIsZSLOn = true;
   3566                 } else if (!strncmp(ZSLStr, "on", ZSLStrSize)) {
   3567                     currentCamera->setZSL("off");
   3568                     mIsZSLOn = false;
   3569                 } else {
   3570                     printf("Set zsl failed!\n");
   3571                 }
   3572             } else {
   3573                 printf("zsl is NULL\n");
   3574             }
   3575         }
   3576             break;
   3577 
   3578         default:
   3579         {
   3580             currentCamera->disablePrintPreview();
   3581         }
   3582             break;
   3583         }
   3584         printf("Command status 0x%x \n", stat);
   3585     }
   3586 
   3587     return NO_ERROR;
   3588 }
   3589 
   3590 /*===========================================================================
   3591  * FUNCTION   : PiPLock
   3592  *
   3593  * DESCRIPTION: Mutex lock for PiP capture
   3594  *
   3595  * PARAMETERS : none
   3596  *
   3597  * RETURN     : none
   3598  *==========================================================================*/
   3599 void TestContext::PiPLock()
   3600 {
   3601     Mutex::Autolock l(mPiPLock);
   3602     while (mPiPinUse) {
   3603         mPiPCond.wait(mPiPLock);
   3604     }
   3605     mPiPinUse = true;
   3606 }
   3607 
   3608 /*===========================================================================
   3609  * FUNCTION   : PiPUnLock
   3610  *
   3611  * DESCRIPTION: Mutex unlock for PiP capture
   3612  *
   3613  * PARAMETERS : none
   3614  *
   3615  * RETURN     : none
   3616  *==========================================================================*/
   3617 void TestContext::PiPUnlock()
   3618 {
   3619     Mutex::Autolock l(mPiPLock);
   3620     mPiPinUse = false;
   3621     mPiPCond.signal();
   3622 }
   3623 
   3624 /*===========================================================================
   3625  * FUNCTION   : ViVLock
   3626  *
   3627  * DESCRIPTION: Mutex lock for ViV Video
   3628  *
   3629  * PARAMETERS : none
   3630  *
   3631  * RETURN     : none
   3632  *==========================================================================*/
   3633 void TestContext::ViVLock()
   3634 {
   3635     Mutex::Autolock l(mViVLock);
   3636     while (mViVinUse) {
   3637         mViVCond.wait(mViVLock);
   3638     }
   3639     mViVinUse = true;
   3640 }
   3641 
   3642 /*===========================================================================
   3643  * FUNCTION   : ViVUnlock
   3644  *
   3645  * DESCRIPTION: Mutex unlock for ViV Video
   3646  *
   3647  * PARAMETERS : none
   3648  *
   3649  * RETURN     : none
   3650  *==========================================================================*/
   3651 void TestContext::ViVUnlock()
   3652 {
   3653     Mutex::Autolock l(mViVLock);
   3654     mViVinUse = false;
   3655     mViVCond.signal();
   3656 }
   3657 
   3658 /*===========================================================================
   3659  * FUNCTION     : setViVSize
   3660  *
   3661  * DESCRIPTION  : Set video in video size
   3662  *
   3663  * PARAMETERS   :
   3664  *   @VideoSize : video size
   3665  *   @camIndex  : camera index
   3666  *
   3667  * RETURN       : none
   3668  *==========================================================================*/
   3669 void TestContext::setViVSize(Size VideoSize, int camIndex)
   3670 {
   3671     mViVVid.VideoSizes[camIndex] = VideoSize;
   3672 }
   3673 
   3674 /*===========================================================================
   3675  * FUNCTION     : main
   3676  *
   3677  * DESCRIPTION  : main function
   3678  *
   3679  * PARAMETERS   :
   3680  *   @argc      : argc
   3681  *   @argv      : argv
   3682  *
   3683  * RETURN       : int status
   3684  *==========================================================================*/
   3685 int main(int argc, char *argv[])
   3686 {
   3687     TestContext ctx;
   3688 
   3689     if (argc > 1) {
   3690         if ( ctx.AddScriptFromFile((const char *)argv[1]) ) {
   3691             printf("Could not add script file... "
   3692                 "continuing in normal menu mode! \n");
   3693         }
   3694     }
   3695 
   3696     ctx.FunctionalTest();
   3697 
   3698     return 0;
   3699 }
   3700