• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::getInternalDisplayToken();
1513     SurfaceComposerClient::getDisplayInfo(display, &dinfo);
1514     uint32_t previewWidth, previewHeight;
1515 
1516     if ((0 >= width) || (0 >= height)) {
1517         printf("Bad preview surface size %dx%d\n", width, height);
1518         return BAD_VALUE;
1519     }
1520 
1521     if ((int)dinfo.w < width) {
1522         previewWidth = dinfo.w;
1523     } else {
1524         previewWidth = (unsigned int)width;
1525     }
1526 
1527     if ((int)dinfo.h < height) {
1528         previewHeight = dinfo.h;
1529     } else {
1530         previewHeight = (unsigned int)height;
1531     }
1532 
1533     mClient = new SurfaceComposerClient();
1534 
1535     if ( NULL == mClient.get() ) {
1536         printf("Unable to establish connection to Surface Composer \n");
1537         return NO_INIT;
1538     }
1539 
1540     mSurfaceControl = mClient->createSurface(String8("QCamera_Test"),
1541                                              previewWidth,
1542                                              previewHeight,
1543                                              pixFormat,
1544                                              0);
1545     if ( NULL == mSurfaceControl.get() ) {
1546         printf("Unable to create preview surface \n");
1547         return NO_INIT;
1548     }
1549 
1550     mPreviewSurface = mSurfaceControl->getSurface();
1551     if ( NULL != mPreviewSurface.get() ) {
1552         mClient->openGlobalTransaction();
1553         ret |= mSurfaceControl->setLayer(0x7fffffff);
1554         if ( mCameraIndex == 0 )
1555             ret |= mSurfaceControl->setPosition(0, 0);
1556         else
1557             ret |= mSurfaceControl->setPosition((float)(dinfo.w - previewWidth),
1558                     (float)(dinfo.h - previewHeight));
1559 
1560         ret |= mSurfaceControl->setSize(previewWidth, previewHeight);
1561         ret |= mSurfaceControl->show();
1562         mClient->closeGlobalTransaction();
1563 
1564         if ( NO_ERROR != ret ) {
1565             printf("Preview surface configuration failed! \n");
1566         }
1567     } else {
1568         ret = NO_INIT;
1569     }
1570 
1571     return ret;
1572 }
1573 
1574 /*===========================================================================
1575  * FUNCTION   : destroyPreviewSurface
1576  *
1577  * DESCRIPTION: closes previously open preview surface
1578  *
1579  * PARAMETERS : None
1580  *
1581  * RETURN     : status_t type of status
1582  *              NO_ERROR  -- success
1583  *              none-zero failure code
1584  *==========================================================================*/
1585 status_t CameraContext::destroyPreviewSurface()
1586 {
1587     if ( NULL != mPreviewSurface.get() ) {
1588         mPreviewSurface.clear();
1589     }
1590 
1591     if ( NULL != mSurfaceControl.get() ) {
1592         mSurfaceControl->clear();
1593         mSurfaceControl.clear();
1594     }
1595 
1596     if ( NULL != mClient.get() ) {
1597         mClient->dispose();
1598         mClient.clear();
1599     }
1600 
1601     return NO_ERROR;
1602 }
1603 
1604 /*===========================================================================
1605  * FUNCTION   : CameraContext
1606  *
1607  * DESCRIPTION: camera context constructor
1608  *
1609  * PARAMETERS : None
1610  *
1611  * RETURN     : None
1612  *==========================================================================*/
1613 CameraContext::CameraContext(int cameraIndex) :
1614     mCameraIndex(cameraIndex),
1615     mResizePreview(true),
1616     mHardwareActive(false),
1617     mPreviewRunning(false),
1618     mRecordRunning(false),
1619     mVideoFd(-1),
1620     mVideoIdx(0),
1621     mRecordingHint(false),
1622     mDoPrintMenu(true),
1623     mPiPCapture(false),
1624     mfmtMultiplier(1),
1625     mSectionsRead(false),
1626     mSectionsAllocated(0),
1627     mSections(NULL),
1628     mJEXIFTmp(NULL),
1629     mHaveAll(false),
1630     mCamera(NULL),
1631     mClient(NULL),
1632     mSurfaceControl(NULL),
1633     mPreviewSurface(NULL),
1634     mInUse(false)
1635 {
1636     mRecorder = new MediaRecorder(String16("camera"));
1637 }
1638 
1639 /*===========================================================================
1640  * FUNCTION     : setTestCtxInstance
1641  *
1642  * DESCRIPTION  : Sends TestContext instance to CameraContext
1643  *
1644  * PARAMETERS   :
1645  *    @instance : TestContext instance
1646  *
1647  * RETURN     : None
1648  *==========================================================================*/
1649 void CameraContext::setTestCtxInstance(TestContext  *instance)
1650 {
1651     mInterpr = instance;
1652 }
1653 
1654 /*===========================================================================
1655  * FUNCTION     : setTestCtxInst
1656  *
1657  * DESCRIPTION  : Sends TestContext instance to Interpreter
1658  *
1659  * PARAMETERS   :
1660  *    @instance : TestContext instance
1661  *
1662  * RETURN     : None
1663  *==========================================================================*/
1664 void Interpreter::setTestCtxInst(TestContext  *instance)
1665 {
1666     mTestContext = instance;
1667 }
1668 
1669 /*===========================================================================
1670  * FUNCTION   : ~CameraContext
1671  *
1672  * DESCRIPTION: camera context destructor
1673  *
1674  * PARAMETERS : None
1675  *
1676  * RETURN     : None
1677  *==========================================================================*/
1678 CameraContext::~CameraContext()
1679 {
1680     stopPreview();
1681     closeCamera();
1682 }
1683 
1684 /*===========================================================================
1685  * FUNCTION   : openCamera
1686  *
1687  * DESCRIPTION: connects to and initializes camera
1688  *
1689  * PARAMETERS : None
1690  *
1691  * RETURN     : status_t type of status
1692  *              NO_ERROR  -- success
1693  *              none-zero failure code
1694  *==========================================================================*/
1695 status_t  CameraContext::openCamera()
1696 {
1697     useLock();
1698     const char *ZSLStr = NULL;
1699     size_t ZSLStrSize = 0;
1700 
1701     if ( NULL != mCamera.get() ) {
1702         printf("Camera already open! \n");
1703         signalFinished();
1704         return NO_ERROR;
1705     }
1706 
1707     printf("openCamera(camera_index=%d)\n", mCameraIndex);
1708 
1709 #ifndef USE_JB_MR1
1710 
1711     String16 packageName("CameraTest");
1712 
1713     mCamera = Camera::connect(mCameraIndex,
1714                               packageName,
1715                               Camera::USE_CALLING_UID);
1716 
1717 #else
1718 
1719     mCamera = Camera::connect(mCameraIndex);
1720 
1721 #endif
1722 
1723     if ( NULL == mCamera.get() ) {
1724         printf("Unable to connect to CameraService\n");
1725         signalFinished();
1726         return NO_INIT;
1727     }
1728 
1729     mParams = mCamera->getParameters();
1730     mParams.getSupportedPreviewSizes(mSupportedPreviewSizes);
1731     mParams.getSupportedPictureSizes(mSupportedPictureSizes);
1732     mParams.getSupportedVideoSizes(mSupportedVideoSizes);
1733 
1734     mCurrentPictureSizeIdx = mSupportedPictureSizes.size() / 2;
1735     mCurrentPreviewSizeIdx = mSupportedPreviewSizes.size() / 2;
1736     mCurrentVideoSizeIdx   = mSupportedVideoSizes.size() / 2;
1737 
1738     mCamera->setListener(this);
1739     mHardwareActive = true;
1740 
1741     mInterpr->setViVSize((Size) mSupportedVideoSizes.itemAt(
1742         mCurrentVideoSizeIdx),
1743         mCameraIndex);
1744 
1745     ZSLStr = mParams.get(CameraContext::KEY_ZSL);
1746     if (NULL != ZSLStr) {
1747         ZSLStrSize = strlen(ZSLStr);
1748         if (!strncmp(ZSLStr, "on", ZSLStrSize)) {
1749             mInterpr->mIsZSLOn = true;
1750         } else if (!strncmp(ZSLStr, "off", ZSLStrSize)) {
1751             mInterpr->mIsZSLOn = false;
1752         } else {
1753             printf("zsl value is not valid!\n");
1754         }
1755     } else {
1756         printf("zsl is NULL\n");
1757     }
1758 
1759     signalFinished();
1760 
1761     return NO_ERROR;
1762 }
1763 
1764 /*===========================================================================
1765  * FUNCTION   : onAsBinder
1766  *
1767  * DESCRIPTION: onAsBinder
1768  *
1769  * PARAMETERS : None
1770  *
1771  * RETURN     : Pointer to IBinder
1772  *==========================================================================*/
1773 IBinder* CameraContext::onAsBinder() {
1774     return NULL;
1775 }
1776 
1777 /*===========================================================================
1778  * FUNCTION   : getNumberOfCameras
1779  *
1780  * DESCRIPTION: returns the number of supported camera by the system
1781  *
1782  * PARAMETERS : None
1783  *
1784  * RETURN     : supported camera count
1785  *==========================================================================*/
1786 int CameraContext::getNumberOfCameras()
1787 {
1788     int ret = -1;
1789 
1790     if ( NULL != mCamera.get() ) {
1791         ret = mCamera->getNumberOfCameras();
1792     }
1793 
1794     return ret;
1795 }
1796 
1797 /*===========================================================================
1798  * FUNCTION   : closeCamera
1799  *
1800  * DESCRIPTION: closes a previously the initialized camera reference
1801  *
1802  * PARAMETERS : None
1803  *
1804  * RETURN     : status_t type of status
1805  *              NO_ERROR  -- success
1806  *              none-zero failure code
1807  *==========================================================================*/
1808 status_t CameraContext::closeCamera()
1809 {
1810     useLock();
1811     if ( NULL == mCamera.get() ) {
1812         return NO_INIT;
1813     }
1814 
1815     mCamera->disconnect();
1816     mCamera.clear();
1817 
1818     mRecorder->init();
1819     mRecorder->close();
1820     mRecorder->release();
1821     mRecorder.clear();
1822 
1823     mHardwareActive = false;
1824     mPreviewRunning = false;
1825     mRecordRunning = false;
1826 
1827     signalFinished();
1828     return NO_ERROR;
1829 }
1830 
1831 /*===========================================================================
1832  * FUNCTION   : startPreview
1833  *
1834  * DESCRIPTION: starts camera preview
1835  *
1836  * PARAMETERS : None
1837  *
1838  * RETURN     : status_t type of status
1839  *              NO_ERROR  -- success
1840  *              none-zero failure code
1841  *==========================================================================*/
1842 status_t CameraContext::startPreview()
1843 {
1844     useLock();
1845 
1846     int ret = NO_ERROR;
1847     int previewWidth, previewHeight;
1848     Size calculatedPreviewSize;
1849     Size currentPreviewSize = mSupportedPreviewSizes.itemAt(
1850         mCurrentPreviewSizeIdx);
1851     Size currentPictureSize = mSupportedPictureSizes.itemAt(
1852         mCurrentPictureSizeIdx);
1853     Size currentVideoSize   = mSupportedVideoSizes.itemAt(
1854         mCurrentVideoSizeIdx);
1855 
1856 #ifndef USE_JB_MR1
1857 
1858     sp<IGraphicBufferProducer> gbp;
1859 
1860 #endif
1861 
1862     if (!mHardwareActive ) {
1863         printf("Camera not active! \n");
1864         return NO_INIT;
1865     }
1866 
1867     if (mPreviewRunning) {
1868         printf("Preview is already running! \n");
1869         signalFinished();
1870         return NO_ERROR;
1871     }
1872 
1873     if (mResizePreview) {
1874         mPreviewRunning = false;
1875 
1876         if ( mRecordingHint ) {
1877             calculatedPreviewSize =
1878                 getPreviewSizeFromVideoSizes(currentVideoSize);
1879             previewWidth = calculatedPreviewSize.width;
1880             previewHeight = calculatedPreviewSize.height;
1881         } else {
1882             previewWidth = currentPreviewSize.width;
1883             previewHeight = currentPreviewSize.height;
1884         }
1885 
1886         ret = createPreviewSurface(previewWidth,
1887                                    previewHeight,
1888                                    HAL_PIXEL_FORMAT_YCrCb_420_SP);
1889         if (  NO_ERROR != ret ) {
1890             printf("Error while creating preview surface\n");
1891             return ret;
1892         }
1893 
1894         // set rdi mode if system prop is set for front camera
1895         if (mCameraIndex == 1) {
1896             char value[32];
1897             property_get("persist.camera.rdimode", value, "0");
1898             int rdimode = atoi(value);
1899             printf("rdi mode = %d\n", rdimode);
1900             if (rdimode == 1) {
1901                 mParams.set("rdi-mode", "enable");
1902             } else {
1903                 mParams.set("rdi-mode", "disable");
1904             }
1905         } else {
1906             mParams.set("rdi-mode", "disable");
1907         }
1908 
1909         //mParams.set("rdi-mode", "enable");
1910         mParams.set("recording-hint", "true");
1911         mParams.setPreviewSize(previewWidth, previewHeight);
1912         mParams.setPictureSize(currentPictureSize.width,
1913             currentPictureSize.height);
1914         mParams.setVideoSize(
1915             currentVideoSize.width, currentVideoSize.height);
1916 
1917         ret |= mCamera->setParameters(mParams.flatten());
1918 
1919 #ifndef USE_JB_MR1
1920 
1921         gbp = mPreviewSurface->getIGraphicBufferProducer();
1922         ret |= mCamera->setPreviewTarget(gbp);
1923 
1924 #else
1925 
1926         ret |= mCamera->setPreviewDisplay(mPreviewSurface);
1927 
1928 #endif
1929         mResizePreview = false;
1930     }
1931 
1932     if ( !mPreviewRunning ) {
1933         ret |= mCamera->startPreview();
1934         if ( NO_ERROR != ret ) {
1935             printf("Preview start failed! \n");
1936             return ret;
1937         }
1938 
1939         mPreviewRunning = true;
1940     }
1941 
1942     signalFinished();
1943 
1944     return ret;
1945 }
1946 
1947 /*===========================================================================
1948  * FUNCTION   : getPreviewSizeFromVideoSizes
1949  *
1950  * DESCRIPTION: Get the preview size from video size. Find all resolutions with
1951  *              the same aspect ratio and choose the same or the closest
1952  *              from them.
1953  *
1954  * PARAMETERS :
1955  *   @currentVideoSize: current video size
1956 
1957  *
1958  * RETURN     : PreviewSize
1959  *==========================================================================*/
1960 Size CameraContext::getPreviewSizeFromVideoSizes(Size currentVideoSize)
1961 {
1962 
1963     Size tmpPreviewSize;
1964     Size PreviewSize;
1965     Size PreviewSizes[mSupportedPreviewSizes.size()];
1966     double tolerance = 0.00001;
1967     double videoRatio;
1968     double previewRatio;
1969     size_t i = 0;
1970     size_t j = 0;
1971     int delta;
1972 
1973     // Find all the resolutions with the same aspect ratio and choose the
1974     // same or the closest resolution from them. Choose the closest resolution
1975     // in case same aspect ratio is not found
1976     if (currentVideoSize.width * currentVideoSize.height > 0 &&
1977             mSupportedPreviewSizes.size() > 0) {
1978         videoRatio = (float)currentVideoSize.width /
1979             (float)currentVideoSize.height;
1980         for (i=0; i<mSupportedPreviewSizes.size(); i++) {
1981             tmpPreviewSize = mSupportedPreviewSizes.itemAt(i);
1982             previewRatio = (float)tmpPreviewSize.width /
1983                 (float)tmpPreviewSize.height;
1984             if (fabs(videoRatio - previewRatio) < tolerance) {
1985                 PreviewSizes[j] = tmpPreviewSize;
1986                 j++;
1987             }
1988         }
1989 
1990         if ( j > 0 ) {
1991             delta = abs((currentVideoSize.width *currentVideoSize.height)-
1992                 (PreviewSizes[0].width * PreviewSizes[0].height));
1993             PreviewSize = PreviewSizes[0];
1994             for (i=0; i<j; i++) {
1995                 if(abs(currentVideoSize.width * currentVideoSize.height) -
1996                     (PreviewSizes[i].width * PreviewSizes[i].height) <
1997                     delta) {
1998                     PreviewSize = PreviewSizes[i];
1999                     delta = abs((currentVideoSize.width *
2000                         currentVideoSize.height) -
2001                         (PreviewSizes[i].width * PreviewSizes[i].height));
2002                 }
2003             }
2004         } else {
2005             // Choose the closest resolution in case same aspect ratio is
2006             // not found
2007             tmpPreviewSize = mSupportedPreviewSizes.itemAt(j);
2008             PreviewSize = tmpPreviewSize;
2009             delta = abs(
2010                     (currentVideoSize.width * currentVideoSize.height)-
2011                     (tmpPreviewSize.width * tmpPreviewSize.height));
2012             for (i=0; i<mSupportedPreviewSizes.size(); i++) {
2013                 tmpPreviewSize = mSupportedPreviewSizes.itemAt(i);
2014                 if(abs(
2015                         (currentVideoSize.width * currentVideoSize.height)-
2016                         (tmpPreviewSize.width * tmpPreviewSize.height)) <
2017                         delta) {
2018                     PreviewSize = tmpPreviewSize;
2019                     delta = abs(
2020                             (currentVideoSize.width * currentVideoSize.height)-
2021                             (tmpPreviewSize.width * tmpPreviewSize.height));
2022                 }
2023             }
2024         }
2025     } else {
2026         memset(&PreviewSize, 0, sizeof(PreviewSize));
2027     }
2028     return PreviewSize;
2029 }
2030 
2031 /*===========================================================================
2032  * FUNCTION   : autoFocus
2033  *
2034  * DESCRIPTION: Triggers autofocus
2035  *
2036  * PARAMETERS : None
2037  *
2038  * RETURN     : status_t type of status
2039  *              NO_ERROR  -- success
2040  *              none-zero failure code
2041  *==========================================================================*/
2042 status_t CameraContext::autoFocus()
2043 {
2044     useLock();
2045     status_t ret = NO_ERROR;
2046 
2047     if ( mPreviewRunning ) {
2048         ret = mCamera->autoFocus();
2049     }
2050 
2051     signalFinished();
2052     return ret;
2053 }
2054 
2055 /*===========================================================================
2056  * FUNCTION   : enablePreviewCallbacks
2057  *
2058  * DESCRIPTION: Enables preview callback messages
2059  *
2060  * PARAMETERS : None
2061  *
2062  * RETURN     : status_t type of status
2063  *              NO_ERROR  -- success
2064  *              none-zero failure code
2065  *==========================================================================*/
2066 status_t CameraContext::enablePreviewCallbacks()
2067 {
2068     useLock();
2069     if ( mHardwareActive ) {
2070         mCamera->setPreviewCallbackFlags(
2071             CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
2072     }
2073 
2074     signalFinished();
2075     return NO_ERROR;
2076 }
2077 
2078 /*===========================================================================
2079  * FUNCTION   : takePicture
2080  *
2081  * DESCRIPTION: triggers image capture
2082  *
2083  * PARAMETERS : None
2084  *
2085  * RETURN     : status_t type of status
2086  *              NO_ERROR  -- success
2087  *              none-zero failure code
2088  *==========================================================================*/
2089 status_t CameraContext::takePicture()
2090 {
2091     status_t ret = NO_ERROR;
2092     useLock();
2093     if ( mPreviewRunning ) {
2094         ret = mCamera->takePicture(
2095             CAMERA_MSG_COMPRESSED_IMAGE|
2096             CAMERA_MSG_RAW_IMAGE);
2097         if (!mRecordingHint && !mInterpr->mIsZSLOn) {
2098             mPreviewRunning = false;
2099         }
2100     } else {
2101         printf("Please resume/start the preview before taking a picture!\n");
2102     }
2103     signalFinished();
2104     return ret;
2105 }
2106 
2107 /*===========================================================================
2108  * FUNCTION   : configureRecorder
2109  *
2110  * DESCRIPTION: Configure video recorder
2111  *
2112  * PARAMETERS : None
2113  *
2114  * RETURN     : status_t type of status
2115  *              NO_ERROR  -- success
2116  *              none-zero failure code
2117  *==========================================================================*/
2118 status_t CameraContext::configureRecorder()
2119 {
2120     useLock();
2121     status_t ret = NO_ERROR;
2122 
2123     mResizePreview = true;
2124     mParams.set("recording-hint", "true");
2125     mRecordingHint = true;
2126     mCamera->setParameters(mParams.flatten());
2127 
2128     Size videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
2129     ret = mRecorder->setParameters(
2130         String8("video-param-encoding-bitrate=64000"));
2131     if ( ret != NO_ERROR ) {
2132         LOGE("Could not configure recorder (%d)", ret);
2133         return ret;
2134     }
2135 
2136     ret = mRecorder->setCamera(
2137         mCamera->remote(), mCamera->getRecordingProxy());
2138     if ( ret != NO_ERROR ) {
2139         LOGE("Could not set camera (%d)", ret);
2140         return ret;
2141     }
2142     ret = mRecorder->setVideoSource(VIDEO_SOURCE_CAMERA);
2143     if ( ret != NO_ERROR ) {
2144         LOGE("Could not set video soruce (%d)", ret);
2145         return ret;
2146     }
2147     ret = mRecorder->setAudioSource(AUDIO_SOURCE_DEFAULT);
2148     if ( ret != NO_ERROR ) {
2149         LOGE("Could not set audio source (%d)", ret);
2150         return ret;
2151     }
2152     ret = mRecorder->setOutputFormat(OUTPUT_FORMAT_DEFAULT);
2153     if ( ret != NO_ERROR ) {
2154         LOGE("Could not set output format (%d)", ret);
2155         return ret;
2156     }
2157 
2158     ret = mRecorder->setVideoEncoder(VIDEO_ENCODER_DEFAULT);
2159     if ( ret != NO_ERROR ) {
2160         LOGE("Could not set video encoder (%d)", ret);
2161         return ret;
2162     }
2163 
2164     char fileName[100];
2165 
2166     snprintf(fileName, sizeof(fileName) / sizeof(char),
2167             "/sdcard/vid_cam%d_%dx%d_%d.mpeg", mCameraIndex,
2168             videoSize.width, videoSize.height, mVideoIdx++);
2169 
2170     if ( mVideoFd < 0 ) {
2171         mVideoFd = open(fileName, O_CREAT | O_RDWR );
2172     }
2173 
2174     if ( mVideoFd < 0 ) {
2175         LOGE("Could not open video file for writing %s!", fileName);
2176         return UNKNOWN_ERROR;
2177     }
2178 
2179     ret = mRecorder->setOutputFile(mVideoFd, 0, 0);
2180     if ( ret != NO_ERROR ) {
2181         LOGE("Could not set output file (%d)", ret);
2182         return ret;
2183     }
2184 
2185     ret = mRecorder->setVideoSize(videoSize.width, videoSize.height);
2186     if ( ret  != NO_ERROR ) {
2187         LOGE("Could not set video size %dx%d", videoSize.width,
2188             videoSize.height);
2189         return ret;
2190     }
2191 
2192     ret = mRecorder->setVideoFrameRate(30);
2193     if ( ret != NO_ERROR ) {
2194         LOGE("Could not set video frame rate (%d)", ret);
2195         return ret;
2196     }
2197 
2198     ret = mRecorder->setAudioEncoder(AUDIO_ENCODER_DEFAULT);
2199     if ( ret != NO_ERROR ) {
2200         LOGE("Could not set audio encoder (%d)", ret);
2201         return ret;
2202     }
2203 
2204     signalFinished();
2205     return ret;
2206 }
2207 
2208 /*===========================================================================
2209  * FUNCTION   : unconfigureViVRecording
2210  *
2211  * DESCRIPTION: Unconfigures video in video recording
2212  *
2213  * PARAMETERS : None
2214  *
2215  * RETURN     : status_t type of status
2216  *              NO_ERROR  -- success
2217  *              none-zero failure code
2218  *==========================================================================*/
2219 status_t CameraContext::unconfigureRecorder()
2220 {
2221     useLock();
2222 
2223     if ( !mRecordRunning ) {
2224         mResizePreview = true;
2225         mParams.set("recording-hint", "false");
2226         mRecordingHint = false;
2227         mCamera->setParameters(mParams.flatten());
2228     }
2229 
2230     signalFinished();
2231     return NO_ERROR;
2232 }
2233 
2234 /*===========================================================================
2235  * FUNCTION   : configureViVRecording
2236  *
2237  * DESCRIPTION: Configures video in video recording
2238  *
2239  * PARAMETERS : None
2240  *
2241  * RETURN     : status_t type of status
2242  *              NO_ERROR  -- success
2243  *              none-zero failure code
2244  *==========================================================================*/
2245 status_t CameraContext::configureViVRecording()
2246 {
2247     status_t ret = NO_ERROR;
2248 
2249     mResizePreview = true;
2250     mParams.set("recording-hint", "true");
2251     mRecordingHint = true;
2252     mCamera->setParameters(mParams.flatten());
2253     mCamera->setRecordingProxyListener(this);
2254 
2255     signalFinished();
2256     return ret;
2257 }
2258 
2259 /*===========================================================================
2260  * FUNCTION   : startRecording
2261  *
2262  * DESCRIPTION: triggers start recording
2263  *
2264  * PARAMETERS : None
2265  *
2266  * RETURN     : status_t type of status
2267  *              NO_ERROR  -- success
2268  *              none-zero failure code
2269  *==========================================================================*/
2270 status_t CameraContext::startRecording()
2271 {
2272     useLock();
2273     status_t ret = NO_ERROR;
2274 
2275 
2276     if ( mPreviewRunning ) {
2277 
2278         mCamera->unlock();
2279 
2280         ret = mRecorder->prepare();
2281         if ( ret != NO_ERROR ) {
2282             LOGE("Could not prepare recorder");
2283             return ret;
2284         }
2285 
2286         ret = mRecorder->start();
2287         if ( ret != NO_ERROR ) {
2288             LOGE("Could not start recorder");
2289             return ret;
2290         }
2291 
2292         mRecordRunning = true;
2293     }
2294     signalFinished();
2295     return ret;
2296 }
2297 
2298 /*===========================================================================
2299  * FUNCTION   : stopRecording
2300  *
2301  * DESCRIPTION: triggers start recording
2302  *
2303  * PARAMETERS : None
2304  *
2305  * RETURN     : status_t type of status
2306  *              NO_ERROR  -- success
2307  *              none-zero failure code
2308  *==========================================================================*/
2309 status_t CameraContext::stopRecording()
2310 {
2311     useLock();
2312     status_t ret = NO_ERROR;
2313 
2314     if ( mRecordRunning ) {
2315             mRecorder->stop();
2316             close(mVideoFd);
2317             mVideoFd = -1;
2318 
2319         mRecordRunning = false;
2320     }
2321 
2322     signalFinished();
2323 
2324     return ret;
2325 }
2326 
2327 /*===========================================================================
2328  * FUNCTION   : startViVRecording
2329  *
2330  * DESCRIPTION: Starts video in video recording
2331  *
2332  * PARAMETERS : None
2333  *
2334  * RETURN     : status_t type of status
2335  *              NO_ERROR  -- success
2336  *              none-zero failure code
2337  *==========================================================================*/
2338 status_t CameraContext::startViVRecording()
2339 {
2340     useLock();
2341     status_t ret;
2342 
2343     if (mInterpr->mViVVid.VideoSizes[0].width *
2344             mInterpr->mViVVid.VideoSizes[0].height >=
2345             mInterpr->mViVVid.VideoSizes[1].width *
2346             mInterpr->mViVVid.VideoSizes[1].height) {
2347         mInterpr->mViVBuff.buffSize = calcBufferSize(
2348             mInterpr->mViVVid.VideoSizes[1].width,
2349             mInterpr->mViVVid.VideoSizes[1].height);
2350         if (mInterpr->mViVBuff.buff == NULL) {
2351             mInterpr->mViVBuff.buff =
2352                 (void *)malloc(mInterpr->mViVBuff.buffSize);
2353         }
2354         mInterpr->mViVVid.sourceCameraID = 1;
2355         mInterpr->mViVVid.destinationCameraID = 0;
2356 
2357     } else {
2358         mInterpr->mViVBuff.buffSize = calcBufferSize(
2359             mInterpr->mViVVid.VideoSizes[0].width,
2360             mInterpr->mViVVid.VideoSizes[0].height);
2361         if (mInterpr->mViVBuff.buff == NULL) {
2362             mInterpr->mViVBuff.buff =
2363                 (void *)malloc(mInterpr->mViVBuff.buffSize);
2364         }
2365         mInterpr->mViVVid.sourceCameraID = 0;
2366         mInterpr->mViVVid.destinationCameraID = 1;
2367     }
2368 
2369     ret = mCamera->startRecording();
2370 
2371     signalFinished();
2372     return ret;
2373 }
2374 
2375 /*===========================================================================
2376  * FUNCTION   : stopViVRecording
2377  *
2378  * DESCRIPTION: Stops video in video recording
2379  *
2380  * PARAMETERS : None
2381  *
2382  * RETURN     : status_t type of status
2383  *              NO_ERROR  -- success
2384  *              none-zero failure code
2385  *==========================================================================*/
2386 status_t CameraContext::stopViVRecording()
2387 {
2388     useLock();
2389     status_t ret = NO_ERROR;
2390 
2391     mCamera->stopRecording();
2392 
2393     signalFinished();
2394     return ret;
2395 }
2396 
2397 /*===========================================================================
2398  * FUNCTION   : stopPreview
2399  *
2400  * DESCRIPTION: stops camera preview
2401  *
2402  * PARAMETERS : None
2403  *
2404  * RETURN     : status_t type of status
2405  *              NO_ERROR  -- success
2406  *              none-zero failure code
2407  *==========================================================================*/
2408 status_t CameraContext::stopPreview()
2409 {
2410     useLock();
2411     status_t ret = NO_ERROR;
2412 
2413     if ( mHardwareActive ) {
2414         mCamera->stopPreview();
2415         ret = destroyPreviewSurface();
2416     }
2417 
2418     mPreviewRunning  = false;
2419     mResizePreview = true;
2420 
2421     signalFinished();
2422 
2423     return ret;
2424 }
2425 
2426 /*===========================================================================
2427  * FUNCTION   : resumePreview
2428  *
2429  * DESCRIPTION: resumes camera preview after image capture
2430  *
2431  * PARAMETERS : None
2432  *
2433  * RETURN     : status_t type of status
2434  *              NO_ERROR  -- success
2435  *              none-zero failure code
2436  *==========================================================================*/
2437 status_t CameraContext::resumePreview()
2438 {
2439     useLock();
2440     status_t ret = NO_ERROR;
2441 
2442     if ( mHardwareActive ) {
2443         ret = mCamera->startPreview();
2444         mPreviewRunning = true;
2445     } else {
2446         ret = NO_INIT;
2447     }
2448 
2449     signalFinished();
2450     return ret;
2451 }
2452 
2453 /*===========================================================================
2454  * FUNCTION   : nextPreviewSize
2455  *
2456  * DESCRIPTION: Iterates through all supported preview sizes.
2457  *
2458  * PARAMETERS : None
2459  *
2460  * RETURN     : status_t type of status
2461  *              NO_ERROR  -- success
2462  *              none-zero failure code
2463  *==========================================================================*/
2464 status_t CameraContext::nextPreviewSize()
2465 {
2466     useLock();
2467     if ( mHardwareActive ) {
2468         mCurrentPreviewSizeIdx += 1;
2469         mCurrentPreviewSizeIdx %= mSupportedPreviewSizes.size();
2470         Size previewSize = mSupportedPreviewSizes.itemAt(
2471             mCurrentPreviewSizeIdx);
2472         mParams.setPreviewSize(previewSize.width,
2473                                previewSize.height);
2474         mResizePreview = true;
2475 
2476         if ( mPreviewRunning ) {
2477             mCamera->stopPreview();
2478             mCamera->setParameters(mParams.flatten());
2479             mCamera->startPreview();
2480         } else {
2481             mCamera->setParameters(mParams.flatten());
2482         }
2483     }
2484 
2485     signalFinished();
2486     return NO_ERROR;
2487 }
2488 
2489 
2490 /*===========================================================================
2491  * FUNCTION   : setPreviewSize
2492  *
2493  * DESCRIPTION: Sets exact preview size if supported
2494  *
2495  * PARAMETERS : format size in the form of WIDTHxHEIGHT
2496  *
2497  * RETURN     : status_t type of status
2498  *              NO_ERROR  -- success
2499  *              none-zero failure code
2500  *==========================================================================*/
2501 status_t CameraContext::setPreviewSize(const char *format)
2502 {
2503     useLock();
2504     if ( mHardwareActive ) {
2505         int newHeight;
2506         int newWidth;
2507         sscanf(format, "%dx%d", &newWidth, &newHeight);
2508 
2509         unsigned int i;
2510         for (i = 0; i < mSupportedPreviewSizes.size(); ++i) {
2511             Size previewSize = mSupportedPreviewSizes.itemAt(i);
2512             if ( newWidth == previewSize.width &&
2513                  newHeight == previewSize.height )
2514             {
2515                 break;
2516             }
2517 
2518         }
2519         if ( i == mSupportedPreviewSizes.size())
2520         {
2521             printf("Preview size %dx%d not supported !\n",
2522                 newWidth, newHeight);
2523             return INVALID_OPERATION;
2524         }
2525 
2526         mParams.setPreviewSize(newWidth,
2527                                newHeight);
2528         mResizePreview = true;
2529 
2530         if ( mPreviewRunning ) {
2531             mCamera->stopPreview();
2532             mCamera->setParameters(mParams.flatten());
2533             mCamera->startPreview();
2534         } else {
2535             mCamera->setParameters(mParams.flatten());
2536         }
2537     }
2538 
2539     signalFinished();
2540     return NO_ERROR;
2541 }
2542 
2543 /*===========================================================================
2544  * FUNCTION   : getCurrentPreviewSize
2545  *
2546  * DESCRIPTION: queries the currently configured preview size
2547  *
2548  * PARAMETERS :
2549  *  @previewSize : preview size currently configured
2550  *
2551  * RETURN     : status_t type of status
2552  *              NO_ERROR  -- success
2553  *              none-zero failure code
2554  *==========================================================================*/
2555 status_t CameraContext::getCurrentPreviewSize(Size &previewSize)
2556 {
2557     useLock();
2558     if ( mHardwareActive ) {
2559         previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
2560     }
2561     signalFinished();
2562     return NO_ERROR;
2563 }
2564 
2565 /*===========================================================================
2566  * FUNCTION   : nextPictureSize
2567  *
2568  * DESCRIPTION: Iterates through all supported picture sizes.
2569  *
2570  * PARAMETERS : None
2571  *
2572  * RETURN     : status_t type of status
2573  *              NO_ERROR  -- success
2574  *              none-zero failure code
2575  *==========================================================================*/
2576 status_t CameraContext::nextPictureSize()
2577 {
2578     useLock();
2579     if ( mHardwareActive ) {
2580         mCurrentPictureSizeIdx += 1;
2581         mCurrentPictureSizeIdx %= mSupportedPictureSizes.size();
2582         Size pictureSize = mSupportedPictureSizes.itemAt(
2583             mCurrentPictureSizeIdx);
2584         mParams.setPictureSize(pictureSize.width,
2585             pictureSize.height);
2586         mCamera->setParameters(mParams.flatten());
2587     }
2588     signalFinished();
2589     return NO_ERROR;
2590 }
2591 
2592 /*===========================================================================
2593  * FUNCTION   : setPictureSize
2594  *
2595  * DESCRIPTION: Sets exact preview size if supported
2596  *
2597  * PARAMETERS : format size in the form of WIDTHxHEIGHT
2598  *
2599  * RETURN     : status_t type of status
2600  *              NO_ERROR  -- success
2601  *              none-zero failure code
2602  *==========================================================================*/
2603 status_t CameraContext::setPictureSize(const char *format)
2604 {
2605     useLock();
2606     if ( mHardwareActive ) {
2607         int newHeight;
2608         int newWidth;
2609         sscanf(format, "%dx%d", &newWidth, &newHeight);
2610 
2611         unsigned int i;
2612         for (i = 0; i < mSupportedPictureSizes.size(); ++i) {
2613             Size PictureSize = mSupportedPictureSizes.itemAt(i);
2614             if ( newWidth == PictureSize.width &&
2615                  newHeight == PictureSize.height )
2616             {
2617                 break;
2618             }
2619 
2620         }
2621         if ( i == mSupportedPictureSizes.size())
2622         {
2623             printf("Preview size %dx%d not supported !\n",
2624                 newWidth, newHeight);
2625             return INVALID_OPERATION;
2626         }
2627 
2628         mParams.setPictureSize(newWidth,
2629                                newHeight);
2630         mCamera->setParameters(mParams.flatten());
2631     }
2632 
2633     signalFinished();
2634     return NO_ERROR;
2635 }
2636 
2637 /*===========================================================================
2638  * FUNCTION   : nextVideoSize
2639  *
2640  * DESCRIPTION: Select the next available video size
2641  *
2642  * PARAMETERS : none
2643  *
2644  * RETURN     : status_t type of status
2645  *              NO_ERROR  -- success
2646  *              none-zero failure code
2647  *==========================================================================*/
2648 status_t CameraContext::nextVideoSize()
2649 {
2650     useLock();
2651     if ( mHardwareActive ) {
2652         mCurrentVideoSizeIdx += 1;
2653         mCurrentVideoSizeIdx %= mSupportedVideoSizes.size();
2654         Size videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
2655         mParams.setVideoSize(videoSize.width,
2656                              videoSize.height);
2657         mCamera->setParameters(mParams.flatten());
2658         mInterpr->setViVSize((Size) mSupportedVideoSizes.itemAt(
2659             mCurrentVideoSizeIdx), mCameraIndex);
2660     }
2661     signalFinished();
2662     return NO_ERROR;
2663 }
2664 
2665 /*===========================================================================
2666  * FUNCTION   : setVideoSize
2667  *
2668  * DESCRIPTION: Set video size
2669  *
2670  * PARAMETERS :
2671  *   @format  : format
2672  *
2673  * RETURN     : status_t type of status
2674  *              NO_ERROR  -- success
2675  *              none-zero failure code
2676  *==========================================================================*/
2677 status_t CameraContext::setVideoSize(const char *format)
2678 {
2679     useLock();
2680     if ( mHardwareActive ) {
2681         int newHeight;
2682         int newWidth;
2683         sscanf(format, "%dx%d", &newWidth, &newHeight);
2684 
2685         unsigned int i;
2686         for (i = 0; i < mSupportedVideoSizes.size(); ++i) {
2687             Size PictureSize = mSupportedVideoSizes.itemAt(i);
2688             if ( newWidth == PictureSize.width &&
2689                  newHeight == PictureSize.height )
2690             {
2691                 break;
2692             }
2693 
2694         }
2695         if ( i == mSupportedVideoSizes.size())
2696         {
2697             printf("Preview size %dx%d not supported !\n",
2698                 newWidth, newHeight);
2699             return INVALID_OPERATION;
2700         }
2701 
2702         mParams.setVideoSize(newWidth,
2703                              newHeight);
2704         mCamera->setParameters(mParams.flatten());
2705     }
2706 
2707     signalFinished();
2708     return NO_ERROR;
2709 }
2710 
2711 /*===========================================================================
2712  * FUNCTION    : getCurrentVideoSize
2713  *
2714  * DESCRIPTION : Get current video size
2715  *
2716  * PARAMETERS  :
2717  *   @videoSize: video Size
2718  *
2719  * RETURN      : status_t type of status
2720  *               NO_ERROR  -- success
2721  *               none-zero failure code
2722  *==========================================================================*/
2723 status_t CameraContext::getCurrentVideoSize(Size &videoSize)
2724 {
2725     useLock();
2726     if ( mHardwareActive ) {
2727         videoSize = mSupportedVideoSizes.itemAt(mCurrentVideoSizeIdx);
2728     }
2729     signalFinished();
2730     return NO_ERROR;
2731 }
2732 
2733 /*===========================================================================
2734  * FUNCTION   : getCurrentPictureSize
2735  *
2736  * DESCRIPTION: queries the currently configured picture size
2737  *
2738  * PARAMETERS :
2739  *  @pictureSize : picture size currently configured
2740  *
2741  * RETURN     : status_t type of status
2742  *              NO_ERROR  -- success
2743  *              none-zero failure code
2744  *==========================================================================*/
2745 status_t CameraContext::getCurrentPictureSize(Size &pictureSize)
2746 {
2747     useLock();
2748     if ( mHardwareActive ) {
2749         pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
2750     }
2751     signalFinished();
2752     return NO_ERROR;
2753 }
2754 
2755 }; //namespace qcamera ends here
2756 
2757 using namespace qcamera;
2758 
2759 /*===========================================================================
2760  * FUNCTION   : printMenu
2761  *
2762  * DESCRIPTION: prints the available camera options
2763  *
2764  * PARAMETERS :
2765  *  @currentCamera : camera context currently being used
2766  *
2767  * RETURN     : None
2768  *==========================================================================*/
2769 void CameraContext::printMenu(sp<CameraContext> currentCamera)
2770 {
2771     if ( !mDoPrintMenu ) return;
2772     Size currentPictureSize, currentPreviewSize, currentVideoSize;
2773     const char *zsl_mode = mParams.get(CameraContext::KEY_ZSL);
2774 
2775     assert(currentCamera.get());
2776 
2777     currentCamera->getCurrentPictureSize(currentPictureSize);
2778     currentCamera->getCurrentPreviewSize(currentPreviewSize);
2779     currentCamera->getCurrentVideoSize(currentVideoSize);
2780 
2781     printf("\n\n=========== FUNCTIONAL TEST MENU ===================\n\n");
2782 
2783     printf(" \n\nSTART / STOP / GENERAL SERVICES \n");
2784     printf(" -----------------------------\n");
2785     printf("   %c. Switch camera - Current Index: %d\n",
2786             Interpreter::SWITCH_CAMERA_CMD,
2787             currentCamera->getCameraIndex());
2788     printf("   %c. Resume Preview after capture \n",
2789             Interpreter::RESUME_PREVIEW_CMD);
2790     printf("   %c. Quit \n",
2791             Interpreter::EXIT_CMD);
2792     printf("   %c. Camera Capability Dump",
2793             Interpreter::DUMP_CAPS_CMD);
2794 
2795     printf(" \n\n PREVIEW SUB MENU \n");
2796     printf(" -----------------------------\n");
2797     printf("   %c. Start Preview\n",
2798             Interpreter::START_PREVIEW_CMD);
2799     printf("   %c. Stop Preview\n",
2800             Interpreter::STOP_PREVIEW_CMD);
2801     printf("   %c. Preview size:  %dx%d\n",
2802             Interpreter::CHANGE_PREVIEW_SIZE_CMD,
2803             currentPreviewSize.width,
2804             currentPreviewSize.height);
2805     printf("   %c. Video size:  %dx%d\n",
2806             Interpreter::CHANGE_VIDEO_SIZE_CMD,
2807             currentVideoSize.width,
2808             currentVideoSize.height);
2809     printf("   %c. Start Recording\n",
2810             Interpreter::START_RECORD_CMD);
2811     printf("   %c. Stop Recording\n",
2812             Interpreter::STOP_RECORD_CMD);
2813     printf("   %c. Start ViV Recording\n",
2814             Interpreter::START_VIV_RECORD_CMD);
2815     printf("   %c. Stop ViV Recording\n",
2816             Interpreter::STOP_VIV_RECORD_CMD);
2817     printf("   %c. Enable preview frames\n",
2818             Interpreter::ENABLE_PRV_CALLBACKS_CMD);
2819     printf("   %c. Trigger autofocus \n",
2820             Interpreter::AUTOFOCUS_CMD);
2821 
2822     printf(" \n\n IMAGE CAPTURE SUB MENU \n");
2823     printf(" -----------------------------\n");
2824     printf("   %c. Take picture/Full Press\n",
2825             Interpreter::TAKEPICTURE_CMD);
2826     printf("   %c. Take picture in picture\n",
2827             Interpreter::TAKEPICTURE_IN_PICTURE_CMD);
2828     printf("   %c. Picture size:  %dx%d\n",
2829             Interpreter::CHANGE_PICTURE_SIZE_CMD,
2830             currentPictureSize.width,
2831             currentPictureSize.height);
2832     printf("   %c. zsl:  %s\n", Interpreter::ZSL_CMD,
2833         (zsl_mode != NULL) ? zsl_mode : "NULL");
2834 
2835     printf("\n   Choice: ");
2836 }
2837 
2838 /*===========================================================================
2839  * FUNCTION   : enablePrintPreview
2840  *
2841  * DESCRIPTION: Enables printing the preview
2842  *
2843  * PARAMETERS : None
2844  *
2845  * RETURN     : None
2846  *==========================================================================*/
2847 void CameraContext::enablePrintPreview()
2848 {
2849     mDoPrintMenu = true;
2850 }
2851 
2852 /*===========================================================================
2853  * FUNCTION   : disablePrintPreview
2854  *
2855  * DESCRIPTION: Disables printing the preview
2856  *
2857  * PARAMETERS : None
2858  *
2859  * RETURN     : None
2860  *==========================================================================*/
2861 void CameraContext::disablePrintPreview()
2862 {
2863     mDoPrintMenu = false;
2864 }
2865 
2866 /*===========================================================================
2867  * FUNCTION   : enablePiPCapture
2868  *
2869  * DESCRIPTION: Enables picture in picture capture
2870  *
2871  * PARAMETERS : None
2872  *
2873  * RETURN     : None
2874  *==========================================================================*/
2875 void CameraContext::enablePiPCapture()
2876 {
2877     mPiPCapture = true;
2878 }
2879 
2880 /*===========================================================================
2881  * FUNCTION   : disablePiPCapture
2882  *
2883  * DESCRIPTION: Disables picture in picture capture
2884  *
2885  * PARAMETERS : None
2886  *
2887  * RETURN     : None
2888  *==========================================================================*/
2889 void CameraContext::disablePiPCapture()
2890 {
2891     mPiPCapture = false;
2892 }
2893 
2894 /*===========================================================================
2895  * FUNCTION   : getZSL
2896  *
2897  * DESCRIPTION: get ZSL value of current camera
2898  *
2899  * PARAMETERS : None
2900  *
2901  * RETURN     : current zsl value
2902  *==========================================================================*/
2903 const char *CameraContext::getZSL()
2904 {
2905     return mParams.get(CameraContext::KEY_ZSL);
2906 }
2907 
2908 /*===========================================================================
2909  * FUNCTION   : setZSL
2910  *
2911  * DESCRIPTION: set ZSL value of current camera
2912  *
2913  * PARAMETERS : zsl value to be set
2914  *
2915  * RETURN     : None
2916  *==========================================================================*/
2917 void CameraContext::setZSL(const char *value)
2918 {
2919     mParams.set(CameraContext::KEY_ZSL, value);
2920     mCamera->setParameters(mParams.flatten());
2921 }
2922 
2923 /*===========================================================================
2924  * FUNCTION   : configureViVCodec
2925  *
2926  * DESCRIPTION: Configures video in video codec
2927  *
2928  * PARAMETERS : none
2929  *
2930  * RETURN     : status_t type of status
2931  *              NO_ERROR  -- success
2932  *              none-zero failure code
2933  *==========================================================================*/
2934 status_t Interpreter::configureViVCodec()
2935 {
2936     status_t ret = NO_ERROR;
2937     char fileName[100];
2938     sp<AMessage> format = new AMessage;
2939     sp<ALooper> looper = new ALooper;
2940 
2941     if (mTestContext->mViVVid.VideoSizes[0].width *
2942             mTestContext->mViVVid.VideoSizes[0].height >=
2943             mTestContext->mViVVid.VideoSizes[1].width *
2944             mTestContext->mViVVid.VideoSizes[1].height) {
2945         snprintf(fileName, sizeof(fileName) / sizeof(char), "/sdcard/ViV_vid_%dx%d_%d.mp4",
2946             mTestContext->mViVVid.VideoSizes[0].width,
2947             mTestContext->mViVVid.VideoSizes[0].height,
2948             mTestContext->mViVVid.ViVIdx++);
2949         format->setInt32("width", mTestContext->mViVVid.VideoSizes[0].width);
2950         format->setInt32("height", mTestContext->mViVVid.VideoSizes[0].height);
2951     } else {
2952         snprintf(fileName, sizeof(fileName) / sizeof(char), "/sdcard/ViV_vid_%dx%d_%d.mp4",
2953             mTestContext->mViVVid.VideoSizes[1].width,
2954             mTestContext->mViVVid.VideoSizes[1].height,
2955             mTestContext->mViVVid.ViVIdx++);
2956         format->setInt32("width", mTestContext->mViVVid.VideoSizes[1].width);
2957         format->setInt32("height", mTestContext->mViVVid.VideoSizes[1].height);
2958     }
2959     int fd = open(fileName, O_CREAT | O_RDWR );
2960     if (fd < 0) {
2961         LOGE("Error opening file");
2962         return UNKNOWN_ERROR;
2963     }
2964     mTestContext->mViVVid.muxer = new MediaMuxer(
2965         fd, MediaMuxer::OUTPUT_FORMAT_MPEG_4);
2966 
2967     format->setString("mime", "video/avc");
2968     format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
2969 
2970     format->setInt32("bitrate", 1000000);
2971     format->setFloat("frame-rate", 30);
2972     format->setInt32("i-frame-interval", 10);
2973 
2974     looper->setName("ViV_recording_looper");
2975     looper->start();
2976     ALOGV("Creating codec");
2977     mTestContext->mViVVid.codec = MediaCodec::CreateByType(
2978         looper, "video/avc", true);
2979     if (mTestContext->mViVVid.codec == NULL) {
2980         fprintf(stderr, "ERROR: unable to create video/avc codec instance\n");
2981         return UNKNOWN_ERROR;
2982     }
2983     ret = mTestContext->mViVVid.codec->configure(format, NULL, NULL,
2984             MediaCodec::CONFIGURE_FLAG_ENCODE);
2985     if (ret != NO_ERROR) {
2986         mTestContext->mViVVid.codec->release();
2987         mTestContext->mViVVid.codec.clear();
2988 
2989         fprintf(stderr, "ERROR: unable to configure codec (err=%d)\n", ret);
2990         return ret;
2991     }
2992 
2993     ALOGV("Creating buffer producer");
2994     ret = mTestContext->mViVVid.codec->createInputSurface(
2995         &mTestContext->mViVVid.bufferProducer);
2996     if (ret != NO_ERROR) {
2997         mTestContext->mViVVid.codec->release();
2998         mTestContext->mViVVid.codec.clear();
2999 
3000         fprintf(stderr,
3001             "ERROR: unable to create encoder input surface (err=%d)\n", ret);
3002         return ret;
3003     }
3004 
3005     ret = mTestContext->mViVVid.codec->start();
3006     if (ret != NO_ERROR) {
3007         mTestContext->mViVVid.codec->release();
3008         mTestContext->mViVVid.codec.clear();
3009 
3010         fprintf(stderr, "ERROR: unable to start codec (err=%d)\n", ret);
3011         return ret;
3012     }
3013     ALOGV("Codec prepared");
3014 
3015     mTestContext->mViVVid.surface = new Surface(
3016         mTestContext->mViVVid.bufferProducer);
3017     mTestContext->mViVVid.ANW = mTestContext->mViVVid.surface;
3018     ret = native_window_api_connect(mTestContext->mViVVid.ANW.get(),
3019         NATIVE_WINDOW_API_CPU);
3020     if (mTestContext->mViVVid.VideoSizes[0].width *
3021         mTestContext->mViVVid.VideoSizes[0].height >=
3022         mTestContext->mViVVid.VideoSizes[1].width *
3023         mTestContext->mViVVid.VideoSizes[1].height) {
3024         native_window_set_buffers_format(mTestContext->mViVVid.ANW.get(),
3025                 HAL_PIXEL_FORMAT_NV12_ENCODEABLE);
3026         native_window_set_buffers_dimensions(mTestContext->mViVVid.ANW.get(),
3027                 mTestContext->mViVVid.VideoSizes[0].width,
3028                 mTestContext->mViVVid.VideoSizes[0].height);
3029     } else {
3030         native_window_set_buffers_format(mTestContext->mViVVid.ANW.get(),
3031                 HAL_PIXEL_FORMAT_NV12_ENCODEABLE);
3032         native_window_set_buffers_dimensions(mTestContext->mViVVid.ANW.get(),
3033                 mTestContext->mViVVid.VideoSizes[1].width,
3034                 mTestContext->mViVVid.VideoSizes[1].height);
3035     }
3036     native_window_set_usage(mTestContext->mViVVid.ANW.get(),
3037         GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
3038     native_window_set_buffer_count(mTestContext->mViVVid.ANW.get(),
3039         mTestContext->mViVVid.buff_cnt);
3040 
3041     ViVEncoderThread();
3042 
3043     return ret;
3044 }
3045 
3046 /*===========================================================================
3047  * FUNCTION   : unconfigureViVCodec
3048  *
3049  * DESCRIPTION: Unconfigures video in video codec
3050  *
3051  * PARAMETERS : none
3052  *
3053  * RETURN     : status_t type of status
3054  *              NO_ERROR  -- success
3055  *              none-zero failure code
3056  *==========================================================================*/
3057 status_t Interpreter::unconfigureViVCodec()
3058 {
3059     status_t ret = NO_ERROR;
3060 
3061     ret = native_window_api_disconnect(mTestContext->mViVVid.ANW.get(),
3062         NATIVE_WINDOW_API_CPU);
3063     mTestContext->mViVVid.bufferProducer = NULL;
3064     mTestContext->mViVVid.codec->stop();
3065     pthread_join(mViVEncThread, NULL);
3066     mTestContext->mViVVid.muxer->stop();
3067     mTestContext->mViVVid.codec->release();
3068     mTestContext->mViVVid.codec.clear();
3069     mTestContext->mViVVid.muxer.clear();
3070     mTestContext->mViVVid.surface.clear();
3071   return ret;
3072 }
3073 
3074 /*===========================================================================
3075  * FUNCTION   : Interpreter
3076  *
3077  * DESCRIPTION: Interpreter constructor
3078  *
3079  * PARAMETERS : none
3080  *
3081  * RETURN     : none
3082  *==========================================================================*/
3083 Interpreter::Interpreter(const char *file)
3084     : mCmdIndex(0)
3085     , mScript(NULL)
3086 {
3087     if (!file){
3088         printf("no File Given\n");
3089         mUseScript = false;
3090         return;
3091     }
3092 
3093     FILE *fh = fopen(file, "r");
3094     if ( !fh ) {
3095         printf("Could not open file %s\n", file);
3096         mUseScript = false;
3097         return;
3098     }
3099 
3100     fseek(fh, 0, SEEK_END);
3101     size_t len = (size_t)ftell(fh);
3102     rewind(fh);
3103 
3104     if( !len ) {
3105         printf("Script file %s is empty !\n", file);
3106         fclose(fh);
3107         return;
3108     }
3109 
3110     mScript = new char[len + 1];
3111     if ( !mScript ) {
3112         fclose(fh);
3113         return;
3114     }
3115 
3116     fread(mScript, sizeof(char), len, fh);
3117     mScript[len] = '\0'; // ensure null terminated;
3118     fclose(fh);
3119 
3120 
3121     char *p1;
3122     char *p2;
3123     p1 = p2 = mScript;
3124 
3125     do {
3126         switch (*p1) {
3127         case '\0':
3128         case '|':
3129             p1++;
3130             break;
3131         case SWITCH_CAMERA_CMD:
3132         case RESUME_PREVIEW_CMD:
3133         case START_PREVIEW_CMD:
3134         case STOP_PREVIEW_CMD:
3135         case CHANGE_PREVIEW_SIZE_CMD:
3136         case CHANGE_PICTURE_SIZE_CMD:
3137         case START_RECORD_CMD:
3138         case STOP_RECORD_CMD:
3139         case START_VIV_RECORD_CMD:
3140         case STOP_VIV_RECORD_CMD:
3141         case DUMP_CAPS_CMD:
3142         case AUTOFOCUS_CMD:
3143         case TAKEPICTURE_CMD:
3144         case TAKEPICTURE_IN_PICTURE_CMD:
3145         case ENABLE_PRV_CALLBACKS_CMD:
3146         case EXIT_CMD:
3147         case ZSL_CMD:
3148         case DELAY:
3149             p2 = p1;
3150             while( (p2 != (mScript + len)) && (*p2 != '|')) {
3151                 p2++;
3152             }
3153             *p2 = '\0';
3154             if (p2 == (p1 + 1))
3155                 mCommands.push_back(Command(
3156                     static_cast<Interpreter::Commands_e>(*p1)));
3157             else
3158                 mCommands.push_back(Command(
3159                     static_cast<Interpreter::Commands_e>(*p1), (p1 + 1)));
3160             p1 = p2;
3161             break;
3162         default:
3163             printf("Invalid cmd %c \n", *p1);
3164             do {
3165                 p1++;
3166 
3167             } while(*p1 != '|' && p1 != (mScript + len));
3168 
3169         }
3170     } while(p1 != (mScript + len));
3171     mUseScript = true;
3172 }
3173 
3174 /*===========================================================================
3175  * FUNCTION   : ~Interpreter
3176  *
3177  * DESCRIPTION: Interpreter destructor
3178  *
3179  * PARAMETERS : none
3180  *
3181  * RETURN     : none
3182  *==========================================================================*/
3183 Interpreter::~Interpreter()
3184 {
3185     if ( mScript )
3186         delete[] mScript;
3187 
3188     mCommands.clear();
3189 }
3190 
3191 /*===========================================================================
3192  * FUNCTION        : getCommand
3193  *
3194  * DESCRIPTION     : Get a command from interpreter
3195  *
3196  * PARAMETERS      :
3197  *   @currentCamera: Current camera context
3198  *
3199  * RETURN          : command
3200  *==========================================================================*/
3201 Interpreter::Command Interpreter::getCommand(
3202     sp<CameraContext> currentCamera)
3203 {
3204     if( mUseScript ) {
3205         return mCommands[mCmdIndex++];
3206     } else {
3207         currentCamera->printMenu(currentCamera);
3208         return Interpreter::Command(
3209             static_cast<Interpreter::Commands_e>(getchar()));
3210     }
3211 }
3212 
3213 /*===========================================================================
3214  * FUNCTION        : TestContext
3215  *
3216  * DESCRIPTION     : TestContext constructor
3217  *
3218  * PARAMETERS      : None
3219  *
3220  * RETURN          : None
3221  *==========================================================================*/
3222 TestContext::TestContext()
3223 {
3224     int i = 0;
3225     mTestRunning = false;
3226     mInterpreter = NULL;
3227     mViVVid.ViVIdx = 0;
3228     mViVVid.buff_cnt = 9;
3229     mViVVid.graphBuf = 0;
3230     mViVVid.mappedBuff = NULL;
3231     mViVVid.isBuffValid = false;
3232     mViVVid.sourceCameraID = -1;
3233     mViVVid.destinationCameraID = -1;
3234     mPiPinUse = false;
3235     mViVinUse = false;
3236     mIsZSLOn = false;
3237     memset(&mViVBuff, 0, sizeof(ViVBuff_t));
3238 
3239     ProcessState::self()->startThreadPool();
3240 
3241     do {
3242         camera[i] = new CameraContext(i);
3243         if ( NULL == camera[i].get() ) {
3244             break;
3245         }
3246         camera[i]->setTestCtxInstance(this);
3247 
3248         //by default open only back camera
3249         if (i==0) {
3250             status_t stat = camera[i]->openCamera();
3251             if ( NO_ERROR != stat ) {
3252                 printf("Error encountered Openging camera id : %d\n", i);
3253                 break;
3254             }
3255         }
3256         mAvailableCameras.add(camera[i]);
3257         i++;
3258     } while ( i < camera[0]->getNumberOfCameras() ) ;
3259 
3260     if (i < camera[0]->getNumberOfCameras() ) {
3261         for (size_t j = 0; j < mAvailableCameras.size(); j++) {
3262             camera[j] = mAvailableCameras.itemAt(j);
3263             camera[j]->closeCamera();
3264             camera[j].clear();
3265         }
3266 
3267         mAvailableCameras.clear();
3268     }
3269 }
3270 
3271 /*===========================================================================
3272  * FUNCTION        : ~TestContext
3273  *
3274  * DESCRIPTION     : TestContext destructor
3275  *
3276  * PARAMETERS      : None
3277  *
3278  * RETURN          : None
3279  *==========================================================================*/
3280 TestContext::~TestContext()
3281 {
3282     delete mInterpreter;
3283 
3284     for (size_t j = 0; j < mAvailableCameras.size(); j++) {
3285         camera[j] = mAvailableCameras.itemAt(j);
3286         camera[j]->closeCamera();
3287         camera[j].clear();
3288     }
3289 
3290     mAvailableCameras.clear();
3291 }
3292 
3293 /*===========================================================================
3294  * FUNCTION        : GetCamerasNum
3295  *
3296  * DESCRIPTION     : Get the number of available cameras
3297  *
3298  * PARAMETERS      : None
3299  *
3300  * RETURN          : Number of cameras
3301  *==========================================================================*/
3302 size_t TestContext::GetCamerasNum()
3303 {
3304     return mAvailableCameras.size();
3305 }
3306 
3307 /*===========================================================================
3308  * FUNCTION        : AddScriptFromFile
3309  *
3310  * DESCRIPTION     : Add script from file
3311  *
3312  * PARAMETERS      :
3313  *   @scriptFile   : Script file
3314  *
3315  * RETURN          : status_t type of status
3316  *                   NO_ERROR  -- success
3317  *                   none-zero failure code
3318  *==========================================================================*/
3319 status_t TestContext::AddScriptFromFile(const char *scriptFile)
3320 {
3321     mInterpreter = new Interpreter(scriptFile);
3322     mInterpreter->setTestCtxInst(this);
3323 
3324     return NO_ERROR;
3325 }
3326 
3327 /*===========================================================================
3328  * FUNCTION        : releasePiPBuff
3329  *
3330  * DESCRIPTION     : Release video in video temp buffer
3331  *
3332  * PARAMETERS      : None
3333  *
3334  * RETURN          : None
3335  *==========================================================================*/
3336 void Interpreter::releasePiPBuff() {
3337     free(mTestContext->mViVBuff.buff);
3338     mTestContext->mViVBuff.buff = NULL;
3339 }
3340 
3341 /*===========================================================================
3342  * FUNCTION   : functionalTest
3343  *
3344  * DESCRIPTION: queries and executes client supplied commands for testing a
3345  *              particular camera.
3346  *
3347  * PARAMETERS :
3348  *  @availableCameras : List with all cameras supported
3349  *
3350  * RETURN     : status_t type of status
3351  *              NO_ERROR  -- continue testing
3352  *              none-zero -- quit test
3353  *==========================================================================*/
3354 status_t TestContext::FunctionalTest()
3355 {
3356     status_t stat = NO_ERROR;
3357     const char *ZSLStr = NULL;
3358     size_t ZSLStrSize = 0;
3359 
3360     assert(mAvailableCameras.size());
3361 
3362     if ( !mInterpreter ) {
3363         mInterpreter = new Interpreter();
3364         mInterpreter->setTestCtxInst(this);
3365     }
3366 
3367     if (mAvailableCameras.size() == 0) {
3368         printf("no cameras supported... exiting test app\n");
3369     } else {
3370         mTestRunning = true;
3371     }
3372 
3373     while (mTestRunning) {
3374         sp<CameraContext> currentCamera =
3375             mAvailableCameras.itemAt(mCurrentCameraIndex);
3376         Interpreter::Command command =
3377             mInterpreter->getCommand(currentCamera);
3378         currentCamera->enablePrintPreview();
3379 
3380         switch (command.cmd) {
3381         case Interpreter::SWITCH_CAMERA_CMD:
3382         {
3383             mCurrentCameraIndex++;
3384             mCurrentCameraIndex %= mAvailableCameras.size();
3385             currentCamera = mAvailableCameras.itemAt(mCurrentCameraIndex);
3386             stat = currentCamera->openCamera();
3387         }
3388             break;
3389 
3390         case Interpreter::RESUME_PREVIEW_CMD:
3391         {
3392             stat = currentCamera->resumePreview();
3393         }
3394             break;
3395 
3396         case Interpreter::START_PREVIEW_CMD:
3397         {
3398             stat = currentCamera->startPreview();
3399         }
3400             break;
3401 
3402         case Interpreter::STOP_PREVIEW_CMD:
3403         {
3404             stat = currentCamera->stopPreview();
3405         }
3406             break;
3407 
3408         case Interpreter::CHANGE_VIDEO_SIZE_CMD:
3409         {
3410             if ( command.arg )
3411                 stat = currentCamera->setVideoSize(command.arg);
3412             else
3413                 stat = currentCamera->nextVideoSize();
3414         }
3415         break;
3416 
3417         case Interpreter::CHANGE_PREVIEW_SIZE_CMD:
3418         {
3419             if ( command.arg )
3420                 stat = currentCamera->setPreviewSize(command.arg);
3421             else
3422                 stat = currentCamera->nextPreviewSize();
3423         }
3424             break;
3425 
3426         case Interpreter::CHANGE_PICTURE_SIZE_CMD:
3427         {
3428             if ( command.arg )
3429                 stat = currentCamera->setPictureSize(command.arg);
3430             else
3431                 stat = currentCamera->nextPictureSize();
3432         }
3433             break;
3434 
3435         case Interpreter::DUMP_CAPS_CMD:
3436         {
3437             currentCamera->printSupportedParams();
3438         }
3439             break;
3440 
3441         case Interpreter::AUTOFOCUS_CMD:
3442         {
3443             stat = currentCamera->autoFocus();
3444         }
3445             break;
3446 
3447         case Interpreter::TAKEPICTURE_CMD:
3448         {
3449             stat = currentCamera->takePicture();
3450         }
3451             break;
3452 
3453         case Interpreter::TAKEPICTURE_IN_PICTURE_CMD:
3454         {
3455             if (mAvailableCameras.size() == 2) {
3456                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
3457                 for (size_t i = 0; i < mAvailableCameras.size(); i++) {
3458                     mCurrentCameraIndex = i;
3459                     currentCamera = mAvailableCameras.itemAt(mCurrentCameraIndex);
3460                     currentCamera->enablePiPCapture();
3461                     stat = currentCamera->takePicture();
3462                 }
3463                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
3464             } else {
3465                 printf("Number of available sensors should be 2\n");
3466             }
3467         }
3468         break;
3469 
3470         case Interpreter::ENABLE_PRV_CALLBACKS_CMD:
3471         {
3472             stat = currentCamera->enablePreviewCallbacks();
3473         }
3474             break;
3475 
3476         case Interpreter::START_RECORD_CMD:
3477         {
3478             stat = currentCamera->stopPreview();
3479             stat = currentCamera->configureRecorder();
3480             stat = currentCamera->startPreview();
3481             stat = currentCamera->startRecording();
3482         }
3483             break;
3484 
3485         case Interpreter::STOP_RECORD_CMD:
3486         {
3487             stat = currentCamera->stopRecording();
3488 
3489             stat = currentCamera->stopPreview();
3490             stat = currentCamera->unconfigureRecorder();
3491             stat = currentCamera->startPreview();
3492         }
3493             break;
3494 
3495         case Interpreter::START_VIV_RECORD_CMD:
3496         {
3497 
3498             if (mAvailableCameras.size() == 2) {
3499                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
3500                 stat = mInterpreter->configureViVCodec();
3501                 for ( size_t i = 0; i < mAvailableCameras.size(); i++ ) {
3502                     mCurrentCameraIndex = i;
3503                     currentCamera = mAvailableCameras.itemAt(
3504                         mCurrentCameraIndex);
3505                     stat = currentCamera->stopPreview();
3506                     stat = currentCamera->configureViVRecording();
3507                     stat = currentCamera->startPreview();
3508                     stat = currentCamera->startViVRecording();
3509                 }
3510                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
3511             } else {
3512                 printf("Number of available sensors should be 2\n");
3513             }
3514 
3515         }
3516             break;
3517 
3518         case Interpreter::STOP_VIV_RECORD_CMD:
3519         {
3520             if (mAvailableCameras.size() == 2) {
3521                 mSaveCurrentCameraIndex = mCurrentCameraIndex;
3522                 for ( size_t i = 0; i < mAvailableCameras.size(); i++ ) {
3523                     mCurrentCameraIndex = i;
3524                     currentCamera = mAvailableCameras.itemAt(
3525                         mCurrentCameraIndex);
3526                     stat = currentCamera->stopViVRecording();
3527                     stat = currentCamera->stopPreview();
3528                     stat = currentCamera->unconfigureRecorder();
3529                     stat = currentCamera->startPreview();
3530                 }
3531                 stat = mInterpreter->unconfigureViVCodec();
3532                 mCurrentCameraIndex = mSaveCurrentCameraIndex;
3533 
3534                 mInterpreter->releasePiPBuff();
3535             } else {
3536                 printf("Number of available sensors should be 2\n");
3537             }
3538         }
3539         break;
3540 
3541         case Interpreter::EXIT_CMD:
3542         {
3543             currentCamera->stopPreview();
3544             mTestRunning = false;
3545         }
3546             break;
3547 
3548         case Interpreter::DELAY:
3549         {
3550             if ( command.arg ) {
3551                 int delay = atoi(command.arg);
3552                 if (0 < delay) {
3553                     usleep(1000U * (unsigned int)delay);
3554                 }
3555             }
3556         }
3557             break;
3558 
3559         case Interpreter::ZSL_CMD:
3560         {
3561             currentCamera = mAvailableCameras.itemAt(
3562                     mCurrentCameraIndex);
3563             ZSLStr = currentCamera->getZSL();
3564 
3565             if (NULL != ZSLStr) {
3566                 ZSLStrSize = strlen(ZSLStr);
3567                 if (!strncmp(ZSLStr, "off", ZSLStrSize)) {
3568                     currentCamera->setZSL("on");
3569                     mIsZSLOn = true;
3570                 } else if (!strncmp(ZSLStr, "on", ZSLStrSize)) {
3571                     currentCamera->setZSL("off");
3572                     mIsZSLOn = false;
3573                 } else {
3574                     printf("Set zsl failed!\n");
3575                 }
3576             } else {
3577                 printf("zsl is NULL\n");
3578             }
3579         }
3580             break;
3581 
3582         default:
3583         {
3584             currentCamera->disablePrintPreview();
3585         }
3586             break;
3587         }
3588         printf("Command status 0x%x \n", stat);
3589     }
3590 
3591     return NO_ERROR;
3592 }
3593 
3594 /*===========================================================================
3595  * FUNCTION   : PiPLock
3596  *
3597  * DESCRIPTION: Mutex lock for PiP capture
3598  *
3599  * PARAMETERS : none
3600  *
3601  * RETURN     : none
3602  *==========================================================================*/
3603 void TestContext::PiPLock()
3604 {
3605     Mutex::Autolock l(mPiPLock);
3606     while (mPiPinUse) {
3607         mPiPCond.wait(mPiPLock);
3608     }
3609     mPiPinUse = true;
3610 }
3611 
3612 /*===========================================================================
3613  * FUNCTION   : PiPUnLock
3614  *
3615  * DESCRIPTION: Mutex unlock for PiP capture
3616  *
3617  * PARAMETERS : none
3618  *
3619  * RETURN     : none
3620  *==========================================================================*/
3621 void TestContext::PiPUnlock()
3622 {
3623     Mutex::Autolock l(mPiPLock);
3624     mPiPinUse = false;
3625     mPiPCond.signal();
3626 }
3627 
3628 /*===========================================================================
3629  * FUNCTION   : ViVLock
3630  *
3631  * DESCRIPTION: Mutex lock for ViV Video
3632  *
3633  * PARAMETERS : none
3634  *
3635  * RETURN     : none
3636  *==========================================================================*/
3637 void TestContext::ViVLock()
3638 {
3639     Mutex::Autolock l(mViVLock);
3640     while (mViVinUse) {
3641         mViVCond.wait(mViVLock);
3642     }
3643     mViVinUse = true;
3644 }
3645 
3646 /*===========================================================================
3647  * FUNCTION   : ViVUnlock
3648  *
3649  * DESCRIPTION: Mutex unlock for ViV Video
3650  *
3651  * PARAMETERS : none
3652  *
3653  * RETURN     : none
3654  *==========================================================================*/
3655 void TestContext::ViVUnlock()
3656 {
3657     Mutex::Autolock l(mViVLock);
3658     mViVinUse = false;
3659     mViVCond.signal();
3660 }
3661 
3662 /*===========================================================================
3663  * FUNCTION     : setViVSize
3664  *
3665  * DESCRIPTION  : Set video in video size
3666  *
3667  * PARAMETERS   :
3668  *   @VideoSize : video size
3669  *   @camIndex  : camera index
3670  *
3671  * RETURN       : none
3672  *==========================================================================*/
3673 void TestContext::setViVSize(Size VideoSize, int camIndex)
3674 {
3675     mViVVid.VideoSizes[camIndex] = VideoSize;
3676 }
3677 
3678 /*===========================================================================
3679  * FUNCTION     : main
3680  *
3681  * DESCRIPTION  : main function
3682  *
3683  * PARAMETERS   :
3684  *   @argc      : argc
3685  *   @argv      : argv
3686  *
3687  * RETURN       : int status
3688  *==========================================================================*/
3689 int main(int argc, char *argv[])
3690 {
3691     TestContext ctx;
3692 
3693     if (argc > 1) {
3694         if ( ctx.AddScriptFromFile((const char *)argv[1]) ) {
3695             printf("Could not add script file... "
3696                 "continuing in normal menu mode! \n");
3697         }
3698     }
3699 
3700     ctx.FunctionalTest();
3701 
3702     return 0;
3703 }
3704