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