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