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