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