1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <time.h>
34 #include <semaphore.h>
35 #include <pthread.h>
36 
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/wait.h>
40 
41 #include <ui/DisplayInfo.h>
42 #include <gui/Surface.h>
43 #include <gui/SurfaceComposerClient.h>
44 #include <gui/ISurfaceComposer.h>
45 
46 #include <system/camera.h>
47 
48 #include <camera/Camera.h>
49 #include <camera/ICamera.h>
50 #include <camera/CameraParameters.h>
51 #include <media/mediarecorder.h>
52 
53 #include <utils/RefBase.h>
54 #include <utils/Mutex.h>
55 #include <utils/Condition.h>
56 #include <binder/IPCThreadState.h>
57 #include <binder/ProcessState.h>
58 #include <binder/IServiceManager.h>
59 #include <cutils/properties.h>
60 #include <cutils/memory.h>
61 #include <SkImageDecoder.h>
62 #include <SkImageEncoder.h>
63 #include <MediaCodec.h>
64 #include <OMX_IVCommon.h>
65 #include <foundation/AMessage.h>
66 #include <media/ICrypto.h>
67 #include <MediaMuxer.h>
68 #include <foundation/ABuffer.h>
69 #include <MediaErrors.h>
70 #include <gralloc_priv.h>
71 #include <math.h>
72 
73 #include "qcamera_test.h"
74 #include "cam_types.h"
75 #include "mm_camera_dbg.h"
76 
77 #define VIDEO_BUF_ALLIGN(size, allign) \
78   (((size) + (allign-1)) & (typeof(size))(~(allign-1)))
79 
80 namespace qcamera {
81 
82 using namespace android;
83 
84 int CameraContext::JpegIdx = 0;
85 int CameraContext::mPiPIdx = 0;
86 const char CameraContext::KEY_ZSL[] = "zsl";
87 
88 /*===========================================================================
89  * FUNCTION   : previewCallback
90  *
91  * DESCRIPTION: preview callback preview mesages are enabled
92  *
93  * PARAMETERS :
94  *   @mem : preview buffer
95  *
96  * RETURN     : None
97  *==========================================================================*/
previewCallback(const sp<IMemory> & mem)98 void CameraContext::previewCallback(const sp<IMemory>& mem)
99 {
100     printf("PREVIEW Callback %p", mem->pointer());
101     uint8_t *ptr = (uint8_t*) mem->pointer();
102     if (NULL != ptr) {
103         printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
104                 ptr[0],
105                 ptr[1],
106                 ptr[2],
107                 ptr[3],
108                 ptr[4],
109                 ptr[5],
110                 ptr[6],
111                 ptr[7],
112                 ptr[8],
113                 ptr[9]);
114     } else {
115         ALOGE(" no preview for NULL CB\n");
116     }
117 }
118 
119 /*===========================================================================
120  * FUNCTION   : useLock
121  *
122  * DESCRIPTION: Mutex lock for CameraContext
123  *
124  * PARAMETERS : none
125  *
126  * RETURN     : none
127  *==========================================================================*/
useLock()128 void CameraContext::useLock()
129 {
130     Mutex::Autolock l(mLock);
131     while (mInUse) {
132         mCond.wait(mLock);
133     }
134     mInUse = true;
135 }
136 
137 /*===========================================================================
138  * FUNCTION   : signalFinished
139  *
140  * DESCRIPTION: Mutex unlock CameraContext
141  *
142  * PARAMETERS : none
143  *
144  * RETURN     : none
145  *==========================================================================*/
signalFinished()146 void CameraContext::signalFinished()
147 {
148     Mutex::Autolock l(mLock);
149     mInUse = false;
150     mCond.signal();
151 }
152 
153 /*===========================================================================
154  * FUNCTION   : saveFile
155  *
156  * DESCRIPTION: helper function for saving buffers on filesystem
157  *
158  * PARAMETERS :
159  *   @mem : buffer to save to filesystem
160  *   @path: File path
161  *
162  * RETURN     : status_t type of status
163  *              NO_ERROR  -- success
164  *              none-zero failure code
165  *==========================================================================*/
saveFile(const sp<IMemory> & mem,String8 path)166 status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path)
167 {
168     unsigned char *buff = NULL;
169     ssize_t size;
170     int fd = -1;
171 
172     if (mem == NULL) {
173         return BAD_VALUE;
174     }
175 
176     fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0655);
177     if(fd < 0) {
178         printf("Unable to open file %s %s\n", path.string(), strerror(fd));
179         return -errno;
180     }
181 
182     size = (ssize_t)mem->size();
183     if (size <= 0) {
184         printf("IMemory object is of zero size\n");
185         close(fd);
186         return BAD_VALUE;
187     }
188 
189     buff = (unsigned char *)mem->pointer();
190     if (!buff) {
191         printf("Buffer pointer is invalid\n");
192         close(fd);
193         return BAD_VALUE;
194     }
195 
196     if (size != write(fd, buff, (size_t)size)) {
197         printf("Bad Write error (%d)%s\n", errno, strerror(errno));
198         close(fd);
199         return INVALID_OPERATION;
200     }
201 
202     printf("%s: buffer=%p, size=%lld stored at %s\n",
203             __FUNCTION__, buff, (long long int) size, path.string());
204 
205     if (fd >= 0)
206         close(fd);
207 
208     return NO_ERROR;
209 }
210 
211 /*===========================================================================
212  * FUNCTION   : PiPCopyToOneFile
213  *
214  * DESCRIPTION: Copy the smaller picture to the bigger one
215  *
216  * PARAMETERS :
217  *   @bitmap0 : Decoded image buffer 0
218  *   @bitmap1 : Decoded image buffer 1
219  *
220  * RETURN     : decoded picture in picture in SkBitmap
221  *==========================================================================*/
PiPCopyToOneFile(SkBitmap * bitmap0,SkBitmap * bitmap1)222 SkBitmap * CameraContext::PiPCopyToOneFile(
223     SkBitmap *bitmap0, SkBitmap *bitmap1)
224 {
225     size_t size0;
226     size_t size1;
227     SkBitmap *src;
228     SkBitmap *dst;
229     unsigned int dstOffset;
230     unsigned int srcOffset;
231 
232     if (bitmap0 == NULL || bitmap1 == NULL) {
233         ALOGE(" bitmap0 : %p, bitmap1 : %p\n",  bitmap0, bitmap1);
234         return NULL;
235     }
236 
237     size0 = bitmap0->getSize();
238     if (size0 <= 0) {
239         printf("Decoded image 0 is of zero size\n");
240         return NULL;
241     }
242 
243     size1 = bitmap1->getSize();
244         if (size1 <= 0) {
245             printf("Decoded image 1 is of zero size\n");
246             return NULL;
247         }
248 
249     if (size0 > size1) {
250         dst = bitmap0;
251         src = bitmap1;
252     } else if (size1 > size0){
253         dst = bitmap1;
254         src = bitmap0;
255     } else {
256         printf("Picture size should be with different size!\n");
257         return NULL;
258     }
259 
260     for (unsigned int i = 0; i < (unsigned int)src->height(); i++) {
261         dstOffset = i * (unsigned int)dst->width() * mfmtMultiplier;
262         srcOffset = i * (unsigned int)src->width() * mfmtMultiplier;
263         memcpy(((unsigned char *)dst->getPixels()) + dstOffset,
264                 ((unsigned char *)src->getPixels()) + srcOffset,
265                 (unsigned int)src->width() * mfmtMultiplier);
266     }
267 
268     return dst;
269 }
270 
271 /*===========================================================================
272  * FUNCTION   : decodeJPEG
273  *
274  * DESCRIPTION: decode jpeg input buffer.
275  *
276  * PARAMETERS :
277  *   @mem     : buffer to decode
278  *   @skBM    : decoded buffer
279  *
280  * RETURN     : status_t type of status
281  *              NO_ERROR  -- success
282  *              none-zero failure code
283 
284  *==========================================================================*/
decodeJPEG(const sp<IMemory> & mem,SkBitmap * skBM)285 status_t CameraContext::decodeJPEG(const sp<IMemory>& mem, SkBitmap *skBM)
286 {
287 #ifndef USE_SDK_20_OR_HIGHER
288     SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
289     const void *buff = NULL;
290     size_t size;
291 
292     buff = (const void *)mem->pointer();
293     size= mem->size();
294 
295     switch(prefConfig) {
296         case SkBitmap::kARGB_8888_Config:
297         {
298             mfmtMultiplier = 4;
299         }
300             break;
301 
302         case SkBitmap::kARGB_4444_Config:
303         {
304             mfmtMultiplier = 2;
305         }
306         break;
307 
308         case SkBitmap::kRGB_565_Config:
309         {
310             mfmtMultiplier = 2;
311         }
312         break;
313 
314         case SkBitmap::kIndex8_Config:
315         {
316             mfmtMultiplier = 4;
317         }
318         break;
319 
320         case SkBitmap::kA8_Config:
321         {
322             mfmtMultiplier = 4;
323         }
324         break;
325 
326         default:
327         {
328             mfmtMultiplier = 0;
329             printf("Decode format is not correct!\n");
330         }
331         break;
332     }
333 
334     if (SkImageDecoder::DecodeMemory(buff, size, skBM, prefConfig,
335             SkImageDecoder::kDecodePixels_Mode) == false) {
336         printf("%s():%d:: Failed during jpeg decode\n",__FUNCTION__,__LINE__);
337         return BAD_VALUE;
338     }
339 #else
340     SkColorType prefConfig = kRGBA_8888_SkColorType;
341     const void *buff = NULL;
342     size_t size;
343 
344     buff = (const void *)mem->pointer();
345     size= mem->size();
346 
347     switch(prefConfig) {
348         case kRGBA_8888_SkColorType:
349         {
350             mfmtMultiplier = 4;
351         }
352         break;
353 
354         case kBGRA_8888_SkColorType:
355         {
356             mfmtMultiplier = 4;
357         }
358         break;
359 
360         case kARGB_4444_SkColorType:
361         {
362             mfmtMultiplier = 2;
363         }
364         break;
365 
366         case kRGB_565_SkColorType:
367         {
368             mfmtMultiplier = 2;
369         }
370         break;
371 
372         case 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  *==========================================================================*/
encodeJPEG(SkWStream * stream,const SkBitmap * bitmap,String8 path)417 status_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  *==========================================================================*/
527 status_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  *==========================================================================*/
744 void 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  *==========================================================================*/
770 CameraContext::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  *==========================================================================*/
792 void 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  *==========================================================================*/
812 void 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  *==========================================================================*/
831 void 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  *==========================================================================*/
874 void 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  *==========================================================================*/
1019 void 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  *==========================================================================*/
1039 void 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  *==========================================================================*/
1190 status_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  *==========================================================================*/
1211 void *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  *==========================================================================*/
1227 void 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  *==========================================================================*/
1343 size_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  *==========================================================================*/
1374 size_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  *==========================================================================*/
1396 size_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  *==========================================================================*/
1418 size_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  *==========================================================================*/
1439 void 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  *==========================================================================*/
1508 status_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  *==========================================================================*/
1586 status_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  *==========================================================================*/
1614 CameraContext::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  *==========================================================================*/
1650 void 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  *==========================================================================*/
1665 void 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  *==========================================================================*/
1679 CameraContext::~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  *==========================================================================*/
1696 status_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  *==========================================================================*/
1774 IBinder* 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  *==========================================================================*/
1787 int 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  *==========================================================================*/
1809 status_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  *==========================================================================*/
1843 status_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  *==========================================================================*/
1961 Size 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  *==========================================================================*/
2043 status_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  *==========================================================================*/
2067 status_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  *==========================================================================*/
2090 status_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  *==========================================================================*/
2119 status_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  *==========================================================================*/
2220 status_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  *==========================================================================*/
2246 status_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  *==========================================================================*/
2271 status_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  *==========================================================================*/
2310 status_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  *==========================================================================*/
2339 status_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  *==========================================================================*/
2387 status_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  *==========================================================================*/
2409 status_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  *==========================================================================*/
2438 status_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  *==========================================================================*/
2465 status_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  *==========================================================================*/
2502 status_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  *==========================================================================*/
2556 status_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  *==========================================================================*/
2577 status_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  *==========================================================================*/
2604 status_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  *==========================================================================*/
2649 status_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  *==========================================================================*/
2678 status_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  *==========================================================================*/
2724 status_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  *==========================================================================*/
2746 status_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 
2758 using 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  *==========================================================================*/
2770 void 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  *==========================================================================*/
2848 void 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  *==========================================================================*/
2862 void 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  *==========================================================================*/
2876 void 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  *==========================================================================*/
2890 void 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  *==========================================================================*/
2904 const 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  *==========================================================================*/
2918 void 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  *==========================================================================*/
2935 status_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  *==========================================================================*/
3058 status_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  *==========================================================================*/
3084 Interpreter::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  *==========================================================================*/
3184 Interpreter::~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  *==========================================================================*/
3202 Interpreter::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  *==========================================================================*/
3223 TestContext::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  *==========================================================================*/
3281 TestContext::~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  *==========================================================================*/
3303 size_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  *==========================================================================*/
3320 status_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  *==========================================================================*/
3337 void 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  *==========================================================================*/
3355 status_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  *==========================================================================*/
3604 void 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  *==========================================================================*/
3622 void 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  *==========================================================================*/
3638 void 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  *==========================================================================*/
3656 void 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  *==========================================================================*/
3674 void 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  *==========================================================================*/
3690 int 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