1 /*
2  * Copyright (C) Texas Instruments - http://www.ti.com/
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifdef OMAP_ENHANCEMENT_CPCAM
18 
19 #include "BufferSourceAdapter.h"
20 #include <ui/GraphicBuffer.h>
21 #include <ui/GraphicBufferMapper.h>
22 #include <hal_public.h>
23 
24 namespace Ti {
25 namespace Camera {
26 
getANWFormat(const char * parameters_format)27 static int getANWFormat(const char* parameters_format)
28 {
29     int format = HAL_PIXEL_FORMAT_TI_NV12;
30 
31     if (parameters_format != NULL) {
32         if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
33             CAMHAL_LOGDA("CbYCrY format selected");
34             format = HAL_PIXEL_FORMAT_TI_UYVY;
35         } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
36             CAMHAL_LOGDA("YUV420SP format selected");
37             format = HAL_PIXEL_FORMAT_TI_NV12;
38         } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
39             CAMHAL_LOGDA("RGB565 format selected");
40             // TODO(XXX): not defined yet
41             format = -1;
42         } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
43             format = HAL_PIXEL_FORMAT_TI_Y16;
44         } else {
45             CAMHAL_LOGDA("Invalid format, NV12 format selected as default");
46             format = HAL_PIXEL_FORMAT_TI_NV12;
47         }
48     }
49 
50     return format;
51 }
52 
getUsageFromANW(int format)53 static int getUsageFromANW(int format)
54 {
55     int usage = GRALLOC_USAGE_SW_READ_RARELY |
56                 GRALLOC_USAGE_SW_WRITE_NEVER;
57 
58     switch (format) {
59         case HAL_PIXEL_FORMAT_TI_NV12:
60         case HAL_PIXEL_FORMAT_TI_Y16:
61             // This usage flag indicates to gralloc we want the
62             // buffers to come from system heap
63             usage |= GRALLOC_USAGE_PRIVATE_0;
64             break;
65         default:
66             // No special flags needed
67             break;
68     }
69     return usage;
70 }
71 
getFormatFromANW(int format)72 static const char* getFormatFromANW(int format)
73 {
74     switch (format) {
75         case HAL_PIXEL_FORMAT_TI_NV12:
76             // Assuming NV12 1D is RAW or Image frame
77             return android::CameraParameters::PIXEL_FORMAT_YUV420SP;
78         case HAL_PIXEL_FORMAT_TI_Y16:
79             return android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
80         case HAL_PIXEL_FORMAT_TI_UYVY:
81             return android::CameraParameters::PIXEL_FORMAT_YUV422I;
82         default:
83             break;
84     }
85     return android::CameraParameters::PIXEL_FORMAT_YUV420SP;
86 }
87 
formatToOutputFrameType(const char * format)88 static CameraFrame::FrameType formatToOutputFrameType(const char* format) {
89     switch (getANWFormat(format)) {
90         case HAL_PIXEL_FORMAT_TI_NV12:
91         case HAL_PIXEL_FORMAT_TI_Y16:
92         case HAL_PIXEL_FORMAT_TI_UYVY:
93             // Assuming NV12 1D is RAW or Image frame
94             return CameraFrame::RAW_FRAME;
95         default:
96             break;
97     }
98     return CameraFrame::RAW_FRAME;
99 }
100 
getHeightFromFormat(const char * format,int stride,int size)101 static int getHeightFromFormat(const char* format, int stride, int size) {
102     CAMHAL_ASSERT((NULL != format) && (0 <= stride) && (0 <= size));
103     switch (getANWFormat(format)) {
104         case HAL_PIXEL_FORMAT_TI_NV12:
105             return (size / (3 * stride)) * 2;
106         case HAL_PIXEL_FORMAT_TI_Y16:
107         case HAL_PIXEL_FORMAT_TI_UYVY:
108             return (size / stride) / 2;
109         default:
110             break;
111     }
112     return 0;
113 }
114 
115 /*--------------------BufferSourceAdapter Class STARTS here-----------------------------*/
116 
117 
118 ///Constant definitions
119 // TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
120 // until faux-NPA mode is implemented
121 const int BufferSourceAdapter::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15;
122 
123 /**
124  * Display Adapter class STARTS here..
125  */
BufferSourceAdapter()126 BufferSourceAdapter::BufferSourceAdapter() : mBufferCount(0)
127 {
128     LOG_FUNCTION_NAME;
129 
130     mPixelFormat = NULL;
131     mBuffers = NULL;
132     mFrameProvider = NULL;
133     mBufferSource = NULL;
134 
135     mFrameWidth = 0;
136     mFrameHeight = 0;
137     mPreviewWidth = 0;
138     mPreviewHeight = 0;
139 
140     LOG_FUNCTION_NAME_EXIT;
141 }
142 
~BufferSourceAdapter()143 BufferSourceAdapter::~BufferSourceAdapter()
144 {
145     LOG_FUNCTION_NAME;
146 
147     freeBufferList(mBuffers);
148 
149     android::AutoMutex lock(mLock);
150 
151     destroy();
152 
153     if (mFrameProvider) {
154         // Unregister with the frame provider
155         mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
156         delete mFrameProvider;
157         mFrameProvider = NULL;
158     }
159 
160     if (mQueueFrame.get()) {
161         mQueueFrame->requestExit();
162         mQueueFrame.clear();
163     }
164 
165     if (mReturnFrame.get()) {
166         mReturnFrame->requestExit();
167         mReturnFrame.clear();
168     }
169 
170     LOG_FUNCTION_NAME_EXIT;
171 }
172 
initialize()173 status_t BufferSourceAdapter::initialize()
174 {
175     status_t ret = NO_ERROR;
176 
177     LOG_FUNCTION_NAME;
178 
179     mReturnFrame.clear();
180     mReturnFrame = new ReturnFrame(this);
181     mReturnFrame->run();
182 
183     mQueueFrame.clear();
184     mQueueFrame = new QueueFrame(this);
185     mQueueFrame->run();
186 
187     LOG_FUNCTION_NAME_EXIT;
188 
189     return ret;
190 }
191 
setPreviewWindow(preview_stream_ops_t * source)192 int BufferSourceAdapter::setPreviewWindow(preview_stream_ops_t *source)
193 {
194     LOG_FUNCTION_NAME;
195 
196     if (!source) {
197         CAMHAL_LOGEA("NULL window object passed to DisplayAdapter");
198         LOG_FUNCTION_NAME_EXIT;
199         return BAD_VALUE;
200     }
201 
202     if (mBufferSource) {
203         char id1[OP_STR_SIZE], id2[OP_STR_SIZE];
204         status_t ret;
205 
206         ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1));
207         if (ret != 0) {
208             CAMHAL_LOGE("Surface::getId returned error %d", ret);
209             return ret;
210         }
211 
212         ret = extendedOps()->get_id(source, id2, sizeof(id2));
213         if (ret != 0) {
214             CAMHAL_LOGE("Surface::getId returned error %d", ret);
215             return ret;
216         }
217         if ((0 >= strlen(id1)) || (0 >= strlen(id2))) {
218             CAMHAL_LOGE("Cannot set ST without name: id1:\"%s\" id2:\"%s\"",
219                         id1, id2);
220             return NOT_ENOUGH_DATA;
221         }
222         if (0 == strcmp(id1, id2)) {
223             return ALREADY_EXISTS;
224         }
225 
226         // client has to unset mBufferSource before being able to set a new one
227         return BAD_VALUE;
228     }
229 
230     // Move to new source obj
231     mBufferSource = source;
232 
233     LOG_FUNCTION_NAME_EXIT;
234 
235     return NO_ERROR;
236 }
237 
match(const char * str)238 bool BufferSourceAdapter::match(const char * str) {
239     char id1[OP_STR_SIZE];
240     status_t ret;
241 
242     ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1));
243 
244     if (ret != 0) {
245         CAMHAL_LOGE("Surface::getId returned error %d", ret);
246     }
247 
248     return strcmp(id1, str) == 0;
249 }
250 
setFrameProvider(FrameNotifier * frameProvider)251 int BufferSourceAdapter::setFrameProvider(FrameNotifier *frameProvider)
252 {
253     LOG_FUNCTION_NAME;
254 
255     if ( !frameProvider ) {
256         CAMHAL_LOGEA("NULL passed for frame provider");
257         LOG_FUNCTION_NAME_EXIT;
258         return BAD_VALUE;
259     }
260 
261     if ( NULL != mFrameProvider ) {
262         delete mFrameProvider;
263     }
264 
265     mFrameProvider = new FrameProvider(frameProvider, this, frameCallback);
266 
267     LOG_FUNCTION_NAME_EXIT;
268 
269     return NO_ERROR;
270 }
271 
setErrorHandler(ErrorNotifier * errorNotifier)272 int BufferSourceAdapter::setErrorHandler(ErrorNotifier *errorNotifier)
273 {
274     status_t ret = NO_ERROR;
275 
276     LOG_FUNCTION_NAME;
277 
278     if ( NULL == errorNotifier ) {
279         CAMHAL_LOGEA("Invalid Error Notifier reference");
280         return -EINVAL;
281     }
282 
283     mErrorNotifier = errorNotifier;
284 
285     LOG_FUNCTION_NAME_EXIT;
286 
287     return ret;
288 }
289 
enableDisplay(int width,int height,struct timeval * refTime)290 int BufferSourceAdapter::enableDisplay(int width, int height,
291                                        struct timeval *refTime)
292 {
293     LOG_FUNCTION_NAME;
294     CameraFrame::FrameType frameType;
295 
296     if (mFrameProvider == NULL) {
297         // no-op frame provider not set yet
298         return NO_ERROR;
299     }
300 
301     if (mBufferSourceDirection == BUFFER_SOURCE_TAP_IN) {
302         // only supporting one type of input frame
303         frameType = CameraFrame::REPROCESS_INPUT_FRAME;
304     } else {
305         frameType = formatToOutputFrameType(mPixelFormat);
306     }
307 
308     mFrameProvider->enableFrameNotification(frameType);
309     LOG_FUNCTION_NAME_EXIT;
310 
311     return NO_ERROR;
312 }
313 
disableDisplay(bool cancel_buffer)314 int BufferSourceAdapter::disableDisplay(bool cancel_buffer)
315 {
316     LOG_FUNCTION_NAME;
317 
318     if (mFrameProvider) mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
319 
320     LOG_FUNCTION_NAME_EXIT;
321 
322     return NO_ERROR;
323 }
324 
pauseDisplay(bool pause)325 status_t BufferSourceAdapter::pauseDisplay(bool pause)
326 {
327     status_t ret = NO_ERROR;
328 
329     LOG_FUNCTION_NAME;
330 
331     // no-op for BufferSourceAdapter
332 
333     LOG_FUNCTION_NAME_EXIT;
334 
335     return ret;
336 }
337 
338 
destroy()339 void BufferSourceAdapter::destroy()
340 {
341     LOG_FUNCTION_NAME;
342 
343     mBufferCount = 0;
344 
345     LOG_FUNCTION_NAME_EXIT;
346 }
347 
allocateBufferList(int width,int dummyHeight,const char * format,int & bytes,int numBufs)348 CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight, const char* format,
349                                                       int &bytes, int numBufs)
350 {
351     LOG_FUNCTION_NAME;
352     status_t err;
353     int i = -1;
354     const int lnumBufs = numBufs;
355     int undequeued = 0;
356     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
357 
358     mBuffers = new CameraBuffer [lnumBufs];
359     memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
360 
361     if ( NULL == mBufferSource ) {
362         return NULL;
363     }
364 
365     int pixFormat = getANWFormat(format);
366     int usage = getUsageFromANW(pixFormat);
367     mPixelFormat = CameraHal::getPixelFormatConstant(format);
368 
369     // Set gralloc usage bits for window.
370     err = mBufferSource->set_usage(mBufferSource, usage);
371     if (err != 0) {
372         CAMHAL_LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
373 
374         if ( ENODEV == err ) {
375             CAMHAL_LOGEA("Preview surface abandoned!");
376             mBufferSource = NULL;
377         }
378 
379         return NULL;
380     }
381 
382     CAMHAL_LOGDB("Number of buffers set to BufferSourceAdapter %d", numBufs);
383     // Set the number of buffers needed for this buffer source
384     err = mBufferSource->set_buffer_count(mBufferSource, numBufs);
385     if (err != 0) {
386         CAMHAL_LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
387 
388         if ( ENODEV == err ) {
389             CAMHAL_LOGEA("Preview surface abandoned!");
390             mBufferSource = NULL;
391         }
392 
393         return NULL;
394     }
395 
396     CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs);
397     mBufferCount = numBufs;
398 
399     // re-calculate height depending on stride and size
400     int height = getHeightFromFormat(format, width, bytes);
401 
402     // Set window geometry
403     err = mBufferSource->set_buffers_geometry(mBufferSource,
404                                               width, height,
405                                               pixFormat);
406 
407     if (err != 0) {
408         CAMHAL_LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err);
409         if ( ENODEV == err ) {
410             CAMHAL_LOGEA("Preview surface abandoned!");
411             mBufferSource = NULL;
412         }
413         return NULL;
414     }
415 
416     if ( mBuffers == NULL ) {
417         CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers");
418         LOG_FUNCTION_NAME_EXIT;
419         return NULL;
420     }
421 
422     mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued);
423 
424     for (i = 0; i < mBufferCount; i++ ) {
425         buffer_handle_t *handle;
426         int stride;  // dummy variable to get stride
427         // TODO(XXX): Do we need to keep stride information in camera hal?
428 
429         err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride);
430 
431         if (err != 0) {
432             CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
433             if ( ENODEV == err ) {
434                 CAMHAL_LOGEA("Preview surface abandoned!");
435                 mBufferSource = NULL;
436             }
437             goto fail;
438         }
439 
440         CAMHAL_LOGDB("got handle %p", handle);
441         mBuffers[i].opaque = (void *)handle;
442         mBuffers[i].type = CAMERA_BUFFER_ANW;
443         mBuffers[i].format = mPixelFormat;
444         mFramesWithCameraAdapterMap.add(handle, i);
445 
446         bytes = CameraHal::calculateBufferSize(format, width, height);
447     }
448 
449     for( i = 0;  i < mBufferCount-undequeued; i++ ) {
450         void *y_uv[2];
451         android::Rect bounds(width, height);
452 
453         buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
454         mBufferSource->lock_buffer(mBufferSource, handle);
455         mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
456         mBuffers[i].mapped = y_uv[0];
457     }
458 
459     // return the rest of the buffers back to ANativeWindow
460     for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++) {
461         buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
462         void *y_uv[2];
463         android::Rect bounds(width, height);
464 
465         mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
466         mBuffers[i].mapped = y_uv[0];
467         mapper.unlock(*handle);
468 
469         err = mBufferSource->cancel_buffer(mBufferSource, handle);
470         if (err != 0) {
471             CAMHAL_LOGEB("cancel_buffer failed: %s (%d)", strerror(-err), -err);
472             if ( ENODEV == err ) {
473                 CAMHAL_LOGEA("Preview surface abandoned!");
474                 mBufferSource = NULL;
475             }
476             goto fail;
477         }
478         mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque);
479     }
480 
481     mFrameWidth = width;
482     mFrameHeight = height;
483     mBufferSourceDirection = BUFFER_SOURCE_TAP_OUT;
484 
485     return mBuffers;
486 
487  fail:
488     // need to cancel buffers if any were dequeued
489     for (int start = 0; start < i && i > 0; start++) {
490         int err = mBufferSource->cancel_buffer(mBufferSource,
491                 (buffer_handle_t *) mBuffers[start].opaque);
492         if (err != 0) {
493           CAMHAL_LOGEB("cancelBuffer failed w/ error 0x%08x", err);
494           break;
495         }
496         mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[start].opaque);
497     }
498 
499     freeBufferList(mBuffers);
500 
501     CAMHAL_LOGEA("Error occurred, performing cleanup");
502 
503     if (NULL != mErrorNotifier.get()) {
504         mErrorNotifier->errorNotify(-ENOMEM);
505     }
506 
507     LOG_FUNCTION_NAME_EXIT;
508     return NULL;
509 
510 }
511 
getBuffers(bool reset)512 CameraBuffer *BufferSourceAdapter::getBuffers(bool reset) {
513     int undequeued = 0;
514     status_t err;
515     android::Mutex::Autolock lock(mLock);
516 
517     if (!mBufferSource || !mBuffers) {
518         CAMHAL_LOGE("Adapter is not set up properly: "
519                     "mBufferSource:%p mBuffers:%p",
520                      mBufferSource, mBuffers);
521         goto fail;
522     }
523 
524     // CameraHal is indicating to us that the state of the mBuffer
525     // might have changed. We might need to check the state of the
526     // buffer list and pass a new one depending on the state of our
527     // surface
528     if (reset) {
529         const int lnumBufs = mBufferCount;
530         android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
531         android::Rect bounds(mFrameWidth, mFrameHeight);
532         void *y_uv[2];
533         CameraBuffer * newBuffers = NULL;
534         unsigned int index = 0;
535         android::KeyedVector<void*, int> missingIndices;
536 
537         newBuffers = new CameraBuffer [lnumBufs];
538         memset (newBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
539 
540         // Use this vector to figure out missing indices
541         for (int i = 0; i < mBufferCount; i++) {
542             missingIndices.add(mBuffers[i].opaque, i);
543         }
544 
545         // assign buffers that we have already dequeued
546         for (index = 0; index < mFramesWithCameraAdapterMap.size(); index++) {
547             int value = mFramesWithCameraAdapterMap.valueAt(index);
548             newBuffers[index].opaque = mBuffers[value].opaque;
549             newBuffers[index].type = mBuffers[value].type;
550             newBuffers[index].format = mBuffers[value].format;
551             newBuffers[index].mapped = mBuffers[value].mapped;
552             mFramesWithCameraAdapterMap.replaceValueAt(index, index);
553             missingIndices.removeItem(newBuffers[index].opaque);
554         }
555 
556         mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued);
557 
558         // dequeue the rest of the buffers
559         for (index; index < (unsigned int)(mBufferCount-undequeued); index++) {
560             buffer_handle_t *handle;
561             int stride;  // dummy variable to get stride
562 
563             err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride);
564             if (err != 0) {
565                 CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
566                 if ( ENODEV == err ) {
567                     CAMHAL_LOGEA("Preview surface abandoned!");
568                     mBufferSource = NULL;
569                 }
570                 goto fail;
571             }
572             newBuffers[index].opaque = (void *)handle;
573             newBuffers[index].type = CAMERA_BUFFER_ANW;
574             newBuffers[index].format = mPixelFormat;
575             mFramesWithCameraAdapterMap.add(handle, index);
576 
577             mBufferSource->lock_buffer(mBufferSource, handle);
578             mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
579             newBuffers[index].mapped = y_uv[0];
580             CAMHAL_LOGDB("got handle %p", handle);
581 
582             missingIndices.removeItem(newBuffers[index].opaque);
583         }
584 
585         // now we need to figure out which buffers aren't dequeued
586         // which are in mBuffers but not newBuffers yet
587         if ((mBufferCount - index) != missingIndices.size()) {
588             CAMHAL_LOGD("Hrmm somethings gone awry. We are missing a different number"
589                         " of buffers than we can fill");
590         }
591         for (unsigned int i = 0; i < missingIndices.size(); i++) {
592             int j = missingIndices.valueAt(i);
593 
594             CAMHAL_LOGD("Filling at %d", j);
595             newBuffers[index].opaque = mBuffers[j].opaque;
596             newBuffers[index].type = mBuffers[j].type;
597             newBuffers[index].format = mBuffers[j].format;
598             newBuffers[index].mapped = mBuffers[j].mapped;
599         }
600 
601         delete [] mBuffers;
602         mBuffers = newBuffers;
603     }
604 
605     return mBuffers;
606 
607  fail:
608     return NULL;
609 }
610 
getSize()611 unsigned int BufferSourceAdapter::getSize() {
612     android::Mutex::Autolock lock(mLock);
613     return CameraHal::calculateBufferSize(mPixelFormat, mFrameWidth, mFrameHeight);
614 }
615 
getBufferCount()616 int BufferSourceAdapter::getBufferCount() {
617     int count = -1;
618 
619     android::Mutex::Autolock lock(mLock);
620     if (mBufferSource) extendedOps()->get_buffer_count(mBufferSource, &count);
621     return count;
622 }
623 
getBufferList(int * num)624 CameraBuffer* BufferSourceAdapter::getBufferList(int *num) {
625     LOG_FUNCTION_NAME;
626     status_t err;
627     const int lnumBufs = 1;
628     int formatSource;
629     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
630     buffer_handle_t *handle;
631 
632     // TODO(XXX): Only supporting one input buffer at a time right now
633     *num = 1;
634     mBuffers = new CameraBuffer [lnumBufs];
635     memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
636 
637     if ( NULL == mBufferSource ) {
638         return NULL;
639     }
640 
641     err = extendedOps()->update_and_get_buffer(mBufferSource, &handle, &mBuffers[0].stride);
642     if (err != 0) {
643         CAMHAL_LOGEB("update and get buffer failed: %s (%d)", strerror(-err), -err);
644         if ( ENODEV == err ) {
645             CAMHAL_LOGEA("Preview surface abandoned!");
646             mBufferSource = NULL;
647         }
648         goto fail;
649     }
650 
651     CAMHAL_LOGD("got handle %p", handle);
652     mBuffers[0].opaque = (void *)handle;
653     mBuffers[0].type = CAMERA_BUFFER_ANW;
654     mFramesWithCameraAdapterMap.add(handle, 0);
655 
656     err = extendedOps()->get_buffer_dimension(mBufferSource, &mBuffers[0].width, &mBuffers[0].height);
657     err = extendedOps()->get_buffer_format(mBufferSource, &formatSource);
658 
659     int t, l, r, b, w, h;
660     err = extendedOps()->get_crop(mBufferSource, &l, &t, &r, &b);
661     err = extendedOps()->get_current_size(mBufferSource, &w, &h);
662 
663     // lock buffer
664     {
665         void *y_uv[2];
666         android::Rect bounds(mBuffers[0].width, mBuffers[0].height);
667         mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
668         mBuffers[0].mapped = y_uv[0];
669     }
670 
671     mFrameWidth = mBuffers[0].width;
672     mFrameHeight = mBuffers[0].height;
673     mPixelFormat = getFormatFromANW(formatSource);
674 
675     mBuffers[0].format = mPixelFormat;
676     mBuffers[0].actual_size = CameraHal::calculateBufferSize(mPixelFormat, w, h);
677     mBuffers[0].offset = t * w + l * CameraHal::getBPP(mPixelFormat);
678     mBufferSourceDirection = BUFFER_SOURCE_TAP_IN;
679 
680     return mBuffers;
681 
682  fail:
683     // need to cancel buffers if any were dequeued
684     freeBufferList(mBuffers);
685 
686     if (NULL != mErrorNotifier.get()) {
687         mErrorNotifier->errorNotify(-ENOMEM);
688     }
689 
690     LOG_FUNCTION_NAME_EXIT;
691     return NULL;
692 }
693 
getOffsets()694 uint32_t * BufferSourceAdapter::getOffsets()
695 {
696     LOG_FUNCTION_NAME;
697 
698     LOG_FUNCTION_NAME_EXIT;
699 
700     return NULL;
701 }
702 
minUndequeueableBuffers(int & undequeueable)703 int BufferSourceAdapter::minUndequeueableBuffers(int& undequeueable) {
704     LOG_FUNCTION_NAME;
705     int ret = NO_ERROR;
706 
707     if(!mBufferSource)
708     {
709         ret = INVALID_OPERATION;
710         goto end;
711     }
712 
713     ret = mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeueable);
714     if ( NO_ERROR != ret ) {
715         CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret);
716         if ( ENODEV == ret ) {
717             CAMHAL_LOGEA("Preview surface abandoned!");
718             mBufferSource = NULL;
719         }
720         return -ret;
721     }
722 
723  end:
724     return ret;
725     LOG_FUNCTION_NAME_EXIT;
726 
727 }
728 
maxQueueableBuffers(unsigned int & queueable)729 int BufferSourceAdapter::maxQueueableBuffers(unsigned int& queueable)
730 {
731     LOG_FUNCTION_NAME;
732     int ret = NO_ERROR;
733     int undequeued = 0;
734 
735     if(mBufferCount == 0) {
736         ret = INVALID_OPERATION;
737         goto end;
738     }
739 
740     ret = minUndequeueableBuffers(undequeued);
741     if (ret != NO_ERROR) {
742         goto end;
743     }
744 
745     queueable = mBufferCount - undequeued;
746 
747  end:
748     return ret;
749     LOG_FUNCTION_NAME_EXIT;
750 }
751 
getFd()752 int BufferSourceAdapter::getFd()
753 {
754     LOG_FUNCTION_NAME;
755 
756     LOG_FUNCTION_NAME_EXIT;
757 
758     return -1;
759 
760 }
761 
returnBuffersToWindow()762 status_t BufferSourceAdapter::returnBuffersToWindow()
763 {
764     status_t ret = NO_ERROR;
765     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
766 
767     //Give the buffers back to display here -  sort of free it
768     if (mBufferSource) {
769         for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) {
770             int value = mFramesWithCameraAdapterMap.valueAt(i);
771             buffer_handle_t *handle = (buffer_handle_t *) mBuffers[value].opaque;
772 
773             // if buffer index is out of bounds skip
774             if ((value < 0) || (value >= mBufferCount)) {
775                 CAMHAL_LOGEA("Potential out bounds access to handle...skipping");
776                 continue;
777             }
778 
779             // unlock buffer before giving it up
780             mapper.unlock(*handle);
781 
782             ret = mBufferSource->cancel_buffer(mBufferSource, handle);
783             if ( ENODEV == ret ) {
784                 CAMHAL_LOGEA("Preview surface abandoned!");
785                 mBufferSource = NULL;
786                 return -ret;
787             } else if ( NO_ERROR != ret ) {
788                 CAMHAL_LOGEB("cancel_buffer() failed: %s (%d)",
789                               strerror(-ret),
790                               -ret);
791                 return -ret;
792             }
793         }
794     } else {
795          CAMHAL_LOGE("mBufferSource is NULL");
796     }
797 
798      ///Clear the frames with camera adapter map
799      mFramesWithCameraAdapterMap.clear();
800 
801      return ret;
802 
803 }
804 
freeBufferList(CameraBuffer * buflist)805 int BufferSourceAdapter::freeBufferList(CameraBuffer * buflist)
806 {
807     LOG_FUNCTION_NAME;
808 
809     status_t ret = NO_ERROR;
810 
811     if ( mBuffers != buflist ) {
812         return BAD_VALUE;
813     }
814 
815     android::AutoMutex lock(mLock);
816 
817     if (mBufferSourceDirection == BUFFER_SOURCE_TAP_OUT) returnBuffersToWindow();
818 
819     if( mBuffers != NULL)
820     {
821         delete [] mBuffers;
822         mBuffers = NULL;
823     }
824 
825     return NO_ERROR;
826 }
827 
828 
supportsExternalBuffering()829 bool BufferSourceAdapter::supportsExternalBuffering()
830 {
831     return false;
832 }
833 
addFrame(CameraFrame * frame)834 void BufferSourceAdapter::addFrame(CameraFrame* frame)
835 {
836     if (mQueueFrame.get()) {
837         mQueueFrame->addFrame(frame);
838     }
839 }
840 
handleFrameCallback(CameraFrame * frame)841 void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame)
842 {
843     status_t ret = NO_ERROR;
844     buffer_handle_t *handle = NULL;
845     int i;
846     uint32_t x, y;
847     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
848 
849     android::AutoMutex lock(mLock);
850 
851     if (!mBuffers || !frame->mBuffer) {
852         CAMHAL_LOGEA("Adapter sent BufferSourceAdapter a NULL frame?");
853         return;
854     }
855 
856     for ( i = 0; i < mBufferCount; i++ ) {
857         if (frame->mBuffer == &mBuffers[i]) {
858             break;
859         }
860     }
861 
862     if (i >= mBufferCount) {
863         CAMHAL_LOGD("Can't find frame in buffer list");
864         if (frame->mFrameType != CameraFrame::REPROCESS_INPUT_FRAME) {
865             mFrameProvider->returnFrame(frame->mBuffer,
866                     static_cast<CameraFrame::FrameType>(frame->mFrameType));
867         }
868         return;
869     }
870 
871     handle = (buffer_handle_t *) mBuffers[i].opaque;
872 
873     // Handle input buffers
874     // TODO(XXX): Move handling of input buffers out of here if
875     // it becomes more complex
876     if (frame->mFrameType == CameraFrame::REPROCESS_INPUT_FRAME) {
877         CAMHAL_LOGD("Unlock %p (buffer #%d)", handle, i);
878         mapper.unlock(*handle);
879         return;
880     }
881 
882     CameraHal::getXYFromOffset(&x, &y, frame->mOffset, frame->mAlignment, mPixelFormat);
883     CAMHAL_LOGVB("offset = %u left = %d top = %d right = %d bottom = %d",
884                   frame->mOffset, x, y, x + frame->mWidth, y + frame->mHeight);
885     ret = mBufferSource->set_crop(mBufferSource, x, y, x + frame->mWidth, y + frame->mHeight);
886     if (NO_ERROR != ret) {
887         CAMHAL_LOGE("mBufferSource->set_crop returned error %d", ret);
888         goto fail;
889     }
890 
891     if ( NULL != frame->mMetaData.get() ) {
892         camera_memory_t *extMeta = frame->mMetaData->getExtendedMetadata();
893         if ( NULL != extMeta ) {
894             camera_metadata_t *metaData = static_cast<camera_metadata_t *> (extMeta->data);
895             metaData->timestamp = frame->mTimestamp;
896             ret = extendedOps()->set_metadata(mBufferSource, extMeta);
897             if (ret != 0) {
898                 CAMHAL_LOGE("Surface::set_metadata returned error %d", ret);
899                 goto fail;
900             }
901         }
902     }
903 
904     // unlock buffer before enqueueing
905     mapper.unlock(*handle);
906 
907     ret = mBufferSource->enqueue_buffer(mBufferSource, handle);
908     if (ret != 0) {
909         CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret);
910         goto fail;
911     }
912 
913     mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) frame->mBuffer->opaque);
914 
915     return;
916 
917 fail:
918     mFramesWithCameraAdapterMap.clear();
919     mBufferSource = NULL;
920     mReturnFrame->requestExit();
921     mQueueFrame->requestExit();
922 }
923 
924 
handleFrameReturn()925 bool BufferSourceAdapter::handleFrameReturn()
926 {
927     status_t err;
928     buffer_handle_t *buf;
929     int i = 0;
930     int stride;  // dummy variable to get stride
931     CameraFrame::FrameType type;
932     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
933     void *y_uv[2];
934     android::Rect bounds(mFrameWidth, mFrameHeight);
935 
936     android::AutoMutex lock(mLock);
937 
938     if ( (NULL == mBufferSource) || (NULL == mBuffers) ) {
939         return false;
940     }
941 
942     err = mBufferSource->dequeue_buffer(mBufferSource, &buf, &stride);
943     if (err != 0) {
944         CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
945 
946         if ( ENODEV == err ) {
947             CAMHAL_LOGEA("Preview surface abandoned!");
948             mBufferSource = NULL;
949         }
950 
951         return false;
952     }
953 
954     err = mBufferSource->lock_buffer(mBufferSource, buf);
955     if (err != 0) {
956         CAMHAL_LOGEB("lockbuffer failed: %s (%d)", strerror(-err), -err);
957 
958         if ( ENODEV == err ) {
959             CAMHAL_LOGEA("Preview surface abandoned!");
960             mBufferSource = NULL;
961         }
962 
963         return false;
964     }
965 
966     mapper.lock(*buf, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
967 
968     for(i = 0; i < mBufferCount; i++) {
969         if (mBuffers[i].opaque == buf)
970             break;
971     }
972 
973     if (i >= mBufferCount) {
974         CAMHAL_LOGEB("Failed to find handle %p", buf);
975     }
976 
977     mFramesWithCameraAdapterMap.add((buffer_handle_t *) mBuffers[i].opaque, i);
978 
979     CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount - 1);
980 
981     mFrameProvider->returnFrame(&mBuffers[i], formatToOutputFrameType(mPixelFormat));
982     return true;
983 }
984 
frameCallback(CameraFrame * caFrame)985 void BufferSourceAdapter::frameCallback(CameraFrame* caFrame)
986 {
987     if ((NULL != caFrame) && (NULL != caFrame->mCookie)) {
988         BufferSourceAdapter *da = (BufferSourceAdapter*) caFrame->mCookie;
989         da->addFrame(caFrame);
990     } else {
991         CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p",
992                     caFrame, caFrame ? caFrame->mCookie : NULL);
993     }
994 }
995 
996 /*--------------------BufferSourceAdapter Class ENDS here-----------------------------*/
997 
998 } // namespace Camera
999 } // namespace Ti
1000 
1001 #endif
1002