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