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