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