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