Home | History | Annotate | Download | only in camera
      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 
     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 
     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 
     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 
     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 
    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  */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    339 void BufferSourceAdapter::destroy()
    340 {
    341     LOG_FUNCTION_NAME;
    342 
    343     mBufferCount = 0;
    344 
    345     LOG_FUNCTION_NAME_EXIT;
    346 }
    347 
    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 
    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 
    611 unsigned int BufferSourceAdapter::getSize() {
    612     android::Mutex::Autolock lock(mLock);
    613     return CameraHal::calculateBufferSize(mPixelFormat, mFrameWidth, mFrameHeight);
    614 }
    615 
    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 
    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 
    694 uint32_t * BufferSourceAdapter::getOffsets()
    695 {
    696     LOG_FUNCTION_NAME;
    697 
    698     LOG_FUNCTION_NAME_EXIT;
    699 
    700     return NULL;
    701 }
    702 
    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 
    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 
    752 int BufferSourceAdapter::getFd()
    753 {
    754     LOG_FUNCTION_NAME;
    755 
    756     LOG_FUNCTION_NAME_EXIT;
    757 
    758     return -1;
    759 
    760 }
    761 
    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 
    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 
    829 bool BufferSourceAdapter::supportsExternalBuffering()
    830 {
    831     return false;
    832 }
    833 
    834 void BufferSourceAdapter::addFrame(CameraFrame* frame)
    835 {
    836     if (mQueueFrame.get()) {
    837         mQueueFrame->addFrame(frame);
    838     }
    839 }
    840 
    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 
    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 
    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