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 "SEC_Overlay"
     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 #include "linux/fb.h"
     41 
     42 /*****************************************************************************/
     43 
     44 #define LOG_FUNCTION_NAME LOGV(" %s %s",  __FILE__, __func__)
     45 
     46 #define NUM_OVERLAY_BUFFERS_REQUESTED  (3)
     47 /* OVRLYSHM on phone keypad*/
     48 #define SHARED_DATA_MARKER             (0x68759746)
     49 
     50 /* These values should come from Surface Flinger */
     51 unsigned int g_lcd_width = 480;
     52 unsigned int g_lcd_height = 800;
     53 unsigned int g_lcd_bpp = 32;
     54 
     55 #define CACHEABLE_BUFFERS 0x1
     56 
     57 /* shared with Camera/Video Playback HAL */
     58 #define ALL_BUFFERS_FLUSHED -66
     59 
     60 uint32_t phyAddr;
     61 s5p_fimc_t g_s5p_fimc;
     62 
     63 typedef struct
     64 {
     65     uint32_t posX;
     66     uint32_t posY;
     67     uint32_t posW;
     68     uint32_t posH;
     69     uint32_t rotation;
     70     uint32_t flip;
     71 
     72     uint32_t posX_org;
     73     uint32_t posY_org;
     74     uint32_t posW_org;
     75     uint32_t posH_org;
     76 
     77 } overlay_ctrl_t;
     78 
     79 typedef struct
     80 {
     81     uint32_t cropX;
     82     uint32_t cropY;
     83     uint32_t cropW;
     84     uint32_t cropH;
     85 } overlay_data_t;
     86 
     87 typedef struct
     88 {
     89     uint32_t marker;
     90     uint32_t size;
     91 
     92     volatile int32_t refCnt;
     93 
     94     uint32_t controlReady; /* Only updated by the control side */
     95     uint32_t dataReady;    /* Only updated by the data side */
     96 
     97     pthread_mutex_t lock;
     98     pthread_mutexattr_t attr;
     99 
    100     uint32_t streamEn;
    101     uint32_t streamingReset;
    102 
    103     uint32_t dispW;
    104     uint32_t dispH;
    105 
    106 } overlay_shared_t;
    107 
    108 /* Only one instance is created per platform */
    109 struct overlay_control_context_t {
    110     struct overlay_control_device_t device;
    111     /* our private state goes below here */
    112     struct overlay_t* overlay_video1;
    113     struct overlay_t* overlay_video2;
    114 };
    115 
    116 /* A separate instance is created per overlay data side user*/
    117 struct overlay_data_context_t {
    118     struct overlay_data_device_t device;
    119     /* our private state goes below here */
    120     int ctl_fd;
    121     int shared_fd;
    122     int shared_size;
    123     int width;
    124     int height;
    125     int format;
    126     int num_buffers;
    127     size_t *buffers_len;
    128     void **buffers;
    129 
    130     overlay_data_t    data;
    131     overlay_shared_t  *shared;
    132     struct mapping_data    *mapping_data;
    133     /* Need to count Qd buffers
    134        to be sure we don't block DQ'ing when exiting */
    135     int qd_buf_count;
    136     int cacheable_buffers;
    137 
    138     bool zerocopy;
    139 };
    140 
    141 static int  create_shared_data(overlay_shared_t **shared);
    142 static void destroy_shared_data(int shared_fd, overlay_shared_t *shared,
    143                                 bool closefd);
    144 static int  open_shared_data(overlay_data_context_t *ctx);
    145 static void close_shared_data(overlay_data_context_t *ctx);
    146 enum { LOCK_REQUIRED = 1, NO_LOCK_NEEDED = 0 };
    147 static int  enable_streaming(overlay_shared_t *shared, int ovly_fd,
    148                              int lock_required );
    149 
    150 static int overlay_device_open(const struct hw_module_t* module,
    151         const char* name, struct hw_device_t** device);
    152 
    153 static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc,
    154                                       unsigned int rotation);
    155 static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc);
    156 
    157 static struct hw_module_methods_t overlay_module_methods = {
    158 open: overlay_device_open
    159 };
    160 
    161 struct overlay_module_t HAL_MODULE_INFO_SYM = {
    162 common: {
    163 tag: HARDWARE_MODULE_TAG,
    164      version_major: 1,
    165      version_minor: 0,
    166      id: OVERLAY_HARDWARE_MODULE_ID,
    167      name: "SEC Overlay module",
    168      author: "The Android Open Source Project",
    169      methods: &overlay_module_methods,
    170         }
    171 };
    172 
    173 /*****************************************************************************/
    174 
    175 /*
    176  * This is the overlay_t object, it is returned to the user and represents
    177  * an overlay. here we use a subclass, where we can store our own state.
    178  * This handles will be passed across processes and possibly given to other
    179  * HAL modules (for instance video decode modules).
    180  */
    181 struct handle_t : public native_handle {
    182     /* add the data fields we need here, for instance: */
    183     int ctl_fd;
    184     int shared_fd;
    185     int width;
    186     int height;
    187     int format;
    188     int num_buffers;
    189     int shared_size;
    190 };
    191 
    192 static int handle_format(const overlay_handle_t overlay) {
    193     return static_cast<const struct handle_t *>(overlay)->format;
    194 }
    195 
    196 static int handle_ctl_fd(const overlay_handle_t overlay) {
    197     return static_cast<const struct handle_t *>(overlay)->ctl_fd;
    198 }
    199 
    200 static int handle_shared_fd(const overlay_handle_t overlay) {
    201     return static_cast<const struct handle_t *>(overlay)->shared_fd;
    202 }
    203 
    204 static int handle_num_buffers(const overlay_handle_t overlay) {
    205     return static_cast<const struct handle_t *>(overlay)->num_buffers;
    206 }
    207 
    208 static int handle_width(const overlay_handle_t overlay) {
    209     return static_cast<const struct handle_t *>(overlay)->width;
    210 }
    211 
    212 static int handle_height(const overlay_handle_t overlay) {
    213     return static_cast<const struct handle_t *>(overlay)->height;
    214 }
    215 
    216 static int handle_shared_size(const overlay_handle_t overlay) {
    217     return static_cast<const struct handle_t *>(overlay)->shared_size;
    218 }
    219 
    220 /* A separate instance of this class is created per overlay */
    221 class overlay_object : public overlay_t
    222 {
    223     handle_t mHandle;
    224 
    225     overlay_ctrl_t    mCtl;
    226     overlay_ctrl_t    mCtlStage;
    227     overlay_shared_t *mShared;
    228 
    229     static overlay_handle_t getHandleRef(struct overlay_t* overlay) {
    230         /* returns a reference to the handle, caller doesn't take ownership */
    231         return &(static_cast<overlay_object *>(overlay)->mHandle);
    232     }
    233 
    234     public:
    235     overlay_object(int ctl_fd, int shared_fd, int shared_size, int w, int h,
    236             int format, int num_buffers) {
    237         this->overlay_t::getHandleRef = getHandleRef;
    238         mHandle.version     = sizeof(native_handle);
    239         mHandle.numFds      = 2;
    240         mHandle.numInts     = 5; /* extra ints we have in our handle */
    241         mHandle.ctl_fd      = ctl_fd;
    242         mHandle.shared_fd   = shared_fd;
    243         mHandle.width       = w;
    244         mHandle.height      = h;
    245         mHandle.format      = format;
    246         mHandle.num_buffers = num_buffers;
    247         mHandle.shared_size = shared_size;
    248         this->w = w;
    249         this->h = h;
    250         this->format = format;
    251 
    252         memset( &mCtl, 0, sizeof( mCtl ) );
    253         memset( &mCtlStage, 0, sizeof( mCtlStage ) );
    254     }
    255 
    256     int               ctl_fd()    { return mHandle.ctl_fd; }
    257     int               shared_fd() { return mHandle.shared_fd; }
    258     overlay_ctrl_t*   data()      { return &mCtl; }
    259     overlay_ctrl_t*   staging()   { return &mCtlStage; }
    260     overlay_shared_t* getShared() { return mShared; }
    261     void              setShared( overlay_shared_t *p ) { mShared = p; }
    262 };
    263 
    264 /*****************************************************************************
    265  *  Local Functions
    266  *****************************************************************************/
    267 
    268 static int create_shared_data(overlay_shared_t **shared)
    269 {
    270     int fd;
    271     /* assuming sizeof(overlay_shared_t) < a single page */
    272     int size = getpagesize();
    273     overlay_shared_t *p;
    274 
    275     if ((fd = ashmem_create_region("overlay_data", size)) < 0) {
    276         LOGE("Failed to Create Overlay Shared Data!\n");
    277         return fd;
    278     }
    279 
    280     p = (overlay_shared_t*)mmap(NULL, size, PROT_READ | PROT_WRITE,
    281             MAP_SHARED, fd, 0);
    282     if (p == MAP_FAILED) {
    283         LOGE("Failed to Map Overlay Shared Data!\n");
    284         close(fd);
    285         return -1;
    286     }
    287 
    288     memset(p, 0, size);
    289     p->marker = SHARED_DATA_MARKER;
    290     p->size   = size;
    291     p->refCnt = 1;
    292     if (pthread_mutexattr_init(&p->attr) != 0) {
    293         LOGE("Failed to initialize overlay mutex attr");
    294         goto MutexAttrErr;
    295     }
    296     if (pthread_mutexattr_setpshared(&p->attr, PTHREAD_PROCESS_SHARED) != 0) {
    297         LOGE("Failed to set the overlay mutex attr to be shared across-processes");
    298         goto MutexAttrSetErr;
    299     }
    300     if (pthread_mutex_init(&p->lock, &p->attr) != 0) {
    301         LOGE("Failed to initialize overlay mutex\n");
    302         goto MutexErr;
    303     }
    304 
    305     *shared = p;
    306     return fd;
    307 
    308 MutexErr:
    309 MutexAttrSetErr:
    310     pthread_mutexattr_destroy(&p->attr);
    311 MutexAttrErr:
    312     munmap(p, size);
    313     close(fd);
    314     return -1;
    315 }
    316 
    317 static void destroy_shared_data(int shared_fd, overlay_shared_t *shared,
    318                                 bool closefd )
    319 {
    320     if (shared == NULL)
    321         return;
    322 
    323     /* Last side deallocated releases the mutex, otherwise the remaining */
    324     /* side will deadlock trying to use an already released mutex */
    325     if (android_atomic_dec(&shared->refCnt) == 1) {
    326         if (pthread_mutex_destroy(&shared->lock)) {
    327             LOGE("Failed to uninitialize overlay mutex!\n");
    328         }
    329 
    330         if (pthread_mutexattr_destroy(&shared->attr)) {
    331             LOGE("Failed to uninitialize the overlay mutex attr!\n");
    332         }
    333         shared->marker = 0;
    334     }
    335 
    336     if (munmap(shared, shared->size)) {
    337         LOGE("Failed to Unmap Overlay Shared Data!\n");
    338     }
    339 
    340     if (closefd && close(shared_fd)) {
    341         LOGE("Failed to Close Overlay Shared Data!\n");
    342     }
    343 }
    344 
    345 static int open_shared_data( overlay_data_context_t *ctx )
    346 {
    347     int rc   = -1;
    348     int mode = PROT_READ | PROT_WRITE;
    349     int fd   = ctx->shared_fd;
    350     int size = ctx->shared_size;
    351 
    352     if (ctx->shared != NULL) {
    353         /* Already open, return success */
    354         LOGI("Overlay Shared Data Already Open\n");
    355         return 0;
    356     }
    357     ctx->shared = (overlay_shared_t*)mmap(0, size, mode, MAP_SHARED, fd, 0);
    358 
    359     if (ctx->shared == MAP_FAILED) {
    360         LOGE("Failed to Map Overlay Shared Data!\n");
    361     } else if ( ctx->shared->marker != SHARED_DATA_MARKER ) {
    362         LOGE("Invalid Overlay Shared Marker!\n");
    363         munmap( ctx->shared, size);
    364     } else if ( (int)ctx->shared->size != size ) {
    365         LOGE("Invalid Overlay Shared Size!\n");
    366         munmap(ctx->shared, size);
    367     } else {
    368         android_atomic_inc(&ctx->shared->refCnt);
    369         rc = 0;
    370     }
    371 
    372     return rc;
    373 }
    374 
    375 static void close_shared_data(overlay_data_context_t *ctx)
    376 {
    377     destroy_shared_data(ctx->shared_fd, ctx->shared, false);
    378     ctx->shared = NULL;
    379 }
    380 
    381 static int enable_streaming_locked(overlay_shared_t *shared, int ovly_fd)
    382 {
    383     int rc = 0;
    384 
    385     if (!shared->controlReady || !shared->dataReady) {
    386         LOGI("Postponing Stream Enable/%d/%d\n", shared->controlReady,
    387                 shared->dataReady);
    388     } else {
    389         shared->streamEn = 1;
    390         rc = v4l2_overlay_stream_on(ovly_fd);
    391         if (rc) {
    392             LOGE("Stream Enable Failed!/%d\n", rc);
    393             shared->streamEn = 0;
    394         }
    395     }
    396 
    397     return rc;
    398 }
    399 
    400 static int enable_streaming(overlay_shared_t *shared, int ovly_fd)
    401 {
    402     int ret;
    403 
    404     pthread_mutex_lock(&shared->lock);
    405     ret = enable_streaming_locked(shared, ovly_fd);
    406     pthread_mutex_unlock(&shared->lock);
    407     return ret;
    408 }
    409 
    410 static int disable_streaming_locked(overlay_shared_t *shared, int ovly_fd)
    411 {
    412     int ret = 0;
    413 
    414     if (shared->streamEn) {
    415         ret = v4l2_overlay_stream_off( ovly_fd );
    416         if (ret) {
    417             LOGE("Stream Off Failed!/%d\n", ret);
    418         } else {
    419             shared->streamingReset = 1;
    420             shared->streamEn = 0;
    421         }
    422     }
    423 
    424     return ret;
    425 }
    426 
    427 static void set_color_space(unsigned int overlay_color_format, unsigned int *v4l2_color_format)
    428 {
    429     switch (overlay_color_format) {
    430     case OVERLAY_FORMAT_RGB_565:
    431         *v4l2_color_format = V4L2_PIX_FMT_RGB565;
    432         break;
    433 
    434     case OVERLAY_FORMAT_YCbYCr_422_I:
    435     case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
    436         *v4l2_color_format = V4L2_PIX_FMT_YUYV;
    437         break;
    438 
    439     case OVERLAY_FORMAT_CbYCrY_422_I:
    440     case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
    441         *v4l2_color_format = V4L2_PIX_FMT_UYVY;
    442         break;
    443 
    444     case HAL_PIXEL_FORMAT_YCbCr_420_P:
    445         *v4l2_color_format = V4L2_PIX_FMT_YUV420;
    446         break;
    447 
    448     case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
    449         *v4l2_color_format = V4L2_PIX_FMT_NV12T;
    450         break;
    451 
    452     case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
    453         *v4l2_color_format = V4L2_PIX_FMT_NV21;
    454         break;
    455 
    456     default :
    457         LOGE("unsupported pixel format (0x%x)", overlay_color_format);
    458         *v4l2_color_format = -1;
    459     }
    460 }
    461 
    462 /****************************************************************************
    463  *  Control module
    464  *****************************************************************************/
    465 
    466 static int overlay_get(struct overlay_control_device_t *dev, int name)
    467 {
    468     int result = -1;
    469 
    470     switch (name) {
    471     /* 0 = no limit */
    472     case OVERLAY_MINIFICATION_LIMIT:   result = 0;  break;
    473     /* 0 = no limit */
    474     case OVERLAY_MAGNIFICATION_LIMIT:  result = 0;  break;
    475     /* 0 = infinite */
    476     case OVERLAY_SCALING_FRAC_BITS:    result = 0;  break;
    477     /* 90 rotation steps (for instance) */
    478     case OVERLAY_ROTATION_STEP_DEG:    result = 90; break;
    479     /* 1-pixel alignment */
    480     case OVERLAY_HORIZONTAL_ALIGNMENT: result = 1;  break;
    481     /* 1-pixel alignment */
    482     case OVERLAY_VERTICAL_ALIGNMENT:   result = 1;  break;
    483     /* 1-pixel alignment */
    484     case OVERLAY_WIDTH_ALIGNMENT:      result = 1;  break;
    485     case OVERLAY_HEIGHT_ALIGNMENT:     break;
    486     }
    487 
    488     return result;
    489 }
    490 
    491 static int get_fb_var_screeninfo( struct fb_var_screeninfo *info )
    492 {
    493     int fd = -1;
    494     int i=0;
    495     char name[64];
    496     int ret = 0;
    497 
    498     char const * const device_template[] = {
    499         "/dev/graphics/fb%u",
    500         "/dev/fb%u",
    501         0 };
    502 
    503     while ((fd==-1) && device_template[i]) {
    504         snprintf(name, 64, device_template[i], 0);
    505         fd = open(name, O_RDWR, 0);
    506         i++;
    507     }
    508 
    509     if (fd < 0)
    510         ret = -EINVAL;
    511 
    512     if (ioctl(fd, FBIOGET_VSCREENINFO, info) == -1)
    513         ret = -EINVAL;
    514 
    515     if (fd > 0)
    516         close(fd);
    517 
    518     return 0;
    519 }
    520 static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev,
    521         uint32_t w, uint32_t h, int32_t  format)
    522 {
    523     LOGD("overlay_createOverlay:IN w=%d h=%d format=%d\n", w, h, format);
    524     LOG_FUNCTION_NAME;
    525 
    526     overlay_object            *overlay;
    527     overlay_control_context_t *ctx = (overlay_control_context_t *)dev;
    528     overlay_shared_t          *shared;
    529 
    530     int ret;
    531     uint32_t num = NUM_OVERLAY_BUFFERS_REQUESTED;
    532     int fd;
    533     int shared_fd;
    534     struct fb_var_screeninfo info;
    535     bool zerocopy = false;
    536 
    537     phyAddr = 0;
    538 
    539     if (format == OVERLAY_FORMAT_DEFAULT) {
    540         LOGV("format == OVERLAY_FORMAT_DEFAULT\n");
    541         LOGV("set to HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP\n");
    542         format = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP;
    543     }
    544 
    545     if (ctx->overlay_video1) {
    546         LOGE("Error - overlays already in use\n");
    547         return NULL;
    548     }
    549 
    550     shared_fd = create_shared_data(&shared);
    551     if (shared_fd < 0) {
    552         LOGE("Failed to create shared data");
    553         return NULL;
    554     }
    555 
    556     fd = v4l2_overlay_open(V4L2_OVERLAY_PLANE_VIDEO1);
    557     if (fd < 0) {
    558         LOGE("Failed to open overlay device : %s\n", strerror(errno));
    559         goto error;
    560     }
    561 
    562     g_s5p_fimc.params.src.full_width = w;
    563     g_s5p_fimc.params.src.full_height = h;
    564     g_s5p_fimc.params.src.width = w;
    565     g_s5p_fimc.params.src.height = h;
    566     set_color_space(format, &g_s5p_fimc.params.src.color_space);
    567     ret = check_fimc_src_constraints(&g_s5p_fimc);
    568     if(ret != 0) {
    569         if(ret < 0) {
    570             LOGE("Not supported source image size");
    571             goto error1;
    572         } else {
    573             LOGD("src width, height are changed [w= %d, h= %d]->[w=%d, h= %d]"
    574                  , w, h, g_s5p_fimc.params.src.width
    575                  , g_s5p_fimc.params.src.height);
    576             w = g_s5p_fimc.params.src.width;
    577             h = g_s5p_fimc.params.src.height;
    578         }
    579     }
    580 
    581     if (v4l2_overlay_init(fd, w, h, format, phyAddr)) {
    582         LOGE("Failed initializing overlays\n");
    583         goto error1;
    584     }
    585 
    586     if (v4l2_overlay_set_crop(fd, 0, 0, w, h)) {
    587         LOGE("Failed defaulting crop window\n");
    588         goto error1;
    589     }
    590 
    591     if (v4l2_overlay_set_flip(fd, 0)) {
    592         LOGE("Failed defaulting flip\n");
    593         goto error1;
    594     }
    595 
    596     if (v4l2_overlay_set_rotation(fd, 0, 0)) {
    597         LOGE("Failed defaulting rotation\n");
    598         goto error1;
    599     }
    600 
    601     if (format >= HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP
    602             && format < HAL_PIXEL_FORMAT_CUSTOM_MAX)
    603         zerocopy = true;
    604 
    605     if (v4l2_overlay_req_buf(fd, &num, 0, (int)zerocopy)) {
    606         LOGE("Failed requesting buffers\n");
    607         goto error1;
    608     }
    609 
    610     v4l2_overlay_init_fimc(fd, &g_s5p_fimc);
    611 
    612     overlay = new overlay_object(fd, shared_fd, shared->size,
    613                                  w, h, format, num);
    614     if (overlay == NULL) {
    615         LOGE("Failed to create overlay object\n");
    616         goto error1;
    617     }
    618     ctx->overlay_video1 = overlay;
    619 
    620     overlay->setShared(shared);
    621 
    622     shared->controlReady = 0;
    623     shared->streamEn = 0;
    624     shared->streamingReset = 0;
    625 
    626     /* get lcd size from kernel framebuffer */
    627     if(get_fb_var_screeninfo(&info) == 0) {
    628         shared->dispW = info.xres;
    629         shared->dispH = info.yres;
    630         g_lcd_width = info.xres;
    631         g_lcd_height = info.yres;
    632         g_lcd_bpp = info.bits_per_pixel;
    633     } else {
    634         shared->dispW = g_lcd_width; /* Need to determine this properly */
    635         shared->dispH = g_lcd_height; /* Need to determine this properly */
    636     }
    637 
    638     LOGI("Opened video1/fd=%d/obj=%08lx/shm=%d/size=%d", fd,
    639             (unsigned long)overlay, shared_fd, shared->size);
    640 
    641     return overlay;
    642 
    643 error1:
    644     close(fd);
    645 error:
    646     destroy_shared_data(shared_fd, shared, true);
    647     return NULL;
    648 }
    649 
    650 static void overlay_destroyOverlay(struct overlay_control_device_t *dev,
    651         overlay_t* overlay)
    652 {
    653     LOGD("overlay_destroyOverlay:IN dev (%p) and overlay (%p)", dev, overlay);
    654     LOG_FUNCTION_NAME;
    655 
    656     overlay_control_context_t *ctx = (overlay_control_context_t *)dev;
    657     overlay_object *obj = static_cast<overlay_object *>(overlay);
    658 
    659     int rc;
    660     int fd = obj->ctl_fd();
    661     uint32_t num = 0;
    662 
    663     overlay_shared_t *shared = obj->getShared();
    664 
    665     if (shared == NULL) {
    666         LOGE("Overlay was already destroyed - nothing needs to be done\n");
    667         return;
    668     }
    669 
    670     pthread_mutex_lock(&shared->lock);
    671 
    672     disable_streaming_locked(shared, fd);
    673 
    674     pthread_mutex_unlock(&shared->lock);
    675 
    676     destroy_shared_data(obj->shared_fd(), shared, true);
    677     obj->setShared(NULL);
    678 
    679     if (v4l2_overlay_req_buf(fd, &num, 0, 0)) {
    680         LOGE("Failed requesting buffers\n");
    681     }
    682 
    683     LOGI("Destroying overlay/fd=%d/obj=%08lx", fd, (unsigned long)overlay);
    684 
    685     if (close(fd)) {
    686         LOGE( "Error closing overly fd/%d\n", errno);
    687     }
    688 
    689     if (overlay) {
    690         if (ctx->overlay_video1 == overlay)
    691             ctx->overlay_video1 = NULL;
    692         delete overlay;
    693         overlay = NULL;
    694     }
    695     LOGD("overlay_destroyOverlay:OUT");
    696 }
    697 
    698 static int overlay_setPosition(struct overlay_control_device_t *dev,
    699         overlay_t* overlay, int x, int y, uint32_t w,
    700         uint32_t h)
    701 {
    702     LOG_FUNCTION_NAME;
    703 
    704     overlay_object *obj = static_cast<overlay_object *>(overlay);
    705 
    706     overlay_ctrl_t   *stage  = obj->staging();
    707     overlay_shared_t *shared = obj->getShared();
    708 
    709     int rc = 0;
    710     int temp_x = x, temp_y = y, temp_w = w, temp_h = h;
    711 
    712     /*
    713      * This logic here is to return an error if the rectangle is not fully
    714      * within the display, unless we have not received a valid position yet,
    715      * in which case we will do our best to adjust the rectangle to be within
    716      * the display.
    717      */
    718 
    719     /* Require a minimum size */
    720     if (temp_w < 16)
    721         temp_w = 16;
    722     if (temp_h < 8)
    723         temp_h = 8;
    724 
    725     if (!shared->controlReady) {
    726         if ( temp_x < 0 ) temp_x = 0;
    727         if ( temp_y < 0 ) temp_y = 0;
    728         if ( temp_w > shared->dispW ) temp_w = shared->dispW;
    729         if ( temp_h > shared->dispH ) temp_h = shared->dispH;
    730         if ( (temp_x + temp_w) > shared->dispW ) temp_w = shared->dispW - temp_x;
    731         if ( (temp_y + temp_h) > shared->dispH ) temp_h = shared->dispH - temp_y;
    732     } else if (temp_x < 0 || temp_y < 0 || (temp_x + temp_w) > shared->dispW ||
    733             (temp_y + temp_h) > shared->dispH) {
    734         /* Return an error */
    735         rc = -1;
    736     }
    737 
    738     if (rc == 0) {
    739         stage->posX = temp_x;
    740         stage->posY = temp_y;
    741         stage->posW = temp_w;
    742         stage->posH = temp_h;
    743 
    744         stage->posX_org = x;
    745         stage->posY_org = y;
    746         stage->posW_org = w;
    747         stage->posH_org = h;
    748     }
    749 
    750     return rc;
    751 }
    752 
    753 static int overlay_getPosition(struct overlay_control_device_t *dev,
    754         overlay_t* overlay, int* x, int* y, uint32_t* w,
    755         uint32_t* h)
    756 {
    757     LOG_FUNCTION_NAME;
    758 
    759     overlay_object *obj = static_cast<overlay_object *>(overlay);
    760     overlay_ctrl_t   *stage  = obj->staging();
    761 
    762     *x = stage->posX_org;
    763     *y = stage->posY_org;
    764     *w = stage->posW_org;
    765     *h = stage->posH_org;
    766 
    767     return 0;
    768 }
    769 
    770 static int overlay_setParameter(struct overlay_control_device_t *dev,
    771         overlay_t* overlay, int param, int value)
    772 {
    773     LOG_FUNCTION_NAME;
    774 
    775     overlay_ctrl_t *stage = static_cast<overlay_object *>(overlay)->staging();
    776     int rc = 0;
    777 
    778     switch (param) {
    779     case OVERLAY_DITHER:
    780         break;
    781 
    782     case OVERLAY_TRANSFORM:
    783         switch ( value )
    784         {
    785         case 0:
    786             stage->rotation = 0;
    787             stage->flip = 0;
    788             break;
    789         case OVERLAY_TRANSFORM_ROT_90:
    790             stage->rotation = 90;
    791             stage->flip = 0;
    792             break;
    793         case OVERLAY_TRANSFORM_ROT_180:
    794             stage->rotation = 180;
    795             stage->flip = 0;
    796             break;
    797         case OVERLAY_TRANSFORM_ROT_270:
    798             stage->rotation = 270;
    799             stage->flip = 0;
    800             break;
    801         // FIMC VFLIP = android overlay FLIP_H.
    802         case OVERLAY_TRANSFORM_FLIP_H:
    803             stage->rotation = 0;
    804             stage->flip = V4L2_CID_VFLIP;
    805             break;
    806         case OVERLAY_TRANSFORM_FLIP_V:
    807             stage->rotation = 0;
    808             stage->flip = V4L2_CID_HFLIP;
    809             break;
    810         // FIMC rotates first but android flips first.
    811         case OVERLAY_TRANSFORM_ROT_90+OVERLAY_TRANSFORM_FLIP_H:
    812             stage->rotation = 90;
    813             stage->flip = V4L2_CID_HFLIP;
    814             break;
    815         case OVERLAY_TRANSFORM_ROT_90+OVERLAY_TRANSFORM_FLIP_V:
    816             stage->rotation = 90;
    817             stage->flip = V4L2_CID_VFLIP;
    818             break;
    819 
    820         default:
    821             rc = -EINVAL;
    822             break;
    823         }
    824         break;
    825     }
    826 
    827     return rc;
    828 }
    829 
    830 static int overlay_stage(struct overlay_control_device_t *dev,
    831         overlay_t* overlay) {
    832     return 0;
    833 }
    834 
    835 static int overlay_commit(struct overlay_control_device_t *dev,
    836         overlay_t* overlay) {
    837     LOG_FUNCTION_NAME;
    838 
    839     overlay_object *obj = static_cast<overlay_object *>(overlay);
    840 
    841     overlay_ctrl_t   *data   = obj->data();
    842     overlay_ctrl_t   *stage  = obj->staging();
    843     overlay_shared_t *shared = obj->getShared();
    844 
    845     int ret = 0;
    846     int fd = obj->ctl_fd();
    847 
    848     if (shared == NULL) {
    849         LOGI("Shared Data Not Init'd!\n");
    850         return -1;
    851     }
    852 
    853     pthread_mutex_lock(&shared->lock);
    854 
    855     if (!shared->controlReady) {
    856         shared->controlReady = 1;
    857     }
    858 
    859     g_s5p_fimc.params.dst.full_width = g_lcd_width;
    860     g_s5p_fimc.params.dst.full_height = g_lcd_height;
    861     g_s5p_fimc.params.dst.width = stage->posW;
    862     g_s5p_fimc.params.dst.height = stage->posH;
    863     if (g_lcd_bpp == 32)
    864         g_s5p_fimc.params.dst.color_space = V4L2_PIX_FMT_RGB32;
    865     else
    866         g_s5p_fimc.params.dst.color_space = V4L2_PIX_FMT_RGB565;
    867     ret = check_fimc_dst_constraints(&g_s5p_fimc, stage->rotation);
    868     if (ret != 0) {
    869         if (ret < 0) {
    870             LOGE("Unsupported destination image size");
    871             goto end;
    872         } else {
    873             LOGD("dst width, height have changed [w= %d, h= %d] -> [w=%d, h= %d]",
    874                     stage->posW, stage->posH, g_s5p_fimc.params.dst.width,
    875                     g_s5p_fimc.params.dst.height);
    876             stage->posW = g_s5p_fimc.params.dst.width;
    877             stage->posH = g_s5p_fimc.params.dst.height;
    878         }
    879     }
    880 
    881     if (data->posX == stage->posX && data->posY == stage->posY &&
    882             data->posW == stage->posW && data->posH == stage->posH &&
    883             data->rotation == stage->rotation &&
    884             data->flip == stage->flip) {
    885         LOGI("Nothing to do!\n");
    886         goto end;
    887     }
    888 
    889     LOGV("Position/X%d/Y%d/W%d/H%d\n", data->posX, data->posY, data->posW,
    890             data->posH);
    891     LOGV("Adjusted Position/X%d/Y%d/W%d/H%d\n", stage->posX, stage->posY,
    892             stage->posW, stage->posH);
    893     LOGV("Rotation/%d\n", stage->rotation );
    894 
    895     if ((ret = disable_streaming_locked(shared, fd)))
    896         goto end;
    897 
    898     if (stage->flip != data->flip) {
    899         ret = v4l2_overlay_set_flip(fd, stage->flip);
    900         if (ret) {
    901             LOGE("Set Flip Failed!/%d\n", ret);
    902             goto end;
    903         }
    904     }
    905 
    906     if (stage->rotation != data->rotation) {
    907         ret = v4l2_overlay_set_rotation(fd, stage->rotation, 0);
    908         if (ret) {
    909             LOGE("Set Rotation Failed!/%d\n", ret);
    910             goto end;
    911         }
    912         v4l2_overlay_s_fbuf(fd, stage->rotation);
    913     }
    914 
    915     ret = v4l2_overlay_set_position(fd, stage->posX, stage->posY,
    916             stage->posW, stage->posH, stage->rotation);
    917     if (ret) {
    918         LOGE("Set Position Failed!/%d\n", ret);
    919         goto end;
    920     }
    921 
    922     data->posX = stage->posX;
    923     data->posY = stage->posY;
    924     data->posW = stage->posW;
    925     data->posH = stage->posH;
    926     data->rotation = stage->rotation;
    927     data->flip = stage->flip;
    928 
    929     ret = enable_streaming_locked(shared, fd);
    930 
    931 end:
    932     pthread_mutex_unlock(&shared->lock);
    933 
    934     return ret;
    935 }
    936 
    937 static int overlay_control_close(struct hw_device_t *dev)
    938 {
    939     LOG_FUNCTION_NAME;
    940 
    941     struct overlay_control_context_t* ctx =
    942            (struct overlay_control_context_t*)dev;
    943     overlay_object *overlay_v1;
    944 
    945     if (ctx) {
    946         overlay_v1 = static_cast<overlay_object *>(ctx->overlay_video1);
    947 
    948         overlay_destroyOverlay((struct overlay_control_device_t *)ctx,
    949                 overlay_v1);
    950 
    951         free(ctx);
    952     }
    953     return 0;
    954 }
    955 
    956 static int get_pixel_format_type(unsigned int pixelformat)
    957 {
    958     switch(pixelformat) {
    959     case V4L2_PIX_FMT_RGB32:
    960     case V4L2_PIX_FMT_RGB565:
    961         return PFT_RGB;
    962 
    963     case V4L2_PIX_FMT_NV12:
    964     case V4L2_PIX_FMT_NV12T:
    965     case V4L2_PIX_FMT_NV21:
    966     case V4L2_PIX_FMT_YUV420:
    967         return PFT_YUV420;
    968 
    969     case V4L2_PIX_FMT_YUYV:
    970     case V4L2_PIX_FMT_UYVY:
    971     case V4L2_PIX_FMT_YVYU:
    972     case V4L2_PIX_FMT_VYUY:
    973     case V4L2_PIX_FMT_NV16:
    974     case V4L2_PIX_FMT_NV61:
    975     case V4L2_PIX_FMT_YUV422P:
    976         return PFT_YUV422;
    977 
    978     default:
    979         return PFT_YUV444;
    980     }
    981 }
    982 
    983 /* check the constraints of destination image size */
    984 static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc,
    985                                       unsigned int rotation)
    986 {
    987     int tmp = 0;
    988 
    989     if((s5p_fimc->params.dst.height > 0) && (s5p_fimc->params.dst.height < 16))
    990         s5p_fimc->params.dst.height = 16;
    991 
    992     if(s5p_fimc->params.dst.width%8 != 0) {
    993         tmp = s5p_fimc->params.dst.width - (s5p_fimc->params.dst.width%8);
    994         if(tmp <= 0)
    995             return -1;
    996         else
    997             s5p_fimc->params.dst.width = tmp;
    998     }
    999 
   1000     return 1;
   1001 }
   1002 /* check the constraints of source image size */
   1003 static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc)
   1004 {
   1005     int format_type = 0;
   1006 
   1007     if(s5p_fimc->params.src.full_width < 16 ||
   1008         s5p_fimc->params.src.full_height < 8 )
   1009         return -1;
   1010 
   1011     if(s5p_fimc->hw_ver == 0x50) {
   1012         format_type = get_pixel_format_type(s5p_fimc->params.src.color_space);
   1013         switch (format_type) {
   1014         case PFT_YUV420:
   1015             if (s5p_fimc->params.src.height%2 != 0)
   1016                 s5p_fimc->params.src.height = s5p_fimc->params.src.height
   1017                                       - (s5p_fimc->params.src.height)%2;
   1018 
   1019             if (s5p_fimc->params.src.width%2 != 0)
   1020                 s5p_fimc->params.src.width = s5p_fimc->params.src.width
   1021                                       - (s5p_fimc->params.src.width)%2;
   1022             break;
   1023 
   1024         case PFT_YUV422:
   1025             if (s5p_fimc->params.src.width%2 != 0)
   1026                 s5p_fimc->params.src.width = s5p_fimc->params.src.width
   1027                                       - (s5p_fimc->params.src.width)%2;
   1028         }
   1029     } else {
   1030         if (s5p_fimc->params.src.height < 8) {
   1031             s5p_fimc->params.src.height = 8;
   1032         }
   1033 
   1034         if (s5p_fimc->params.src.width%16 != 0) {
   1035             s5p_fimc->params.src.width = s5p_fimc->params.src.width
   1036                                           - (s5p_fimc->params.src.width)%16;
   1037         }
   1038     }
   1039 
   1040     return 1;
   1041 }
   1042 
   1043 /****************************************************************************
   1044  * Data module
   1045  *****************************************************************************/
   1046 
   1047 int overlay_initialize(struct overlay_data_device_t *dev,
   1048         overlay_handle_t handle)
   1049 {
   1050     LOG_FUNCTION_NAME;
   1051 
   1052     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1053     struct stat stat;
   1054 
   1055     int i;
   1056     int rc = -1;
   1057 
   1058     ctx->num_buffers  = handle_num_buffers(handle);
   1059     ctx->width        = handle_width(handle);
   1060     ctx->height       = handle_height(handle);
   1061     ctx->format       = handle_format(handle);
   1062     ctx->ctl_fd       = handle_ctl_fd(handle);
   1063     ctx->shared_fd    = handle_shared_fd(handle);
   1064     ctx->shared_size  = handle_shared_size(handle);
   1065     ctx->shared       = NULL;
   1066     ctx->qd_buf_count = 0;
   1067     ctx->cacheable_buffers = 0;
   1068 
   1069     if (ctx->format >= HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP
   1070             && ctx->format < HAL_PIXEL_FORMAT_CUSTOM_MAX)
   1071         ctx->zerocopy = true;
   1072     else
   1073         ctx->zerocopy = false;
   1074 
   1075     if (fstat(ctx->ctl_fd, &stat)) {
   1076         LOGE("Error = %s from %s\n", strerror(errno), "overlay initialize");
   1077         return -1;
   1078     }
   1079 
   1080     if (open_shared_data(ctx)) {
   1081         return -1;
   1082     }
   1083 
   1084     ctx->shared->dataReady = 0;
   1085 
   1086     ctx->mapping_data = new struct mapping_data;
   1087     ctx->buffers     = new void* [ctx->num_buffers];
   1088     ctx->buffers_len = new size_t[ctx->num_buffers];
   1089 
   1090     if (!ctx->buffers || !ctx->buffers_len || !ctx->mapping_data) {
   1091         LOGE("Failed alloc'ing buffer arrays\n");
   1092         goto error;
   1093     } else {
   1094 
   1095         /*
   1096          * in the zero copy case,
   1097          * don't need to mmap buffer for source
   1098          */
   1099         if (ctx->zerocopy)
   1100             rc = 0;
   1101         else {
   1102             for (i = 0; i < ctx->num_buffers; i++) {
   1103                 rc = v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i],
   1104                         &ctx->buffers_len[i]);
   1105                 if (rc) {
   1106                     LOGE("Failed mapping buffers\n");
   1107                     goto error;
   1108                 }
   1109             }
   1110         }
   1111     }
   1112 
   1113     v4l2_overlay_init_fimc(ctx->ctl_fd, &g_s5p_fimc);
   1114 
   1115     return ( rc );
   1116 
   1117 error:
   1118 
   1119     if(ctx->mapping_data)
   1120         delete (ctx->mapping_data);
   1121     if(ctx->buffers)
   1122         delete [] ctx->buffers;
   1123     if(ctx->buffers_len)
   1124         delete [] ctx->buffers_len;
   1125 
   1126     close_shared_data( ctx );
   1127 
   1128     return -1;
   1129 }
   1130 
   1131 static int overlay_resizeInput(struct overlay_data_device_t *dev, uint32_t w,
   1132         uint32_t h)
   1133 {
   1134     int rc = -1;
   1135     int ret = 0;
   1136 
   1137     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1138 
   1139     if ((ctx->width == (int)w) && (ctx->width == (int)h)) {
   1140         LOGV("same as current width and height. so do nothing");
   1141         return 0;
   1142     }
   1143 
   1144     if (!ctx->shared) {
   1145         LOGI("Shared Data Not Init'd!\n");
   1146         return -1;
   1147     }
   1148 
   1149     if (ctx->shared->dataReady) {
   1150         LOGV("Either setCrop() or queueBuffer() was called prior to this!"
   1151                 "Therefore failing this call.\n");
   1152         return -1;
   1153     }
   1154 
   1155     pthread_mutex_lock(&ctx->shared->lock);
   1156 
   1157     if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd)))
   1158         goto end;
   1159 
   1160     if (!ctx->zerocopy) {
   1161         for (int i = 0; i < ctx->num_buffers; i++) {
   1162             v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]);
   1163         }
   1164     }
   1165 
   1166     g_s5p_fimc.params.src.full_width = w;
   1167     g_s5p_fimc.params.src.full_height = h;
   1168     g_s5p_fimc.params.src.width = w;
   1169     g_s5p_fimc.params.src.height = h;
   1170     set_color_space(ctx->format, &g_s5p_fimc.params.src.color_space);
   1171     ret = check_fimc_src_constraints(&g_s5p_fimc);
   1172 
   1173     if(ret != 0) {
   1174         if(ret < 0) {
   1175             LOGE("Not supported source image size");
   1176             goto end;
   1177         } else {
   1178             LOGD("src width, height are changed [w= %d, h= %d] -> [w=%d, h= %d]"
   1179                  , w, h, g_s5p_fimc.params.src.width
   1180                  , g_s5p_fimc.params.src.height);
   1181             w = g_s5p_fimc.params.src.width;
   1182             h = g_s5p_fimc.params.src.height;
   1183         }
   1184     }
   1185 
   1186     rc = v4l2_overlay_init(ctx->ctl_fd, w, h, ctx->format, phyAddr);
   1187     if (rc) {
   1188         LOGE("Error initializing overlay");
   1189         goto end;
   1190     }
   1191     rc = v4l2_overlay_set_crop(ctx->ctl_fd, 0, 0, w, h);
   1192     if (rc) {
   1193         LOGE("Error setting crop window\n");
   1194         goto end;
   1195     }
   1196     rc = v4l2_overlay_req_buf(ctx->ctl_fd, (uint32_t *)(&ctx->num_buffers),
   1197             ctx->cacheable_buffers, (int)ctx->zerocopy);
   1198     if (rc) {
   1199         LOGE("Error creating buffers");
   1200         goto end;
   1201     }
   1202 
   1203     if (!ctx->zerocopy) {
   1204         for (int i = 0; i < ctx->num_buffers; i++)
   1205             v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i],
   1206                     &ctx->buffers_len[i]);
   1207     }
   1208 
   1209     rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd);
   1210 
   1211 end:
   1212     pthread_mutex_unlock(&ctx->shared->lock);
   1213 
   1214     return rc;
   1215 }
   1216 
   1217 
   1218 static int overlay_data_setParameter(struct overlay_data_device_t *dev,
   1219         int param, int value)
   1220 {
   1221     int ret = 0;
   1222     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1223 
   1224     if (ctx->shared == NULL) {
   1225         LOGI("Shared Data Not Init'd!\n");
   1226         return -1;
   1227     }
   1228 
   1229     if (ctx->shared->dataReady) {
   1230         LOGI("Too late. Cant set it now!\n");
   1231         return -1;
   1232     }
   1233 
   1234     if (param == CACHEABLE_BUFFERS)
   1235         ctx->cacheable_buffers = value;
   1236 
   1237     return ( ret );
   1238 }
   1239 
   1240 
   1241 static int overlay_setCrop(struct overlay_data_device_t *dev, uint32_t x,
   1242         uint32_t y, uint32_t w, uint32_t h) {
   1243     LOG_FUNCTION_NAME;
   1244 
   1245     int rc = 0;
   1246     int cnt = 0;
   1247     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1248 
   1249     if (ctx->shared == NULL) {
   1250         LOGI("Shared Data Not Init'd!\n");
   1251         return -1;
   1252     }
   1253 
   1254     pthread_mutex_lock(&ctx->shared->lock);
   1255 
   1256     ctx->shared->dataReady = 1;
   1257 
   1258     if (ctx->data.cropX == x && ctx->data.cropY == y && ctx->data.cropW == w
   1259             && ctx->data.cropH == h) {
   1260         goto end;
   1261     }
   1262 
   1263     ctx->data.cropX = x;
   1264     ctx->data.cropY = y;
   1265     ctx->data.cropW = w;
   1266     ctx->data.cropH = h;
   1267 
   1268     LOGV("Crop Win/X%d/Y%d/W%d/H%d\n", x, y, w, h );
   1269 
   1270     if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd)))
   1271         goto end;
   1272 
   1273     rc = v4l2_overlay_set_crop(ctx->ctl_fd, x, y, w, h);
   1274     if (rc) {
   1275         LOGE("Set Crop Window Failed!/%d\n", rc);
   1276     }
   1277 
   1278     rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd);
   1279 
   1280 end:
   1281     pthread_mutex_unlock(&ctx->shared->lock);
   1282     return rc;
   1283 }
   1284 
   1285 static int overlay_getCrop(struct overlay_data_device_t *dev , uint32_t* x,
   1286         uint32_t* y, uint32_t* w, uint32_t* h) {
   1287     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1288 
   1289     return v4l2_overlay_get_crop(ctx->ctl_fd, x, y, w, h);
   1290 }
   1291 
   1292 int overlay_dequeueBuffer(struct overlay_data_device_t *dev,
   1293         overlay_buffer_t *buffer) {
   1294     /* blocks until a buffer is available and return an opaque structure
   1295      * representing this buffer.
   1296      */
   1297 
   1298     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1299 
   1300     int rc=0;
   1301     int i = -1;
   1302     uint32_t num = 0;
   1303     int cnt = 0;
   1304 
   1305     pthread_mutex_lock(&ctx->shared->lock);
   1306     if ( ctx->shared->streamingReset ) {
   1307         ctx->shared->streamingReset = 0;
   1308         pthread_mutex_unlock(&ctx->shared->lock);
   1309         return ALL_BUFFERS_FLUSHED;
   1310     }
   1311     pthread_mutex_unlock(&ctx->shared->lock);
   1312 
   1313     /* If we are not streaming dequeue will fail,
   1314        skip to prevent error printouts */
   1315     if (ctx->shared->streamEn && ctx->qd_buf_count) {
   1316         if ((rc = v4l2_overlay_dq_buf( ctx->ctl_fd, &i ,ctx->zerocopy)) != 0) {
   1317             LOGE("Failed to DQ/%d\n", rc);
   1318         }
   1319         else if (i < 0 || i > ctx->num_buffers) {
   1320             rc = -EINVAL;
   1321         } else {
   1322             *((int *)buffer) = i;
   1323             ctx->qd_buf_count --;
   1324         }
   1325     } else {
   1326         rc = -1;
   1327     }
   1328 
   1329     return rc;
   1330 }
   1331 
   1332 int overlay_queueBuffer(struct overlay_data_device_t *dev,
   1333         overlay_buffer_t buffer) {
   1334     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1335 
   1336     int cnt = 0;
   1337 
   1338     pthread_mutex_lock(&ctx->shared->lock);
   1339     if ( ctx->shared->streamingReset ) {
   1340         ctx->shared->streamingReset = 0;
   1341         pthread_mutex_unlock(&ctx->shared->lock);
   1342         return ALL_BUFFERS_FLUSHED;
   1343     }
   1344     pthread_mutex_unlock(&ctx->shared->lock);
   1345 
   1346     /* Catch the case where the data side had no need to set the crop window */
   1347     if (!ctx->shared->dataReady) {
   1348         ctx->shared->dataReady = 1;
   1349         enable_streaming(ctx->shared, ctx->ctl_fd);
   1350     }
   1351 
   1352     if (!ctx->shared->controlReady) return -1;
   1353     int rc = v4l2_overlay_q_buf( ctx->ctl_fd, (int)buffer, (int) ctx->zerocopy );
   1354     if (rc == 0 && ctx->qd_buf_count < ctx->num_buffers) {
   1355         ctx->qd_buf_count ++;
   1356     }
   1357 
   1358     return rc;
   1359 }
   1360 
   1361 void *overlay_getBufferAddress(struct overlay_data_device_t *dev,
   1362         overlay_buffer_t buffer)
   1363 {
   1364     LOG_FUNCTION_NAME;
   1365 
   1366     /* this may fail (NULL) if this feature is not supported. In that case,
   1367      * presumably, there is some other HAL module that can fill the buffer,
   1368      * using a DSP for instance
   1369      */
   1370     int ret;
   1371     struct v4l2_buffer buf;
   1372     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1373 
   1374     if (ctx->zerocopy)
   1375         return NULL;
   1376 
   1377     if ((int)buffer >= 0 && (int)buffer < ctx->num_buffers)
   1378         return (void*) ctx->buffers[(int)buffer];
   1379     else
   1380         return NULL;
   1381 }
   1382 
   1383 int overlay_getBufferCount(struct overlay_data_device_t *dev)
   1384 {
   1385     LOG_FUNCTION_NAME;
   1386 
   1387     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1388 
   1389     return (ctx->num_buffers);
   1390 }
   1391 
   1392 static int overlay_data_close(struct hw_device_t *dev) {
   1393 
   1394     LOG_FUNCTION_NAME;
   1395 
   1396     struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
   1397     int rc;
   1398 
   1399     if (ctx) {
   1400         overlay_data_device_t *overlay_dev = &ctx->device;
   1401         int buf;
   1402         int i;
   1403 
   1404         pthread_mutex_lock(&ctx->shared->lock);
   1405 
   1406         if (!ctx->zerocopy)
   1407             for (i = 0; i < ctx->num_buffers; i++) {
   1408                 LOGV("Unmap Buffer/%d/%08lx/%d", i, (unsigned long)ctx->buffers[i],
   1409                                                  ctx->buffers_len[i] );
   1410                 rc = v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]);
   1411                 if (rc != 0) {
   1412                     LOGE("Error unmapping the buffer/%d/%d", i, rc);
   1413                 }
   1414             }
   1415 
   1416         delete (ctx->mapping_data);
   1417         delete [] ctx->buffers;
   1418         delete [] ctx->buffers_len;
   1419 
   1420         pthread_mutex_unlock(&ctx->shared->lock);
   1421 
   1422         ctx->shared->dataReady = 0;
   1423         close_shared_data( ctx );
   1424 
   1425         free(ctx);
   1426     }
   1427 
   1428     return 0;
   1429 }
   1430 
   1431 /*****************************************************************************/
   1432 
   1433 static int overlay_device_open(const struct hw_module_t* module,
   1434         const char* name, struct hw_device_t** device)
   1435 {
   1436     LOG_FUNCTION_NAME;
   1437     int status = -EINVAL;
   1438 
   1439     if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) {
   1440         struct overlay_control_context_t *dev;
   1441         dev = (overlay_control_context_t*)malloc(sizeof(*dev));
   1442 
   1443         /* initialize our state here */
   1444         memset(dev, 0, sizeof(*dev));
   1445 
   1446         /* initialize the procs */
   1447         dev->device.common.tag = HARDWARE_DEVICE_TAG;
   1448         dev->device.common.version = 0;
   1449         dev->device.common.module = const_cast<hw_module_t*>(module);
   1450         dev->device.common.close = overlay_control_close;
   1451 
   1452         dev->device.get = overlay_get;
   1453         dev->device.createOverlay = overlay_createOverlay;
   1454         dev->device.destroyOverlay = overlay_destroyOverlay;
   1455         dev->device.setPosition = overlay_setPosition;
   1456         dev->device.getPosition = overlay_getPosition;
   1457         dev->device.setParameter = overlay_setParameter;
   1458         dev->device.stage = overlay_stage;
   1459         dev->device.commit = overlay_commit;
   1460 
   1461         *device = &dev->device.common;
   1462         status = 0;
   1463     } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) {
   1464         struct overlay_data_context_t *dev;
   1465         dev = (overlay_data_context_t*)malloc(sizeof(*dev));
   1466 
   1467         /* initialize our state here */
   1468         memset(dev, 0, sizeof(*dev));
   1469 
   1470         /* initialize the procs */
   1471         dev->device.common.tag = HARDWARE_DEVICE_TAG;
   1472         dev->device.common.version = 0;
   1473         dev->device.common.module = const_cast<hw_module_t*>(module);
   1474         dev->device.common.close = overlay_data_close;
   1475 
   1476         dev->device.initialize = overlay_initialize;
   1477         dev->device.resizeInput = overlay_resizeInput;
   1478         dev->device.setCrop = overlay_setCrop;
   1479         dev->device.getCrop = overlay_getCrop;
   1480         dev->device.setParameter = overlay_data_setParameter;
   1481         dev->device.dequeueBuffer = overlay_dequeueBuffer;
   1482         dev->device.queueBuffer = overlay_queueBuffer;
   1483         dev->device.getBufferAddress = overlay_getBufferAddress;
   1484         dev->device.getBufferCount = overlay_getBufferCount;
   1485 
   1486         *device = &dev->device.common;
   1487         status = 0;
   1488     }
   1489     return status;
   1490 }
   1491