Home | History | Annotate | Download | only in liboverlay
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      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 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "TIOverlay"
     19 
     20 #include <hardware/hardware.h>
     21 #include <hardware/overlay.h>
     22 
     23 extern "C" {
     24 #include "v4l2_utils.h"
     25 }
     26 
     27 #include <pthread.h>
     28 #include <fcntl.h>
     29 #include <errno.h>
     30 #include <sys/types.h>
     31 #include <sys/stat.h>
     32 #include <sys/mman.h>
     33 #include <unistd.h>
     34 #include <linux/videodev.h>
     35 
     36 #include <cutils/log.h>
     37 #include <cutils/ashmem.h>
     38 #include <cutils/atomic.h>
     39 
     40 /*****************************************************************************/
     41 
     42 #define LOG_FUNCTION_NAME LOGV(" %s %s",  __FILE__, __FUNCTION__)
     43 
     44 #define NUM_OVERLAY_BUFFERS_REQUESTED  (8)
     45 #define SHARED_DATA_MARKER             (0x68759746) // OVRLYSHM on phone keypad
     46 
     47 /* These values should come from Surface Flinger */
     48 #define LCD_WIDTH 480
     49 #define LCD_HEIGHT 854
     50 
     51 #define CACHEABLE_BUFFERS 0x1
     52 
     53 #define ALL_BUFFERS_FLUSHED -66 //shared with Camera/Video Playback HAL
     54 
     55 typedef struct
     56 {
     57   uint32_t posX;
     58   uint32_t posY;
     59   uint32_t posW;
     60   uint32_t posH;
     61   uint32_t rotation;
     62 } overlay_ctrl_t;
     63 
     64 typedef struct
     65 {
     66   uint32_t cropX;
     67   uint32_t cropY;
     68   uint32_t cropW;
     69   uint32_t cropH;
     70 } overlay_data_t;
     71 
     72 typedef struct
     73 {
     74   uint32_t marker;
     75   uint32_t size;
     76 
     77   volatile int32_t refCnt;
     78 
     79   uint32_t controlReady; // Only updated by the control side
     80   uint32_t dataReady;    // Only updated by the data side
     81 
     82   pthread_mutex_t lock;
     83   pthread_mutexattr_t attr;
     84 
     85   uint32_t streamEn;
     86   uint32_t streamingReset;
     87 
     88   uint32_t dispW;
     89   uint32_t dispH;
     90 
     91 } overlay_shared_t;
     92 
     93 // Only one instance is created per platform
     94 struct overlay_control_context_t {
     95     struct overlay_control_device_t device;
     96     /* our private state goes below here */
     97     struct overlay_t* overlay_video1;
     98     struct overlay_t* overlay_video2;
     99 };
    100 
    101 // A separate instance is created per overlay data side user
    102 struct overlay_data_context_t {
    103     struct overlay_data_device_t device;
    104     /* our private state goes below here */
    105     int ctl_fd;
    106     int shared_fd;
    107     int shared_size;
    108     int width;
    109     int height;
    110     int format;
    111     int num_buffers;
    112     size_t *buffers_len;
    113     void **buffers;
    114 
    115     overlay_data_t    data;
    116     overlay_shared_t  *shared;
    117     mapping_data_t    *mapping_data;
    118     // Need to count Qd buffers to be sure we don't block DQ'ing when exiting
    119     int qd_buf_count;
    120     int cacheable_buffers;
    121 };
    122 
    123 static int  create_shared_data(overlay_shared_t **shared);
    124 static void destroy_shared_data(int shared_fd, overlay_shared_t *shared, bool closefd);
    125 static int  open_shared_data(overlay_data_context_t *ctx);
    126 static void close_shared_data(overlay_data_context_t *ctx);
    127 enum { LOCK_REQUIRED = 1, NO_LOCK_NEEDED = 0 };
    128 static int  enable_streaming( overlay_shared_t *shared, int ovly_fd, int lock_required );
    129 
    130 static int overlay_device_open(const struct hw_module_t* module,
    131                                const char* name, struct hw_device_t** device);
    132 
    133 static struct hw_module_methods_t overlay_module_methods = {
    134     open: overlay_device_open
    135 };
    136 
    137 struct overlay_module_t HAL_MODULE_INFO_SYM = {
    138     common: {
    139         tag: HARDWARE_MODULE_TAG,
    140         version_major: 1,
    141         version_minor: 0,
    142         id: OVERLAY_HARDWARE_MODULE_ID,
    143         name: "Sample Overlay module",
    144         author: "The Android Open Source Project",
    145         methods: &overlay_module_methods,
    146     }
    147 };
    148 
    149 /*****************************************************************************/
    150 
    151 /*
    152  * This is the overlay_t object, it is returned to the user and represents
    153  * an overlay. here we use a subclass, where we can store our own state.
    154  * This handles will be passed across processes and possibly given to other
    155  * HAL modules (for instance video decode modules).
    156  */
    157 struct handle_t : public native_handle {
    158     /* add the data fields we need here, for instance: */
    159     int ctl_fd;
    160     int shared_fd;
    161     int width;
    162     int height;
    163     int format;
    164     int num_buffers;
    165     int shared_size;
    166 };
    167 
    168 static int handle_format(const overlay_handle_t overlay) {
    169     return static_cast<const struct handle_t *>(overlay)->format;
    170 }
    171 
    172 static int handle_ctl_fd(const overlay_handle_t overlay) {
    173     return static_cast<const struct handle_t *>(overlay)->ctl_fd;
    174 }
    175 
    176 static int handle_shared_fd(const overlay_handle_t overlay) {
    177     return static_cast<const struct handle_t *>(overlay)->shared_fd;
    178 }
    179 
    180 static int handle_num_buffers(const overlay_handle_t overlay) {
    181     return static_cast<const struct handle_t *>(overlay)->num_buffers;
    182 }
    183 
    184 static int handle_width(const overlay_handle_t overlay) {
    185     return static_cast<const struct handle_t *>(overlay)->width;
    186 }
    187 
    188 static int handle_height(const overlay_handle_t overlay) {
    189     return static_cast<const struct handle_t *>(overlay)->height;
    190 }
    191 
    192 static int handle_shared_size(const overlay_handle_t overlay) {
    193     return static_cast<const struct handle_t *>(overlay)->shared_size;
    194 }
    195 
    196 // A separate instance of this class is created per overlay
    197 class overlay_object : public overlay_t
    198 {
    199     handle_t mHandle;
    200 
    201     overlay_ctrl_t    mCtl;
    202     overlay_ctrl_t    mCtlStage;
    203     overlay_shared_t *mShared;
    204 
    205     static overlay_handle_t getHandleRef(struct overlay_t* overlay) {
    206         /* returns a reference to the handle, caller doesn't take ownership */
    207         return &(static_cast<overlay_object *>(overlay)->mHandle);
    208     }
    209 
    210 public:
    211     overlay_object(int ctl_fd, int shared_fd, int shared_size, int w, int h,
    212                    int format, int num_buffers) {
    213         this->overlay_t::getHandleRef = getHandleRef;
    214         mHandle.version     = sizeof(native_handle);
    215         mHandle.numFds      = 2;
    216         mHandle.numInts     = 5; // extra ints we have in our handle
    217         mHandle.ctl_fd      = ctl_fd;
    218         mHandle.shared_fd   = shared_fd;
    219         mHandle.width       = w;
    220         mHandle.height      = h;
    221         mHandle.format      = format;
    222         mHandle.num_buffers = num_buffers;
    223         mHandle.shared_size = shared_size;
    224         this->w = w;
    225         this->h = h;
    226         this->format = format;
    227 
    228         memset( &mCtl, 0, sizeof( mCtl ) );
    229         memset( &mCtlStage, 0, sizeof( mCtlStage ) );
    230     }
    231 
    232     int               ctl_fd()    { return mHandle.ctl_fd; }
    233     int               shared_fd() { return mHandle.shared_fd; }
    234     overlay_ctrl_t*   data()      { return &mCtl; }
    235     overlay_ctrl_t*   staging()   { return &mCtlStage; }
    236     overlay_shared_t* getShared() { return mShared; }
    237     void              setShared( overlay_shared_t *p ) { mShared = p; }
    238 };
    239 
    240 // ****************************************************************************
    241 // Local Functions
    242 // ****************************************************************************
    243 
    244 static int create_shared_data(overlay_shared_t **shared)
    245 {
    246     int fd;
    247     // assuming sizeof(overlay_shared_t) < a single page
    248     int size = getpagesize();
    249     overlay_shared_t *p;
    250 
    251     if ((fd = ashmem_create_region("overlay_data", size)) < 0) {
    252         LOGE("Failed to Create Overlay Shared Data!\n");
    253         return fd;
    254     }
    255 
    256     p = (overlay_shared_t*)mmap(NULL, size, PROT_READ | PROT_WRITE,
    257                                 MAP_SHARED, fd, 0);
    258     if (p == MAP_FAILED) {
    259         LOGE("Failed to Map Overlay Shared Data!\n");
    260         close(fd);
    261         return -1;
    262     }
    263 
    264     memset(p, 0, size);
    265     p->marker = SHARED_DATA_MARKER;
    266     p->size   = size;
    267     p->refCnt = 1;
    268     int ret = 0;
    269     if ((ret = pthread_mutexattr_init(&p->attr)) != 0) {
    270         LOGE("Failed to initialize overlay mutex attr");
    271     }
    272     if (ret == 0 && (ret = pthread_mutexattr_setpshared(&p->attr, PTHREAD_PROCESS_SHARED)) != 0) {
    273        LOGE("Failed to set the overlay mutex attr to be shared across-processes");
    274     }
    275     if (ret == 0 && (ret = pthread_mutex_init(&p->lock, &p->attr)) != 0) {
    276         LOGE("Failed to initialize overlay mutex\n");
    277     }
    278     if (ret != 0) {
    279         munmap(p, size);
    280         close(fd);
    281         return -1;
    282     }
    283     *shared = p;
    284     return fd;
    285 }
    286 
    287 static void destroy_shared_data( int shared_fd, overlay_shared_t *shared, bool closefd )
    288 {
    289     if (shared == NULL)
    290         return;
    291 
    292     // Last side deallocated releases the mutex, otherwise the remaining
    293     // side will deadlock trying to use an already released mutex
    294     if (android_atomic_dec(&shared->refCnt) == 1) {
    295         if (pthread_mutex_destroy(&shared->lock)) {
    296             LOGE("Failed to uninitialize overlay mutex!\n");
    297         }
    298 
    299         if (pthread_mutexattr_destroy(&shared->attr)) {
    300             LOGE("Failed to uninitialize the overlay mutex attr!\n");
    301         }
    302         shared->marker = 0;
    303     }
    304 
    305     if (munmap(shared, shared->size)) {
    306         LOGE("Failed to Unmap Overlay Shared Data!\n");
    307     }
    308 
    309     if (closefd && close(shared_fd)) {
    310         LOGE("Failed to Close Overlay Shared Data!\n");
    311     }
    312 }
    313 
    314 static int open_shared_data( overlay_data_context_t *ctx )
    315 {
    316     int rc   = -1;
    317     int mode = PROT_READ | PROT_WRITE;
    318     int fd   = ctx->shared_fd;
    319     int size = ctx->shared_size;
    320 
    321     if (ctx->shared != NULL) {
    322         // Already open, return success
    323         LOGI("Overlay Shared Data Already Open\n");
    324         return 0;
    325     }
    326     ctx->shared = (overlay_shared_t*)mmap(0, size, mode, MAP_SHARED, fd, 0);
    327 
    328     if (ctx->shared == MAP_FAILED) {
    329         LOGE("Failed to Map Overlay Shared Data!\n");
    330     } else if ( ctx->shared->marker != SHARED_DATA_MARKER ) {
    331         LOGE("Invalid Overlay Shared Marker!\n");
    332         munmap( ctx->shared, size);
    333     } else if ( (int)ctx->shared->size != size ) {
    334         LOGE("Invalid Overlay Shared Size!\n");
    335         munmap(ctx->shared, size);
    336     } else {
    337         android_atomic_inc(&ctx->shared->refCnt);
    338         rc = 0;
    339     }
    340 
    341     return rc;
    342 }
    343 
    344 static void close_shared_data(overlay_data_context_t *ctx)
    345 {
    346     destroy_shared_data(ctx->shared_fd, ctx->shared, false);
    347     ctx->shared = NULL;
    348 }
    349 
    350 static int enable_streaming_locked(overlay_shared_t *shared, int ovly_fd)
    351 {
    352     int rc = 0;
    353 
    354     if (!shared->controlReady || !shared->dataReady) {
    355         LOGI("Postponing Stream Enable/%d/%d\n", shared->controlReady,
    356              shared->dataReady);
    357     } else {
    358         shared->streamEn = 1;
    359         rc = v4l2_overlay_stream_on(ovly_fd);
    360         if (rc) {
    361             LOGE("Stream Enable Failed!/%d\n", rc);
    362             shared->streamEn = 0;
    363         }
    364     }
    365 
    366     return rc;
    367 }
    368 
    369 static int enable_streaming(overlay_shared_t *shared, int ovly_fd)
    370 {
    371     int ret;
    372 
    373     pthread_mutex_lock(&shared->lock);
    374     ret = enable_streaming_locked(shared, ovly_fd);
    375     pthread_mutex_unlock(&shared->lock);
    376     return ret;
    377 }
    378 
    379 static int disable_streaming_locked(overlay_shared_t *shared, int ovly_fd)
    380 {
    381     int ret = 0;
    382 
    383     if (shared->streamEn) {
    384         ret = v4l2_overlay_stream_off( ovly_fd );
    385         if (ret) {
    386             LOGE("Stream Off Failed!/%d\n", ret);
    387         } else {
    388             shared->streamingReset = 1;
    389             shared->streamEn = 0;
    390         }
    391     }
    392 
    393     return ret;
    394 }
    395 
    396 // ****************************************************************************
    397 // Control module
    398 // ****************************************************************************
    399 
    400 static int overlay_get(struct overlay_control_device_t *dev, int name)
    401 {
    402     int result = -1;
    403 
    404     switch (name) {
    405         case OVERLAY_MINIFICATION_LIMIT:   result = 0;  break; // 0 = no limit
    406         case OVERLAY_MAGNIFICATION_LIMIT:  result = 0;  break; // 0 = no limit
    407         case OVERLAY_SCALING_FRAC_BITS:    result = 0;  break; // 0 = infinite
    408         case OVERLAY_ROTATION_STEP_DEG:    result = 90; break; // 90 rotation steps (for instance)
    409         case OVERLAY_HORIZONTAL_ALIGNMENT: result = 1;  break; // 1-pixel alignment
    410         case OVERLAY_VERTICAL_ALIGNMENT:   result = 1;  break; // 1-pixel alignment
    411         case OVERLAY_WIDTH_ALIGNMENT:      result = 1;  break; // 1-pixel alignment
    412         case OVERLAY_HEIGHT_ALIGNMENT:     break;
    413     }
    414 
    415     return result;
    416 }
    417 
    418 static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev,
    419                                         uint32_t w, uint32_t h, int32_t  format)
    420 {
    421     LOGD("overlay_createOverlay:IN w=%d h=%d format=%d\n", w, h, format);
    422     LOG_FUNCTION_NAME;
    423 
    424     overlay_object            *overlay;
    425     overlay_control_context_t *ctx = (overlay_control_context_t *)dev;
    426     overlay_shared_t          *shared;
    427 
    428     int ret;
    429     uint32_t num = NUM_OVERLAY_BUFFERS_REQUESTED;
    430     int fd;
    431     int shared_fd;
    432 
    433     if (format == OVERLAY_FORMAT_DEFAULT)
    434     {
    435         format = OVERLAY_FORMAT_YCbYCr_422_I;
    436     }
    437 
    438     if (ctx->overlay_video1) {
    439         LOGE("Error - overlays already in use\n");
    440         return NULL;
    441     }
    442 
    443     shared_fd = create_shared_data(&shared);
    444     if (shared_fd < 0) {
    445         LOGE("Failed to create shared data");
    446         return NULL;
    447     }
    448 
    449     fd = v4l2_overlay_open(V4L2_OVERLAY_PLANE_VIDEO1);
    450     if (fd < 0) {
    451         LOGE("Failed to open overlay device\n");
    452         goto error;
    453     }
    454 
    455     if (v4l2_overlay_init(fd, w, h, format)) {
    456         LOGE("Failed initializing overlays\n");
    457         goto error1;
    458     }
    459 
    460     if (v4l2_overlay_set_crop(fd, 0, 0, w, h)) {
    461         LOGE("Failed defaulting crop window\n");
    462         goto error1;
    463     }
    464 
    465     if (v4l2_overlay_set_rotation(fd, 0, 0)) {
    466         LOGE("Failed defaulting rotation\n");
    467         goto error1;
    468     }
    469 
    470     if (v4l2_overlay_req_buf(fd, &num, 0)) {
    471         LOGE("Failed requesting buffers\n");
    472         goto error1;
    473     }
    474 
    475    overlay = new overlay_object(fd, shared_fd, shared->size, w, h, format, num);
    476    if (overlay == NULL) {
    477         LOGE("Failed to create overlay object\n");
    478         goto error1;
    479    }
    480    ctx->overlay_video1 = overlay;
    481 
    482    overlay->setShared(shared);
    483 
    484    shared->controlReady = 0;
    485    shared->streamEn = 0;
    486    shared->streamingReset = 0;
    487    shared->dispW = LCD_WIDTH; // Need to determine this properly
    488    shared->dispH = LCD_HEIGHT; // Need to determine this properly
    489 
    490     LOGI("Opened video1/fd=%d/obj=%08lx/shm=%d/size=%d", fd,
    491         (unsigned long)overlay, shared_fd, shared->size);
    492 
    493 
    494     LOGD("overlay_createOverlay: OUT");
    495     return overlay;
    496 
    497 error1:
    498     close(fd);
    499 error:
    500     destroy_shared_data(shared_fd, shared, true);
    501     return NULL;
    502 }
    503 
    504 static void overlay_destroyOverlay(struct overlay_control_device_t *dev,
    505                                    overlay_t* overlay)
    506 {
    507     LOGD("overlay_destroyOverlay:IN dev (%p) and overlay (%p)", dev, overlay);
    508     LOG_FUNCTION_NAME;
    509 
    510     overlay_control_context_t *ctx = (overlay_control_context_t *)dev;
    511     overlay_object *obj = static_cast<overlay_object *>(overlay);
    512 
    513     int rc;
    514     int fd = obj->ctl_fd();
    515     overlay_shared_t *shared = obj->getShared();
    516 
    517     if (shared == NULL) {
    518         LOGE("Overlay was already destroyed - nothing needs to be done\n");
    519         return;
    520     }
    521 
    522     pthread_mutex_lock(&shared->lock);
    523 
    524     disable_streaming_locked(shared, fd);
    525 
    526     pthread_mutex_unlock(&shared->lock);
    527 
    528     destroy_shared_data(obj->shared_fd(), shared, true);
    529     obj->setShared(NULL);
    530 
    531     LOGI("Destroying overlay/fd=%d/obj=%08lx", fd, (unsigned long)overlay);
    532 
    533     if (close(fd)) {
    534         LOGE( "Error closing overly fd/%d\n", errno);
    535     }
    536 
    537     if (overlay) {
    538         if (ctx->overlay_video1 == overlay)
    539             ctx->overlay_video1 = NULL;
    540         delete overlay;
    541         overlay = NULL;
    542     }
    543     LOGD("overlay_destroyOverlay:OUT");
    544 }
    545 
    546 static int overlay_setPosition(struct overlay_control_device_t *dev,
    547                                overlay_t* overlay, int x, int y, uint32_t w,
    548                                uint32_t h)
    549 {
    550     LOG_FUNCTION_NAME;
    551 
    552     overlay_object *obj = static_cast<overlay_object *>(overlay);
    553 
    554     overlay_ctrl_t   *stage  = obj->staging();
    555     overlay_shared_t *shared = obj->getShared();
    556 
    557     int rc = 0;
    558 
    559     // FIXME:  This is a hack to deal with seemingly unintentional negative
    560     // offset that pop up now and again.  I believe the negative offsets are
    561     // due to a surface flinger bug that has not yet been found or fixed.
    562     //
    563     // This logic here is to return an error if the rectangle is not fully
    564     // within the display, unless we have not received a valid position yet,
    565     // in which case we will do our best to adjust the rectangle to be within
    566     // the display.
    567 
    568     // Require a minimum size
    569     if (w < 16 || h < 16) {
    570         // Return an error
    571         rc = -1;
    572     } else if (!shared->controlReady) {
    573         if ( x < 0 ) x = 0;
    574         if ( y < 0 ) y = 0;
    575         if ( w > shared->dispW ) w = shared->dispW;
    576         if ( h > shared->dispH ) h = shared->dispH;
    577         if ( (x + w) > shared->dispW ) w = shared->dispW - x;
    578         if ( (y + h) > shared->dispH ) h = shared->dispH - y;
    579     } else if (x < 0 || y < 0 || (x + w) > shared->dispW ||
    580                (y + h) > shared->dispH) {
    581         // Return an error
    582         rc = -1;
    583     }
    584 
    585     if (rc == 0) {
    586         stage->posX = x;
    587         stage->posY = y;
    588         stage->posW = w;
    589         stage->posH = h;
    590     }
    591 
    592     return rc;
    593 }
    594 
    595 static int overlay_getPosition(struct overlay_control_device_t *dev,
    596                                overlay_t* overlay, int* x, int* y, uint32_t* w,
    597                                uint32_t* h)
    598 {
    599     LOG_FUNCTION_NAME;
    600 
    601     int fd = static_cast<overlay_object *>(overlay)->ctl_fd();
    602 
    603     if (v4l2_overlay_get_position(fd, x, y, (int32_t*)w, (int32_t*)h)) {
    604         return -EINVAL;
    605     }
    606     return 0;
    607 }
    608 
    609 static int overlay_setParameter(struct overlay_control_device_t *dev,
    610                                 overlay_t* overlay, int param, int value)
    611 {
    612     LOG_FUNCTION_NAME;
    613 
    614     overlay_ctrl_t *stage = static_cast<overlay_object *>(overlay)->staging();
    615     int rc = 0;
    616 
    617     switch (param) {
    618     case OVERLAY_DITHER:
    619         break;
    620 
    621     case OVERLAY_TRANSFORM:
    622         switch ( value )
    623         {
    624         case 0:
    625             stage->rotation = 0;
    626             break;
    627         case OVERLAY_TRANSFORM_ROT_90:
    628             stage->rotation = 90;
    629             break;
    630         case OVERLAY_TRANSFORM_ROT_180:
    631             stage->rotation = 180;
    632             break;
    633         case OVERLAY_TRANSFORM_ROT_270:
    634             stage->rotation = 270;
    635             break;
    636         default:
    637             rc = -EINVAL;
    638             break;
    639         }
    640         break;
    641     }
    642 
    643     return rc;
    644 }
    645 
    646 static int overlay_stage(struct overlay_control_device_t *dev,
    647                           overlay_t* overlay) {
    648     return 0;
    649 }
    650 
    651 static int overlay_commit(struct overlay_control_device_t *dev,
    652                           overlay_t* overlay) {
    653     LOG_FUNCTION_NAME;
    654 
    655     overlay_object *obj = static_cast<overlay_object *>(overlay);
    656 
    657     overlay_ctrl_t   *data   = obj->data();
    658     overlay_ctrl_t   *stage  = obj->staging();
    659     overlay_shared_t *shared = obj->getShared();
    660 
    661     int ret = 0;
    662     int fd = obj->ctl_fd();
    663 
    664     if (shared == NULL) {
    665         LOGI("Shared Data Not Init'd!\n");
    666         return -1;
    667     }
    668 
    669     pthread_mutex_lock(&shared->lock);
    670 
    671     if (!shared->controlReady) {
    672         shared->controlReady = 1;
    673     }
    674 
    675     if (data->posX == stage->posX && data->posY == stage->posY &&
    676         data->posW == stage->posW && data->posH == stage->posH &&
    677         data->rotation == stage->rotation) {
    678         LOGI("Nothing to do!\n");
    679         goto end;
    680     }
    681 
    682     LOGI("Position/X%d/Y%d/W%d/H%d\n", data->posX, data->posY, data->posW,
    683          data->posH);
    684     LOGI("Adjusted Position/X%d/Y%d/W%d/H%d\n", stage->posX, stage->posY,
    685          stage->posW, data->posH);
    686     LOGI("Rotation/%d\n", stage->rotation );
    687 
    688     if ((ret = disable_streaming_locked(shared, fd)))
    689         goto end;
    690 
    691     if (stage->rotation != data->rotation) {
    692         ret = v4l2_overlay_set_rotation(fd, stage->rotation, 0);
    693         if (ret) {
    694             LOGE("Set Rotation Failed!/%d\n", ret);
    695             goto end;
    696         }
    697         data->rotation = stage->rotation;
    698     }
    699 
    700     if (!(stage->posX == data->posX && stage->posY == data->posY &&
    701         stage->posW == data->posW && stage->posH == data->posH)) {
    702         ret = v4l2_overlay_set_position(fd, stage->posX, stage->posY,
    703                                         stage->posW, stage->posH);
    704         if (ret) {
    705             LOGE("Set Position Failed!/%d\n", ret);
    706             goto end;
    707         }
    708         data->posX = stage->posX;
    709         data->posY = stage->posY;
    710         data->posW = stage->posW;
    711         data->posH = stage->posH;
    712     }
    713 
    714     ret = enable_streaming_locked(shared, fd);
    715 
    716 end:
    717     pthread_mutex_unlock(&shared->lock);
    718 
    719     return ret;
    720 }
    721 
    722 static int overlay_control_close(struct hw_device_t *dev)
    723 {
    724     LOG_FUNCTION_NAME;
    725 
    726     struct overlay_control_context_t* ctx = (struct overlay_control_context_t*)dev;
    727     overlay_object *overlay_v1;
    728     //overlay_object *overlay_v2;
    729 
    730     if (ctx) {
    731         overlay_v1 = static_cast<overlay_object *>(ctx->overlay_video1);
    732         //overlay_v2 = static_cast<overlay_object *>(ctx->overlay_video2);
    733 
    734         overlay_destroyOverlay((struct overlay_control_device_t *)ctx,
    735                                overlay_v1);
    736         //overlay_destroyOverlay((struct overlay_control_device_t *)ctx, overlay_v2);
    737 
    738         free(ctx);
    739     }
    740     return 0;
    741 }
    742 
    743 // ****************************************************************************
    744 // Data module
    745 // ****************************************************************************
    746 
    747 int overlay_initialize(struct overlay_data_device_t *dev,
    748                        overlay_handle_t handle)
    749 {
    750     LOG_FUNCTION_NAME;
    751 
    752     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    753     struct stat stat;
    754 
    755     int i;
    756     int rc = -1;
    757 
    758     ctx->num_buffers  = handle_num_buffers(handle);
    759     ctx->width        = handle_width(handle);
    760     ctx->height       = handle_height(handle);
    761     ctx->format       = handle_format(handle);
    762     ctx->ctl_fd       = handle_ctl_fd(handle);
    763     ctx->shared_fd    = handle_shared_fd(handle);
    764     ctx->shared_size  = handle_shared_size(handle);
    765     ctx->shared       = NULL;
    766     ctx->qd_buf_count = 0;
    767     ctx->cacheable_buffers = 0;
    768 
    769     if (fstat(ctx->ctl_fd, &stat)) {
    770         LOGE("Error = %s from %s\n", strerror(errno), "overlay initialize");
    771         return -1;
    772     }
    773 
    774     if (open_shared_data(ctx)) {
    775         return -1;
    776     }
    777 
    778     ctx->shared->dataReady = 0;
    779 
    780     ctx->mapping_data = new mapping_data_t;
    781     ctx->buffers     = new void* [ctx->num_buffers];
    782     ctx->buffers_len = new size_t[ctx->num_buffers];
    783     if (!ctx->buffers || !ctx->buffers_len || !ctx->mapping_data) {
    784             LOGE("Failed alloc'ing buffer arrays\n");
    785             close_shared_data(ctx);
    786     } else {
    787         for (i = 0; i < ctx->num_buffers; i++) {
    788             rc = v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i],
    789                                        &ctx->buffers_len[i]);
    790             if (rc) {
    791                 LOGE("Failed mapping buffers\n");
    792                 close_shared_data( ctx );
    793                 break;
    794             }
    795         }
    796     }
    797 
    798     return ( rc );
    799 }
    800 
    801 static int overlay_resizeInput(struct overlay_data_device_t *dev, uint32_t w,
    802                                uint32_t h)
    803 {
    804     int rc = -1;
    805 
    806     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    807 
    808     if ((ctx->width == (int)w) && (ctx->width == (int)h)) {
    809         LOGV("same as current width and height. so do nothing");
    810         return 0;
    811     }
    812 
    813     if (!ctx->shared) {
    814         LOGI("Shared Data Not Init'd!\n");
    815         return -1;
    816     }
    817 
    818     if (ctx->shared->dataReady) {
    819         LOGV("Either setCrop() or queueBuffer() was called prior to this!"
    820              "Therefore failing this call.\n");
    821         return -1;
    822     }
    823 
    824     pthread_mutex_lock(&ctx->shared->lock);
    825 
    826     if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd)))
    827         goto end;
    828 
    829     for (int i = 0; i < ctx->num_buffers; i++) {
    830         v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]);
    831     }
    832 
    833     rc = v4l2_overlay_init(ctx->ctl_fd, w, h, ctx->format);
    834     if (rc) {
    835         LOGE("Error initializing overlay");
    836         goto end;
    837     }
    838     rc = v4l2_overlay_set_crop(ctx->ctl_fd, 0, 0, w, h);
    839     if (rc) {
    840         LOGE("Error setting crop window\n");
    841         goto end;
    842     }
    843     rc = v4l2_overlay_req_buf(ctx->ctl_fd, (uint32_t *)(&ctx->num_buffers),
    844                               ctx->cacheable_buffers);
    845     if (rc) {
    846         LOGE("Error creating buffers");
    847         goto end;
    848     }
    849 
    850     for (int i = 0; i < ctx->num_buffers; i++)
    851         v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i],
    852                              &ctx->buffers_len[i]);
    853 
    854     rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd);
    855 
    856 end:
    857     pthread_mutex_unlock(&ctx->shared->lock);
    858 
    859     return rc;
    860 }
    861 
    862 
    863 static int overlay_data_setParameter(struct overlay_data_device_t *dev,
    864                                      int param, int value)
    865 {
    866     int ret = 0;
    867     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    868 
    869     if (ctx->shared == NULL)
    870     {
    871         LOGI("Shared Data Not Init'd!\n");
    872         return -1;
    873     }
    874 
    875     if (ctx->shared->dataReady) {
    876         LOGI("Too late. Cant set it now!\n");
    877         return -1;
    878     }
    879 
    880     if (param == CACHEABLE_BUFFERS)
    881         ctx->cacheable_buffers = value;
    882 
    883     //ret = v4l2_overlay_set_attributes(ctx->ctl_fd, param, value);
    884     return ( ret );
    885 }
    886 
    887 
    888 static int overlay_setCrop(struct overlay_data_device_t *dev, uint32_t x,
    889                            uint32_t y, uint32_t w, uint32_t h) {
    890     LOG_FUNCTION_NAME;
    891 
    892     int rc = 0;
    893     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    894 
    895     if (ctx->shared == NULL) {
    896         LOGI("Shared Data Not Init'd!\n");
    897         return -1;
    898     }
    899 
    900     pthread_mutex_lock(&ctx->shared->lock);
    901 
    902     ctx->shared->dataReady = 1;
    903 
    904     if (ctx->data.cropX == x && ctx->data.cropY == y && ctx->data.cropW == w
    905         && ctx->data.cropH == h) {
    906         LOGI("Nothing to do!\n");
    907         goto end;
    908     }
    909 
    910     ctx->data.cropX = x;
    911     ctx->data.cropY = y;
    912     ctx->data.cropW = w;
    913     ctx->data.cropH = h;
    914 
    915     LOGI("Crop Win/X%d/Y%d/W%d/H%d\n", x, y, w, h );
    916 
    917     if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd)))
    918         goto end;
    919 
    920     rc = v4l2_overlay_set_crop(ctx->ctl_fd, x, y, w, h);
    921     if (rc) {
    922         LOGE("Set Crop Window Failed!/%d\n", rc);
    923     }
    924 
    925     rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd);
    926 
    927 end:
    928     pthread_mutex_unlock(&ctx->shared->lock);
    929     return rc;
    930 }
    931 
    932 static int overlay_getCrop(struct overlay_data_device_t *dev , uint32_t* x,
    933                            uint32_t* y, uint32_t* w, uint32_t* h) {
    934     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    935 
    936     return v4l2_overlay_get_crop(ctx->ctl_fd, x, y, w, h);
    937 }
    938 
    939 int overlay_dequeueBuffer(struct overlay_data_device_t *dev,
    940                           overlay_buffer_t *buffer) {
    941     /* blocks until a buffer is available and return an opaque structure
    942      * representing this buffer.
    943      */
    944 
    945     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    946 
    947     int rc;
    948     int i = -1;
    949 
    950     pthread_mutex_lock(&ctx->shared->lock);
    951     if ( ctx->shared->streamingReset )
    952     {
    953         ctx->shared->streamingReset = 0;
    954         pthread_mutex_unlock(&ctx->shared->lock);
    955         return ALL_BUFFERS_FLUSHED;
    956     }
    957     pthread_mutex_unlock(&ctx->shared->lock);
    958 
    959     // If we are not streaming dequeue will fail, skip to prevent error printouts
    960     if (ctx->shared->streamEn) {
    961         if ((rc = v4l2_overlay_dq_buf( ctx->ctl_fd, &i )) != 0) {
    962             LOGE("Failed to DQ/%d\n", rc);
    963         }
    964         else if (i < 0 || i > ctx->num_buffers) {
    965             rc = -EINVAL;
    966         } else {
    967             *((int *)buffer) = i;
    968             ctx->qd_buf_count --;
    969         }
    970     } else {
    971         rc = -1;
    972     }
    973 
    974     return rc;
    975 }
    976 
    977 int overlay_queueBuffer(struct overlay_data_device_t *dev,
    978                         overlay_buffer_t buffer) {
    979 
    980     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
    981 
    982     pthread_mutex_lock(&ctx->shared->lock);
    983     if ( ctx->shared->streamingReset )
    984     {
    985         ctx->shared->streamingReset = 0;
    986         pthread_mutex_unlock(&ctx->shared->lock);
    987         return ALL_BUFFERS_FLUSHED;
    988     }
    989     pthread_mutex_unlock(&ctx->shared->lock);
    990 
    991     // Catch the case where the data side had no need to set the crop window
    992     if (!ctx->shared->dataReady) {
    993         ctx->shared->dataReady = 1;
    994         enable_streaming(ctx->shared, ctx->ctl_fd);
    995     }
    996 
    997     int rc = v4l2_overlay_q_buf( ctx->ctl_fd, (int)buffer );
    998     if (rc == 0 && ctx->qd_buf_count < ctx->num_buffers) {
    999         ctx->qd_buf_count ++;
   1000     }
   1001 
   1002     return rc;
   1003 }
   1004 
   1005 void *overlay_getBufferAddress(struct overlay_data_device_t *dev,
   1006                                overlay_buffer_t buffer)
   1007 {
   1008     LOG_FUNCTION_NAME;
   1009 
   1010     /* this may fail (NULL) if this feature is not supported. In that case,
   1011      * presumably, there is some other HAL module that can fill the buffer,
   1012      * using a DSP for instance
   1013      */
   1014     int ret;
   1015     struct v4l2_buffer buf;
   1016     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1017 
   1018     ret = v4l2_overlay_query_buffer(ctx->ctl_fd, (int)buffer, &buf);
   1019 
   1020     if (ret)
   1021         return NULL;
   1022 
   1023     // Initialize ctx->mapping_data
   1024     memset(ctx->mapping_data, 0, sizeof(mapping_data_t));
   1025 
   1026     ctx->mapping_data->fd = ctx->ctl_fd;
   1027     ctx->mapping_data->length = buf.length;
   1028     ctx->mapping_data->offset = buf.m.offset;
   1029     ctx->mapping_data->ptr = NULL;
   1030 
   1031     if ((int)buffer >= 0 && (int)buffer < ctx->num_buffers) {
   1032         ctx->mapping_data->ptr = ctx->buffers[(int)buffer];
   1033         LOGI("Buffer/%d/addr=%08lx/len=%d", (int)buffer, (unsigned long)ctx->mapping_data->ptr,
   1034              ctx->buffers_len[(int)buffer]);
   1035     }
   1036 
   1037     return (void *)ctx->mapping_data;
   1038 }
   1039 
   1040 int overlay_getBufferCount(struct overlay_data_device_t *dev)
   1041 {
   1042     LOG_FUNCTION_NAME;
   1043 
   1044     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1045 
   1046     return (ctx->num_buffers);
   1047 }
   1048 
   1049 static int overlay_data_close(struct hw_device_t *dev) {
   1050 
   1051     LOG_FUNCTION_NAME;
   1052 
   1053     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1054     int rc;
   1055 
   1056     if (ctx) {
   1057         overlay_data_device_t *overlay_dev = &ctx->device;
   1058         int buf;
   1059         int i;
   1060 
   1061         pthread_mutex_lock(&ctx->shared->lock);
   1062 
   1063         for (i = 0; i < ctx->num_buffers; i++) {
   1064             LOGV("Unmap Buffer/%d/%08lx/%d", i, (unsigned long)ctx->buffers[i], ctx->buffers_len[i] );
   1065             rc = v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]);
   1066             if (rc != 0) {
   1067                 LOGE("Error unmapping the buffer/%d/%d", i, rc);
   1068             }
   1069         }
   1070 
   1071         delete(ctx->mapping_data);
   1072         delete(ctx->buffers);
   1073         delete(ctx->buffers_len);
   1074 
   1075         pthread_mutex_unlock(&ctx->shared->lock);
   1076 
   1077         ctx->shared->dataReady = 0;
   1078         close_shared_data( ctx );
   1079 
   1080         free(ctx);
   1081     }
   1082 
   1083     return 0;
   1084 }
   1085 
   1086 /*****************************************************************************/
   1087 
   1088 static int overlay_device_open(const struct hw_module_t* module,
   1089                                const char* name, struct hw_device_t** device)
   1090 {
   1091     LOG_FUNCTION_NAME;
   1092     int status = -EINVAL;
   1093 
   1094     if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) {
   1095         struct overlay_control_context_t *dev;
   1096         dev = (overlay_control_context_t*)malloc(sizeof(*dev));
   1097 
   1098         /* initialize our state here */
   1099         memset(dev, 0, sizeof(*dev));
   1100 
   1101         /* initialize the procs */
   1102         dev->device.common.tag = HARDWARE_DEVICE_TAG;
   1103         dev->device.common.version = 0;
   1104         dev->device.common.module = const_cast<hw_module_t*>(module);
   1105         dev->device.common.close = overlay_control_close;
   1106 
   1107         dev->device.get = overlay_get;
   1108         dev->device.createOverlay = overlay_createOverlay;
   1109         dev->device.destroyOverlay = overlay_destroyOverlay;
   1110         dev->device.setPosition = overlay_setPosition;
   1111         dev->device.getPosition = overlay_getPosition;
   1112         dev->device.setParameter = overlay_setParameter;
   1113         dev->device.stage = overlay_stage;
   1114         dev->device.commit = overlay_commit;
   1115 
   1116         *device = &dev->device.common;
   1117         status = 0;
   1118     } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) {
   1119         struct overlay_data_context_t *dev;
   1120         dev = (overlay_data_context_t*)malloc(sizeof(*dev));
   1121 
   1122         /* initialize our state here */
   1123         memset(dev, 0, sizeof(*dev));
   1124 
   1125         /* initialize the procs */
   1126         dev->device.common.tag = HARDWARE_DEVICE_TAG;
   1127         dev->device.common.version = 0;
   1128         dev->device.common.module = const_cast<hw_module_t*>(module);
   1129         dev->device.common.close = overlay_data_close;
   1130 
   1131         dev->device.initialize = overlay_initialize;
   1132         dev->device.resizeInput = overlay_resizeInput;
   1133         dev->device.setCrop = overlay_setCrop;
   1134         dev->device.getCrop = overlay_getCrop;
   1135         dev->device.setParameter = overlay_data_setParameter;
   1136         dev->device.dequeueBuffer = overlay_dequeueBuffer;
   1137         dev->device.queueBuffer = overlay_queueBuffer;
   1138         dev->device.getBufferAddress = overlay_getBufferAddress;
   1139         dev->device.getBufferCount = overlay_getBufferCount;
   1140 
   1141         *device = &dev->device.common;
   1142         status = 0;
   1143     }
   1144     return status;
   1145 }
   1146