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