exynos_gscaler.c revision 2607aa30bcae2244e1bc68cbc0a0fc5a2b4ef570
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright@ Samsung Electronics Co. LTD 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/*! 19 * \file exynos_gscaler.c 20 * \brief header file for Gscaler HAL 21 * \author ShinWon Lee (shinwon.lee@samsung.com) 22 * \date 2012/01/09 23 * 24 * <b>Revision History: </b> 25 * - 2012.01.09 : ShinWon Lee(shinwon.lee@samsung.com) \n 26 * Create 27 * 28 * - 2012.02.07 : ShinWon Lee(shinwon.lee@samsung.com) \n 29 * Change file name to exynos_gscaler.h 30 * 31 * - 2012.02.09 : Sangwoo, Parkk(sw5771.park@samsung.com) \n 32 * Use Multiple Gscaler by Multiple Process 33 * 34 * - 2012.02.20 : Sangwoo, Park(sw5771.park@samsung.com) \n 35 * Add exynos_gsc_set_rotation() API 36 * 37 * - 2012.02.20 : ShinWon Lee(shinwon.lee@samsung.com) \n 38 * Add size constrain 39 * 40 */ 41 42//#define LOG_NDEBUG 0 43#include "exynos_gsc_utils.h" 44 45static unsigned int m_gsc_get_plane_count( 46 int v4l_pixel_format) 47{ 48 int plane_count = 0; 49 50 switch (v4l_pixel_format) { 51 case V4L2_PIX_FMT_RGB32: 52 case V4L2_PIX_FMT_BGR32: 53 case V4L2_PIX_FMT_RGB24: 54 case V4L2_PIX_FMT_RGB565: 55 case V4L2_PIX_FMT_RGB555X: 56 case V4L2_PIX_FMT_RGB444: 57 case V4L2_PIX_FMT_YUYV: 58 case V4L2_PIX_FMT_UYVY: 59 case V4L2_PIX_FMT_NV16: 60 case V4L2_PIX_FMT_NV61: 61 plane_count = 1; 62 break; 63 case V4L2_PIX_FMT_NV12M: 64 case V4L2_PIX_FMT_NV12MT_16X16: 65 case V4L2_PIX_FMT_NV12: 66 case V4L2_PIX_FMT_NV21: 67 case V4L2_PIX_FMT_NV21M: 68 plane_count = 2; 69 break; 70 case V4L2_PIX_FMT_YVU420M: 71 case V4L2_PIX_FMT_YUV422P: 72 case V4L2_PIX_FMT_YUV420M: 73 plane_count = 3; 74 break; 75 default: 76 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n", 77 __func__, v4l_pixel_format); 78 plane_count = -1; 79 break; 80 } 81 82 return plane_count; 83} 84 85static unsigned int m_gsc_get_plane_size( 86 unsigned int *plane_size, 87 unsigned int width, 88 unsigned int height, 89 int v4l_pixel_format) 90{ 91 switch (v4l_pixel_format) { 92 /* 1 plane */ 93 case V4L2_PIX_FMT_RGB32: 94 case V4L2_PIX_FMT_BGR32: 95 plane_size[0] = width * height * 4; 96 plane_size[1] = 0; 97 plane_size[2] = 0; 98 break; 99 case V4L2_PIX_FMT_RGB24: 100 plane_size[0] = width * height * 3; 101 plane_size[1] = 0; 102 plane_size[2] = 0; 103 break; 104 case V4L2_PIX_FMT_RGB565: 105 case V4L2_PIX_FMT_RGB555X: 106 case V4L2_PIX_FMT_RGB444: 107 case V4L2_PIX_FMT_YUYV: 108 case V4L2_PIX_FMT_UYVY: 109 plane_size[0] = width * height * 2; 110 plane_size[1] = 0; 111 plane_size[2] = 0; 112 break; 113 /* 2 planes */ 114 case V4L2_PIX_FMT_NV12M: 115 case V4L2_PIX_FMT_NV12: 116 case V4L2_PIX_FMT_NV21: 117 case V4L2_PIX_FMT_NV21M: 118 plane_size[0] = width * height; 119 plane_size[1] = width * (height / 2); 120 plane_size[2] = 0; 121 break; 122 case V4L2_PIX_FMT_NV16: 123 case V4L2_PIX_FMT_NV61: 124 plane_size[0] = width * height * 2; 125 plane_size[1] = 0; 126 plane_size[2] = 0; 127 break; 128 case V4L2_PIX_FMT_NV12MT_16X16: 129 plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16); 130 plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8); 131 plane_size[2] = 0; 132 break; 133 /* 3 planes */ 134 case V4L2_PIX_FMT_YVU420M: 135 case V4L2_PIX_FMT_YUV422P: 136 plane_size[0] = width * height; 137 plane_size[1] = (width / 2) * (height / 2); 138 plane_size[2] = (width / 2) * (height / 2); 139 break; 140 default: 141 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n", 142 __func__, v4l_pixel_format); 143 return -1; 144 break; 145 } 146 147 return 0; 148} 149 150static int m_exynos_gsc_multiple_of_n( 151 int number, int N) 152{ 153 int result = number; 154 switch (N) { 155 case 1: 156 case 2: 157 case 4: 158 case 8: 159 case 16: 160 case 32: 161 case 64: 162 case 128: 163 case 256: 164 result = (number - (number & (N-1))); 165 break; 166 default: 167 result = number - (number % N); 168 break; 169 } 170 return result; 171} 172 173static bool m_exynos_gsc_check_src_size( 174 unsigned int *w, unsigned int *h, 175 unsigned int *crop_x, unsigned int *crop_y, 176 unsigned int *crop_w, unsigned int *crop_h, 177 int v4l2_colorformat) 178{ 179 if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) { 180 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)", 181 __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h); 182 return false; 183 } 184 185 if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) { 186 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)", 187 __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h); 188 return false; 189 } 190 191 switch (v4l2_colorformat) { 192 // YUV420 193 case V4L2_PIX_FMT_YUV420M: 194 case V4L2_PIX_FMT_YVU420M: 195 case V4L2_PIX_FMT_NV12M: 196 case V4L2_PIX_FMT_NV12MT: 197 case V4L2_PIX_FMT_NV21: 198 case V4L2_PIX_FMT_NV21M: 199 *w = (*w + 15) & ~15; 200 *h = (*h + 15) & ~15; 201 //*w = m_exynos_gsc_multiple_of_n(*w, 16); 202 //*h = m_exynos_gsc_multiple_of_n(*h, 16); 203 *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4); 204 *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 4); 205 break; 206 // YUV422 207 case V4L2_PIX_FMT_YUYV: 208 case V4L2_PIX_FMT_YUV422P: 209 case V4L2_PIX_FMT_UYVY: 210 case V4L2_PIX_FMT_NV16: 211 case V4L2_PIX_FMT_YVYU: 212 case V4L2_PIX_FMT_VYUY: 213 *h = (*h + 7) & ~7; 214 //*h = m_exynos_gsc_multiple_of_n(*h, 8); 215 *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4); 216 *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2); 217 break; 218 // RGB 219 case V4L2_PIX_FMT_RGB32: 220 case V4L2_PIX_FMT_RGB24: 221 case V4L2_PIX_FMT_RGB565: 222 case V4L2_PIX_FMT_BGR32: 223 case V4L2_PIX_FMT_RGB555X: 224 case V4L2_PIX_FMT_RGB444: 225 default: 226 *h = (*h + 7) & ~7; 227 //*h = m_exynos_gsc_multiple_of_n(*h, 8); 228 *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 2); 229 *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2); 230 break; 231 } 232 233 return true; 234} 235 236static bool m_exynos_gsc_check_dst_size( 237 unsigned int *w, unsigned int *h, 238 unsigned int *crop_x, unsigned int *crop_y, 239 unsigned int *crop_w, unsigned int *crop_h, 240 int v4l2_colorformat, 241 int rotation) 242{ 243 unsigned int *new_w; 244 unsigned int *new_h; 245 unsigned int *new_crop_w; 246 unsigned int *new_crop_h; 247 248 new_w = w; 249 new_h = h; 250 new_crop_w = crop_w; 251 new_crop_h = crop_h; 252 253 if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) { 254 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)", 255 __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h); 256 return false; 257 } 258 259 if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) { 260 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)", 261 __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h); 262 return false; 263 } 264 265 switch (v4l2_colorformat) { 266 // YUV420 267 case V4L2_PIX_FMT_NV12M: 268 case V4L2_PIX_FMT_NV12MT: 269 case V4L2_PIX_FMT_NV21: 270 case V4L2_PIX_FMT_NV21M: 271 case V4L2_PIX_FMT_YUV420M: 272 case V4L2_PIX_FMT_YVU420M: 273 *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2); 274 *new_h = m_exynos_gsc_multiple_of_n(*new_h, 2); 275 break; 276 // YUV422 277 case V4L2_PIX_FMT_YUYV: 278 case V4L2_PIX_FMT_YUV422P: 279 case V4L2_PIX_FMT_UYVY: 280 case V4L2_PIX_FMT_NV16: 281 case V4L2_PIX_FMT_YVYU: 282 case V4L2_PIX_FMT_VYUY: 283 *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2); 284 break; 285 // RGB 286 case V4L2_PIX_FMT_RGB32: 287 case V4L2_PIX_FMT_RGB24: 288 case V4L2_PIX_FMT_RGB565: 289 case V4L2_PIX_FMT_BGR32: 290 case V4L2_PIX_FMT_RGB555X: 291 case V4L2_PIX_FMT_RGB444: 292 default: 293 break; 294 } 295 296 return true; 297} 298 299static int m_exynos_gsc_output_create( 300 struct GSC_HANDLE *gsc_handle, 301 int dev_num, 302 int out_mode) 303{ 304 struct media_device *media0; 305 struct media_entity *gsc_sd_entity; 306 struct media_entity *gsc_vd_entity; 307 struct media_entity *sink_sd_entity; 308 struct media_link *links; 309 char node[32]; 310 char devname[32]; 311 unsigned int cap; 312 int i; 313 int fd = 0; 314 315 Exynos_gsc_In(); 316 317 if ((out_mode != GSC_OUT_FIMD) && 318 (out_mode != GSC_OUT_TV)) 319 return -1; 320 321 gsc_handle->out_mode = out_mode; 322 /* GSCX => FIMD_WINX : arbitrary linking is not allowed */ 323 if ((out_mode == GSC_OUT_FIMD) && 324 (dev_num > 2)) 325 return -1; 326 327 /* media0 */ 328 sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0); 329 media0 = exynos_media_open(node); 330 if (media0 == NULL) { 331 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node); 332 return false; 333 } 334 335 /* Get the sink subdev entity by name and make the node of sink subdev*/ 336 if (out_mode == GSC_OUT_FIMD) 337 sprintf(devname, PFX_FIMD_ENTITY, dev_num); 338 else 339 sprintf(devname, PFX_MXR_ENTITY, 0); 340 341 sink_sd_entity = exynos_media_get_entity_by_name(media0, devname, strlen(devname)); 342 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR); 343 if ( sink_sd_entity->fd < 0) { 344 ALOGE("%s:: failed to open sink subdev node", __func__); 345 goto gsc_output_err; 346 } 347 348 /* get GSC video dev & sub dev entity by name*/ 349 sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num); 350 gsc_vd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname)); 351 352 sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num); 353 gsc_sd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname)); 354 355 /* gsc sub-dev open */ 356 sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num); 357 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR); 358 359 /* setup link : GSC : video device --> sub device */ 360 for (i = 0; i < (int) gsc_vd_entity->num_links; i++) { 361 links = &gsc_vd_entity->links[i]; 362 363 if (links == NULL || 364 links->source->entity != gsc_vd_entity || 365 links->sink->entity != gsc_sd_entity) { 366 continue; 367 } else if (exynos_media_setup_link(media0, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { 368 ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed", 369 __func__, links->source->entity->info.id, links->sink->entity->info.id); 370 return -1; 371 } 372 } 373 374 /* setup link : GSC: sub device --> sink device */ 375 for (i = 0; i < (int) gsc_sd_entity->num_links; i++) { 376 links = &gsc_sd_entity->links[i]; 377 378 if (links == NULL || links->source->entity != gsc_sd_entity || 379 links->sink->entity != sink_sd_entity) { 380 continue; 381 } else if (exynos_media_setup_link(media0, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { 382 ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed", 383 __func__, links->source->entity->info.id, links->sink->entity->info.id); 384 return -1; 385 } 386 } 387 388 /* gsc video-dev open */ 389 sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num); 390 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR); 391 cap = V4L2_CAP_STREAMING | 392 V4L2_CAP_VIDEO_OUTPUT_MPLANE; 393 394 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) { 395 ALOGE("%s::exynos_v4l2_querycap() fail", __func__); 396 goto gsc_output_err; 397 } 398 gsc_handle->gsc_sd_entity = gsc_sd_entity; 399 gsc_handle->gsc_vd_entity = gsc_vd_entity; 400 gsc_handle->sink_sd_entity = sink_sd_entity; 401 gsc_handle->media0 = media0; 402 403 Exynos_gsc_Out(); 404 405 return 0; 406 407gsc_output_err: 408 /* to do */ 409 return -1; 410 411} 412 413static int m_exynos_gsc_m2m_create( 414 int dev) 415{ 416 int fd = 0; 417 int video_node_num; 418 unsigned int cap; 419 char node[32]; 420 421 Exynos_gsc_In(); 422 423 switch(dev) { 424 case 0: 425 video_node_num = NODE_NUM_GSC_0; 426 break; 427 case 1: 428 video_node_num = NODE_NUM_GSC_1; 429 break; 430 case 2: 431 video_node_num = NODE_NUM_GSC_2; 432 break; 433 case 3: 434 video_node_num = NODE_NUM_GSC_3; 435 break; 436 default: 437 ALOGE("%s::unexpected dev(%d) fail", __func__, dev); 438 return -1; 439 break; 440 } 441 442 sprintf(node, "%s%d", PFX_NODE_GSC, video_node_num); 443 fd = exynos_v4l2_open(node, O_RDWR); 444 if (fd < 0) { 445 ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node); 446 return -1; 447 } 448 449 cap = V4L2_CAP_STREAMING | 450 V4L2_CAP_VIDEO_OUTPUT_MPLANE | 451 V4L2_CAP_VIDEO_CAPTURE_MPLANE; 452 453 if (exynos_v4l2_querycap(fd, cap) == false) { 454 ALOGE("%s::exynos_v4l2_querycap() fail", __func__); 455 if (0 < fd) 456 close(fd); 457 fd = 0; 458 return -1; 459 } 460 461 Exynos_gsc_Out(); 462 463 return fd; 464} 465 466 467static bool m_exynos_gsc_out_destroy(struct GSC_HANDLE *gsc_handle) 468{ 469 struct media_link * links; 470 int i; 471 472 Exynos_gsc_In(); 473 474 if (gsc_handle == NULL) { 475 ALOGE("%s::gsc_handle is NULL", __func__); 476 return false; 477 } 478 479 if (gsc_handle->src.stream_on == true) { 480 if (exynos_gsc_out_stop((void *)gsc_handle) < 0) 481 ALOGE("%s::exynos_gsc_out_stop() fail", __func__); 482 483 gsc_handle->src.stream_on = false; 484 } 485 486 /* unlink : gscaler-out --> fimd */ 487 for (i = 0; i < (int) gsc_handle->gsc_sd_entity->num_links; i++) { 488 links = &gsc_handle->gsc_sd_entity->links[i]; 489 490 if (links == NULL || links->source->entity != gsc_handle->gsc_sd_entity || 491 links->sink->entity != gsc_handle->sink_sd_entity) { 492 continue; 493 } else if (exynos_media_setup_link(gsc_handle->media0, links->source, 494 links->sink, 0) < 0) { 495 ALOGE("%s::exynos_media_setup_unlink [src.entity=%d->sink.entity=%d] failed", 496 __func__, links->source->entity->info.id, links->sink->entity->info.id); 497 } 498 } 499 500 close(gsc_handle->gsc_vd_entity->fd); 501 close(gsc_handle->gsc_sd_entity->fd); 502 gsc_handle->gsc_vd_entity->fd = -1; 503 gsc_handle->gsc_vd_entity->fd = -1; 504 505 Exynos_gsc_Out(); 506 507 return true; 508 509} 510 511static bool m_exynos_gsc_destroy( 512 struct GSC_HANDLE *gsc_handle) 513{ 514 Exynos_gsc_In(); 515 516 if (gsc_handle->src.stream_on == true) { 517 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) 518 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__); 519 520 gsc_handle->src.stream_on = false; 521 } 522 523 if (gsc_handle->dst.stream_on == true) { 524 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) 525 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__); 526 527 gsc_handle->dst.stream_on = false; 528 } 529 530 if (0 < gsc_handle->gsc_fd) 531 close(gsc_handle->gsc_fd); 532 gsc_handle->gsc_fd = 0; 533 534 Exynos_gsc_Out(); 535 536 return true; 537} 538 539bool m_exynos_gsc_find_and_trylock_and_create( 540 struct GSC_HANDLE *gsc_handle) 541{ 542 int i = 0; 543 bool flag_find_new_gsc = false; 544 unsigned int total_sleep_time = 0; 545 546 Exynos_gsc_In(); 547 548 do { 549 for (i = 0; i < NUM_OF_GSC_HW; i++) { 550 // HACK : HWComposer, HDMI uses gscaler with their own code. 551 // So, This obj_mutex cannot defense their open() 552 if (i == 0 || i == 3) 553 continue; 554 555 if (exynos_mutex_trylock(gsc_handle->obj_mutex[i]) == true) { 556 557 // destroy old one. 558 m_exynos_gsc_destroy(gsc_handle); 559 560 // create new one. 561 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(i); 562 if (gsc_handle->gsc_fd < 0) { 563 gsc_handle->gsc_fd = 0; 564 exynos_mutex_unlock(gsc_handle->obj_mutex[i]); 565 continue; 566 } 567 568 if (gsc_handle->cur_obj_mutex) 569 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 570 571 gsc_handle->cur_obj_mutex = gsc_handle->obj_mutex[i]; 572 573 flag_find_new_gsc = true; 574 break; 575 } 576 } 577 578 // waiting for another process doesn't use gscaler. 579 // we need to make decision how to do. 580 if (flag_find_new_gsc == false) { 581 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 582 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 583 ALOGV("%s::waiting for anthere process doens't use gscaler", __func__); 584 } 585 586 } while( flag_find_new_gsc == false 587 && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 588 589 if (flag_find_new_gsc == false) 590 ALOGE("%s::we don't have no available gsc.. fail", __func__); 591 592 Exynos_gsc_Out(); 593 594 return flag_find_new_gsc; 595} 596 597static bool m_exynos_gsc_set_format( 598 int fd, 599 struct gsc_info *info, 600 bool force) 601{ 602 Exynos_gsc_In(); 603 604 struct v4l2_requestbuffers req_buf; 605 int plane_count; 606 607 plane_count = m_gsc_get_plane_count(info->v4l2_colorformat); 608 if (plane_count < 0) { 609 ALOGE("%s::not supported v4l2_colorformat", __func__); 610 return false; 611 } 612 613 if (force == false) { 614 // format 615 info->format.type = info->buf_type; 616 if (exynos_v4l2_g_fmt(fd, &info->format) < 0) { 617 ALOGE("%s::exynos_v4l2_g_fmt() fail type=%d", __func__, info->buf_type); 618 return false; 619 } 620 621 if (info->width != info->format.fmt.pix_mp.width || 622 info->height != info->format.fmt.pix_mp.height || 623 info->v4l2_colorformat != info->format.fmt.pix_mp.pixelformat) { 624 ALOGV("%s::info is different..)", __func__); 625 goto set_hw; 626 } 627 628 // crop 629 info->crop.type = info->buf_type; 630 if (exynos_v4l2_g_crop(fd, &info->crop) < 0) { 631 ALOGE("%s::exynos_v4l2_g_crop() fail", __func__); 632 return false; 633 } 634 635 if (info->crop_left != info->crop.c.left || 636 info->crop_top != info->crop.c.top || 637 info->crop_width != info->crop.c.width || 638 info->crop_height != info->crop.c.height) { 639 ALOGV("%s::crop is different..", __func__); 640 goto set_hw; 641 } 642 643 // rotation value; 644 int value = 0; 645 646 if (exynos_v4l2_g_ctrl(fd, V4L2_CID_ROTATE, &value) < 0) { 647 ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__); 648 return false; 649 } 650 651 if (info->rotation != value) { 652 ALOGV("%s::rotation is different..", __func__); 653 goto set_hw; 654 } 655 656 if (exynos_v4l2_g_ctrl(fd, V4L2_CID_VFLIP, &value) < 0) { 657 ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__); 658 return false; 659 } 660 661 if (info->flip_horizontal != value) { 662 ALOGV("%s::flip_horizontal is different..", __func__); 663 goto set_hw; 664 } 665 666 if (exynos_v4l2_g_ctrl(fd, V4L2_CID_HFLIP, &value) < 0) { 667 ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__); 668 return false; 669 } 670 671 if (info->flip_vertical != value) { 672 ALOGV("%s::flip_vertical is different..", __func__); 673 goto set_hw; 674 } 675 676 // skip s_fmt 677 ALOGV("%s::fmt, crop is same with old-one, so skip s_fmt crop..", __func__); 678 return true; 679 } 680 681set_hw: 682 683 if (info->stream_on == true) { 684 if (exynos_v4l2_streamoff(fd, info->buf_type) < 0) { 685 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__); 686 return false; 687 } 688 info->stream_on = false; 689 } 690 691 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) { 692 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__); 693 return false; 694 } 695 696 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) { 697 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__); 698 return false; 699 } 700 701 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) { 702 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__); 703 return false; 704 } 705 info->format.type = info->buf_type; 706 info->format.fmt.pix_mp.width = info->width; 707 info->format.fmt.pix_mp.height = info->height; 708 info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat; 709 info->format.fmt.pix_mp.field = V4L2_FIELD_ANY; 710 info->format.fmt.pix_mp.num_planes = plane_count; 711 712 if (exynos_v4l2_s_fmt(fd, &info->format) < 0) { 713 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__); 714 return false; 715 } 716 717 info->crop.type = info->buf_type; 718 info->crop.c.left = info->crop_left; 719 info->crop.c.top = info->crop_top; 720 info->crop.c.width = info->crop_width; 721 info->crop.c.height = info->crop_height; 722 723 if (exynos_v4l2_s_crop(fd, &info->crop) < 0) { 724 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__); 725 return false; 726 } 727 728 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) { 729 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__); 730 return false; 731 } 732 733 req_buf.count = 1; 734 req_buf.type = info->buf_type; 735 req_buf.memory = V4L2_MEMORY_DMABUF; 736 if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) { 737 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__); 738 return false; 739 } 740 741 Exynos_gsc_Out(); 742 743 return true; 744} 745 746static bool m_exynos_gsc_set_addr( 747 int fd, 748 struct gsc_info *info) 749{ 750 unsigned int i; 751 unsigned int plane_size[NUM_OF_GSC_PLANES]; 752 753 m_gsc_get_plane_size(plane_size, 754 info->width, 755 info->height, 756 info->v4l2_colorformat); 757 758 info->buffer.index = 0; 759 info->buffer.type = info->buf_type; 760 info->buffer.memory = V4L2_MEMORY_DMABUF; 761 info->buffer.m.planes = info->planes; 762 info->buffer.length = info->format.fmt.pix_mp.num_planes; 763 764 for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) { 765 info->buffer.m.planes[i].m.fd = (int)info->addr[i]; 766 info->buffer.m.planes[i].length = plane_size[i]; 767 info->buffer.m.planes[i].bytesused = 0; 768 } 769 770 if (exynos_v4l2_qbuf(fd, &info->buffer) < 0) { 771 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__); 772 return false; 773 } 774 775 return true; 776} 777 778void *exynos_gsc_create( 779 void) 780{ 781 int i = 0; 782 int op_id = 0; 783 char mutex_name[32]; 784 785 Exynos_gsc_In(); 786 787 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 788 if (gsc_handle == NULL) { 789 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 790 goto err; 791 } 792 793 gsc_handle->gsc_fd = 0; 794 memset(&gsc_handle->src, 0, sizeof(struct gsc_info)); 795 memset(&gsc_handle->dst, 0, sizeof(struct gsc_info)); 796 797 gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 798 gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 799 800 gsc_handle->op_mutex = NULL; 801 for (i = 0; i < NUM_OF_GSC_HW; i++) 802 gsc_handle->obj_mutex[i] = NULL; 803 804 gsc_handle->cur_obj_mutex = NULL; 805 gsc_handle->flag_local_path = false; 806 gsc_handle->flag_exclusive_open = false; 807 808 srand(time(NULL)); 809 op_id = rand() % 1000000; // just make random id 810 sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id); 811 gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name); 812 if (gsc_handle->op_mutex == NULL) { 813 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 814 goto err; 815 } 816 817 exynos_mutex_lock(gsc_handle->op_mutex); 818 819 // check if it is available 820 for (i = 0; i < NUM_OF_GSC_HW; i++) { 821 sprintf(mutex_name, "%sObject%d", LOG_TAG, i); 822 823 gsc_handle->obj_mutex[i] = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 824 if (gsc_handle->obj_mutex[i] == NULL) { 825 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 826 goto err; 827 } 828 } 829 830 if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) { 831 ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__); 832 goto err; 833 } 834 835 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 836 exynos_mutex_unlock(gsc_handle->op_mutex); 837 838 return (void *)gsc_handle; 839 840err: 841 if (gsc_handle) { 842 m_exynos_gsc_destroy(gsc_handle); 843 844 if (gsc_handle->cur_obj_mutex) 845 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 846 847 for (i = 0; i < NUM_OF_GSC_HW; i++) { 848 if ((gsc_handle->obj_mutex[i] != NULL) && 849 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 850 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 851 ALOGE("%s::exynos_mutex_destroy() fail", __func__); 852 } 853 } 854 855 if (gsc_handle->op_mutex) 856 exynos_mutex_unlock(gsc_handle->op_mutex); 857 858 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 859 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 860 861 free(gsc_handle); 862 } 863 864 Exynos_gsc_Out(); 865 866 return NULL; 867} 868 869void *exynos_gsc_reserve(int dev_num) 870{ 871 char mutex_name[32]; 872 unsigned int total_sleep_time = 0; 873 bool gsc_flag = false; 874 875 if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) { 876 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num); 877 return NULL; 878 } 879 880 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 881 if (gsc_handle == NULL) { 882 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 883 goto err; 884 } 885 886 gsc_handle->gsc_fd = -1; 887 gsc_handle->op_mutex = NULL; 888 gsc_handle->cur_obj_mutex = NULL; 889 890 sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num); 891 gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 892 if (gsc_handle->cur_obj_mutex == NULL) { 893 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 894 goto err; 895 } 896 897 do { 898 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) { 899 gsc_flag = true; 900 break; 901 } 902 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 903 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 904 ALOGV("%s::waiting for another process to release the requested gscaler", __func__); 905 } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 906 907 if (gsc_flag == true) 908 return (void *)gsc_handle; 909 910err: 911 if (gsc_handle) { 912 free(gsc_handle); 913 } 914 915 return NULL; 916} 917 918void exynos_gsc_release(void *handle) 919{ 920 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle; 921 922 if (handle == NULL) { 923 ALOGE("%s::handle == NULL() fail", __func__); 924 return; 925 } 926 927 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 928 exynos_mutex_destroy(gsc_handle->cur_obj_mutex); 929 free(gsc_handle); 930 return; 931} 932 933void *exynos_gsc_create_exclusive( 934 int dev_num, 935 int mode, 936 int out_mode) 937{ 938 int i = 0; 939 int op_id = 0; 940 char mutex_name[32]; 941 unsigned int total_sleep_time = 0; 942 bool gsc_flag = false; 943 int ret = 0; 944 945 Exynos_gsc_In(); 946 947 if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) { 948 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num); 949 return NULL; 950 } 951 952 if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) { 953 ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode); 954 return NULL; 955 } 956 957 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 958 if (gsc_handle == NULL) { 959 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 960 goto err; 961 } 962 memset(gsc_handle, 0, sizeof(struct GSC_HANDLE)); 963 gsc_handle->gsc_fd = -1; 964 gsc_handle->gsc_mode = mode; 965 966 gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 967 gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 968 969 gsc_handle->op_mutex = NULL; 970 for (i = 0; i < NUM_OF_GSC_HW; i++) 971 gsc_handle->obj_mutex[i] = NULL; 972 973 gsc_handle->cur_obj_mutex = NULL; 974 gsc_handle->flag_local_path = false; 975 gsc_handle->flag_exclusive_open = true; 976 977 srand(time(NULL)); 978 op_id = rand() % 1000000; // just make random id 979 sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id); 980 gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name); 981 if (gsc_handle->op_mutex == NULL) { 982 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 983 goto err; 984 } 985 986 exynos_mutex_lock(gsc_handle->op_mutex); 987 988 sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num); 989 gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 990 if (gsc_handle->cur_obj_mutex == NULL) { 991 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 992 goto err; 993 } 994 995 do { 996 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) { 997 if (mode == GSC_M2M_MODE) { 998 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(dev_num); 999 if (gsc_handle->gsc_fd < 0) { 1000 ALOGE("%s::m_exynos_gsc_m2m_create(%i) fail", __func__, dev_num); 1001 goto err; 1002 } 1003 } else if (mode == GSC_OUTPUT_MODE) { 1004 ret = m_exynos_gsc_output_create(gsc_handle, dev_num, out_mode); 1005 if (ret < 0) { 1006 ALOGE("%s::m_exynos_gsc_output_create(%i) fail", __func__, dev_num); 1007 goto err; 1008 } 1009 } 1010 /*else 1011 gsc_handle->gsc_fd = m_exynos_gsc_capture_create(dev_num);*/ 1012 1013 gsc_flag = true; 1014 break; 1015 } 1016 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 1017 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 1018 ALOGV("%s::waiting for anthere process doens't use gscaler", __func__); 1019 } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 1020 1021 exynos_mutex_unlock(gsc_handle->op_mutex); 1022 if (gsc_flag == true) { 1023 Exynos_gsc_Out(); 1024 return (void *)gsc_handle; 1025 } 1026 1027err: 1028 if (gsc_handle) { 1029 m_exynos_gsc_destroy(gsc_handle); 1030 1031 if (gsc_handle->cur_obj_mutex) 1032 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 1033 1034 for (i = 0; i < NUM_OF_GSC_HW; i++) { 1035 if ((gsc_handle->obj_mutex[i] != NULL) && 1036 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 1037 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 1038 ALOGE("%s::exynos_mutex_destroy() fail", __func__); 1039 } 1040 } 1041 1042 if (gsc_handle->op_mutex) 1043 exynos_mutex_unlock(gsc_handle->op_mutex); 1044 1045 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 1046 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 1047 1048 free(gsc_handle); 1049 } 1050 1051 Exynos_gsc_Out(); 1052 1053 return NULL; 1054} 1055 1056void exynos_gsc_destroy( 1057 void *handle) 1058{ 1059 int i = 0; 1060 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle; 1061 1062 Exynos_gsc_In(); 1063 1064 if (handle == NULL) { 1065 ALOGE("%s::handle == NULL() fail", __func__); 1066 return; 1067 } 1068 1069 exynos_mutex_lock(gsc_handle->op_mutex); 1070 1071 if (gsc_handle->flag_exclusive_open == false) 1072 exynos_mutex_lock(gsc_handle->cur_obj_mutex); 1073 1074 if (gsc_handle->gsc_mode == GSC_OUTPUT_MODE) 1075 m_exynos_gsc_out_destroy(gsc_handle); 1076 else 1077 m_exynos_gsc_destroy(gsc_handle); 1078 1079 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 1080 1081 for (i = 0; i < NUM_OF_GSC_HW; i++) { 1082 if ((gsc_handle->obj_mutex[i] != NULL) && 1083 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 1084 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 1085 ALOGE("%s::exynos_mutex_destroy(obj_mutex) fail", __func__); 1086 } 1087 } 1088 1089 exynos_mutex_unlock(gsc_handle->op_mutex); 1090 1091 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 1092 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 1093 1094 if (gsc_handle) 1095 free(gsc_handle); 1096 1097 Exynos_gsc_Out(); 1098 1099} 1100 1101int exynos_gsc_set_src_format( 1102 void *handle, 1103 unsigned int width, 1104 unsigned int height, 1105 unsigned int crop_left, 1106 unsigned int crop_top, 1107 unsigned int crop_width, 1108 unsigned int crop_height, 1109 unsigned int v4l2_colorformat, 1110 unsigned int cacheable, 1111 unsigned int mode_drm) 1112{ 1113 Exynos_gsc_In(); 1114 1115 struct GSC_HANDLE *gsc_handle; 1116 gsc_handle = (struct GSC_HANDLE *)handle; 1117 1118 if (handle == NULL) { 1119 ALOGE("%s::handle == NULL() fail", __func__); 1120 return -1; 1121 } 1122 1123 exynos_mutex_lock(gsc_handle->op_mutex); 1124 1125 gsc_handle->src.width = width; 1126 gsc_handle->src.height = height; 1127 gsc_handle->src.crop_left = crop_left; 1128 gsc_handle->src.crop_top = crop_top; 1129 gsc_handle->src.crop_width = crop_width; 1130 gsc_handle->src.crop_height = crop_height; 1131 gsc_handle->src.v4l2_colorformat = v4l2_colorformat; 1132 gsc_handle->src.cacheable = cacheable; 1133 gsc_handle->src.mode_drm = mode_drm; 1134 1135 if (gsc_handle->flag_exclusive_open == true) { 1136 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src, false) == false) { 1137 ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__); 1138 } 1139 } 1140 1141 exynos_mutex_unlock(gsc_handle->op_mutex); 1142 1143 Exynos_gsc_Out(); 1144 1145 return 0; 1146} 1147 1148int exynos_gsc_set_dst_format( 1149 void *handle, 1150 unsigned int width, 1151 unsigned int height, 1152 unsigned int crop_left, 1153 unsigned int crop_top, 1154 unsigned int crop_width, 1155 unsigned int crop_height, 1156 unsigned int v4l2_colorformat, 1157 unsigned int cacheable, 1158 unsigned int mode_drm) 1159{ 1160 Exynos_gsc_In(); 1161 1162 struct GSC_HANDLE *gsc_handle; 1163 gsc_handle = (struct GSC_HANDLE *)handle; 1164 1165 if (handle == NULL) { 1166 ALOGE("%s::handle == NULL() fail", __func__); 1167 return -1; 1168 } 1169 1170 exynos_mutex_lock(gsc_handle->op_mutex); 1171 1172 gsc_handle->dst.width = width; 1173 gsc_handle->dst.height = height; 1174 gsc_handle->dst.crop_left = crop_left; 1175 gsc_handle->dst.crop_top = crop_top; 1176 gsc_handle->dst.crop_width = crop_width; 1177 gsc_handle->dst.crop_height = crop_height; 1178 gsc_handle->dst.v4l2_colorformat = v4l2_colorformat; 1179 gsc_handle->dst.cacheable = cacheable; 1180 gsc_handle->dst.mode_drm = mode_drm; 1181 1182 if (gsc_handle->flag_exclusive_open == true) { 1183 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst, false) == false) { 1184 ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__); 1185 } 1186 } 1187 1188 exynos_mutex_unlock(gsc_handle->op_mutex); 1189 1190 Exynos_gsc_Out(); 1191 return 0; 1192} 1193 1194static int exynos_gsc_ctrl_sysmmu( 1195 int fd, 1196 int flag) 1197{ 1198 int sys_mmu_flag = flag ^ 1; 1199 1200#if 0 //it will be enabled later 1201 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_USE_SYSMMU, sys_mmu_flag) < 0) { 1202 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_USE_SYSMMU) fail", __func__); 1203 return -1; 1204 } 1205#endif 1206 return 0; 1207} 1208 1209int exynos_gsc_set_rotation( 1210 void *handle, 1211 int rotation, 1212 int flip_horizontal, 1213 int flip_vertical) 1214{ 1215 int ret = -1; 1216 struct GSC_HANDLE *gsc_handle; 1217 gsc_handle = (struct GSC_HANDLE *)handle; 1218 1219 if (handle == NULL) { 1220 ALOGE("%s::handle == NULL() fail", __func__); 1221 return ret; 1222 } 1223 1224 exynos_mutex_lock(gsc_handle->op_mutex); 1225 1226 int new_rotation = rotation % 360; 1227 1228 if (new_rotation % 90 != 0) { 1229 ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__, rotation); 1230 goto done; 1231 } 1232 1233 if(new_rotation < 0) 1234 new_rotation = -new_rotation; 1235 1236 gsc_handle->dst.rotation = new_rotation; 1237 gsc_handle->dst.flip_horizontal = flip_horizontal; 1238 gsc_handle->dst.flip_vertical = flip_vertical; 1239 1240 ret = 0; 1241done: 1242 exynos_mutex_unlock(gsc_handle->op_mutex); 1243 1244 return ret; 1245} 1246 1247int exynos_gsc_set_src_addr( 1248 void *handle, 1249 void *addr[3]) 1250{ 1251 struct GSC_HANDLE *gsc_handle; 1252 gsc_handle = (struct GSC_HANDLE *)handle; 1253 1254 Exynos_gsc_In(); 1255 1256 if (handle == NULL) { 1257 ALOGE("%s::handle == NULL() fail", __func__); 1258 return -1; 1259 } 1260 1261 exynos_mutex_lock(gsc_handle->op_mutex); 1262 1263 gsc_handle->src.addr[0] = addr[0]; 1264 gsc_handle->src.addr[1] = addr[1]; 1265 gsc_handle->src.addr[2] = addr[2]; 1266 1267 if (gsc_handle->flag_exclusive_open == true) { 1268 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) { 1269 ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__); 1270 } 1271 } 1272 1273 exynos_mutex_unlock(gsc_handle->op_mutex); 1274 1275 Exynos_gsc_Out(); 1276 1277 return 0; 1278} 1279 1280int exynos_gsc_set_dst_addr( 1281 void *handle, 1282 void *addr[3]) 1283{ 1284 struct GSC_HANDLE *gsc_handle; 1285 gsc_handle = (struct GSC_HANDLE *)handle; 1286 int ret = 0; 1287 1288 Exynos_gsc_In(); 1289 1290 if (handle == NULL) { 1291 ALOGE("%s::handle == NULL() fail", __func__); 1292 return -1; 1293 } 1294 1295 exynos_mutex_lock(gsc_handle->op_mutex); 1296 1297 gsc_handle->dst.addr[0] = addr[0]; 1298 gsc_handle->dst.addr[1] = addr[1]; 1299 gsc_handle->dst.addr[2] = addr[2]; 1300 1301 if (gsc_handle->flag_exclusive_open == true) { 1302 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) { 1303 ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__); 1304 ret = -1; 1305 } 1306 } 1307 1308 exynos_mutex_unlock(gsc_handle->op_mutex); 1309 1310 Exynos_gsc_Out(); 1311 1312 return ret; 1313} 1314 1315static void rotateValueHAL2GSC(unsigned int transform, 1316 unsigned int *rotate, 1317 unsigned int *hflip, 1318 unsigned int *vflip) 1319{ 1320 int rotate_flag = transform & 0x7; 1321 *rotate = 0; 1322 *hflip = 0; 1323 *vflip = 0; 1324 1325 switch (rotate_flag) { 1326 case HAL_TRANSFORM_ROT_90: 1327 *rotate = 90; 1328 break; 1329 case HAL_TRANSFORM_ROT_180: 1330 *rotate = 180; 1331 break; 1332 case HAL_TRANSFORM_ROT_270: 1333 *rotate = 270; 1334 break; 1335 case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: 1336 *rotate = 90; 1337 *vflip = 1; /* set vflip to compensate the rot & flip order. */ 1338 break; 1339 case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: 1340 *rotate = 90; 1341 *hflip = 1; /* set hflip to compensate the rot & flip order. */ 1342 break; 1343 case HAL_TRANSFORM_FLIP_H: 1344 *hflip = 1; 1345 break; 1346 case HAL_TRANSFORM_FLIP_V: 1347 *vflip = 1; 1348 break; 1349 default: 1350 break; 1351 } 1352} 1353 1354static bool get_plane_size(int V4L2_PIX, 1355 unsigned int * size, 1356 unsigned int frame_size, 1357 int src_planes) 1358{ 1359 unsigned int frame_ratio = 1; 1360 int src_bpp = get_yuv_bpp(V4L2_PIX); 1361 1362 src_planes = (src_planes == -1) ? 1 : src_planes; 1363 frame_ratio = 8 * (src_planes -1) / (src_bpp - 8); 1364 1365 switch (src_planes) { 1366 case 1: 1367 switch (V4L2_PIX) { 1368 case V4L2_PIX_FMT_BGR32: 1369 case V4L2_PIX_FMT_RGB32: 1370 size[0] = frame_size << 2; 1371 break; 1372 case V4L2_PIX_FMT_RGB565X: 1373 case V4L2_PIX_FMT_NV16: 1374 case V4L2_PIX_FMT_NV61: 1375 case V4L2_PIX_FMT_YUYV: 1376 case V4L2_PIX_FMT_UYVY: 1377 case V4L2_PIX_FMT_VYUY: 1378 case V4L2_PIX_FMT_YVYU: 1379 size[0] = frame_size << 1; 1380 break; 1381 case V4L2_PIX_FMT_YUV420: 1382 case V4L2_PIX_FMT_NV12: 1383 case V4L2_PIX_FMT_NV21: 1384 case V4L2_PIX_FMT_NV21M: 1385 size[0] = (frame_size * 3) >> 1; 1386 break; 1387 default: 1388 ALOGE("%s::invalid color type", __func__); 1389 return false; 1390 break; 1391 } 1392 size[1] = 0; 1393 size[2] = 0; 1394 break; 1395 case 2: 1396 size[0] = frame_size; 1397 size[1] = frame_size / frame_ratio; 1398 size[2] = 0; 1399 break; 1400 case 3: 1401 size[0] = frame_size; 1402 size[1] = frame_size / frame_ratio; 1403 size[2] = frame_size / frame_ratio; 1404 break; 1405 default: 1406 ALOGE("%s::invalid color foarmt", __func__); 1407 return false; 1408 break; 1409 } 1410 1411 return true; 1412} 1413 1414int exynos_gsc_m2m_config(void *handle, 1415 exynos_gsc_img *src_img, 1416 exynos_gsc_img *dst_img) 1417{ 1418 struct GSC_HANDLE *gsc_handle; 1419 int32_t src_color_space; 1420 int32_t dst_color_space; 1421 int ret; 1422 unsigned int rotate; 1423 unsigned int hflip; 1424 unsigned int vflip; 1425 1426 Exynos_gsc_In(); 1427 1428 gsc_handle = (struct GSC_HANDLE *)handle; 1429 if (gsc_handle == NULL) { 1430 ALOGE("%s::gsc_handle == NULL() fail", __func__); 1431 return -1; 1432 } 1433 1434 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); 1435 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); 1436 rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip); 1437 exynos_gsc_set_rotation(gsc_handle, rotate, hflip, vflip); 1438 1439 ret = exynos_gsc_set_src_format(gsc_handle, src_img->fw, src_img->fh, 1440 src_img->x, src_img->y, src_img->w, src_img->h, 1441 src_color_space, src_img->cacheable, src_img->drmMode); 1442 if (ret < 0) { 1443 ALOGE("%s: fail: exynos_gsc_set_src_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]", 1444 __func__, src_img->fw, src_img->fh, src_img->x, src_img->y, src_img->w, src_img->h, 1445 src_color_space, src_img->rot); 1446 return -1; 1447 } 1448 1449 ret = exynos_gsc_set_dst_format(gsc_handle, dst_img->fw, dst_img->fh, 1450 dst_img->x, dst_img->y, dst_img->w, dst_img->h, 1451 dst_color_space, dst_img->cacheable, src_img->drmMode); 1452 if (ret < 0) { 1453 ALOGE("%s: fail: exynos_gsc_set_dst_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]", 1454 __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y, dst_img->w, dst_img->h, 1455 src_color_space, dst_img->rot); 1456 return -1; 1457 } 1458 1459 Exynos_gsc_Out(); 1460 1461 return 0; 1462} 1463 1464int exynos_gsc_out_config(void *handle, 1465 exynos_gsc_img *src_img, 1466 exynos_gsc_img *dst_img) 1467{ 1468 struct GSC_HANDLE *gsc_handle; 1469 struct v4l2_format fmt; 1470 struct v4l2_crop crop; 1471 struct v4l2_requestbuffers reqbuf; 1472 struct v4l2_subdev_format sd_fmt; 1473 struct v4l2_subdev_crop sd_crop; 1474 int i; 1475 unsigned int rotate; 1476 unsigned int hflip; 1477 unsigned int vflip; 1478 unsigned int plane_size[NUM_OF_GSC_PLANES]; 1479 bool rgb; 1480 1481 struct v4l2_rect dst_rect; 1482 int32_t src_color_space; 1483 int32_t dst_color_space; 1484 int32_t src_planes; 1485 1486 gsc_handle = (struct GSC_HANDLE *)handle; 1487 if (gsc_handle == NULL) { 1488 ALOGE("%s::gsc_handle == NULL() fail", __func__); 1489 return -1; 1490 } 1491 1492 Exynos_gsc_In(); 1493 1494 if (gsc_handle->src.stream_on != false) { 1495 ALOGE("Error: Src is already streamed on !!!!"); 1496 return -1; 1497 } 1498 1499 memcpy(&gsc_handle->src_img, src_img, sizeof(exynos_gsc_img)); 1500 memcpy(&gsc_handle->dst_img, dst_img, sizeof(exynos_gsc_img)); 1501 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); 1502 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); 1503 src_planes = get_yuv_planes(src_color_space); 1504 src_planes = (src_planes == -1) ? 1 : src_planes; 1505 rgb = get_yuv_planes(dst_color_space) == -1; 1506 rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip); 1507 1508 if (m_exynos_gsc_check_src_size(&gsc_handle->src_img.fw, &gsc_handle->src_img.fh, 1509 &gsc_handle->src_img.x, &gsc_handle->src_img.y, 1510 &gsc_handle->src_img.w, &gsc_handle->src_img.h, 1511 src_color_space) == false) { 1512 ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__); 1513 return -1; 1514 } 1515 1516 if (m_exynos_gsc_check_dst_size(&gsc_handle->dst_img.fw, &gsc_handle->dst_img.fh, 1517 &gsc_handle->dst_img.x, &gsc_handle->dst_img.y, 1518 &gsc_handle->dst_img.w, &gsc_handle->dst_img.h, 1519 dst_color_space, 1520 rotate) == false) { 1521 ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__); 1522 return -1; 1523 } 1524 1525 /*set: src v4l2_buffer*/ 1526 gsc_handle->src.src_buf_idx = 0; 1527 gsc_handle->src.qbuf_cnt = 0; 1528 /* set format: src pad of GSC sub-dev*/ 1529 sd_fmt.pad = GSCALER_SUBDEV_PAD_SOURCE; 1530 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1531 sd_fmt.format.width = gsc_handle->dst_img.fw; 1532 sd_fmt.format.height = gsc_handle->dst_img.fh; 1533 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE : 1534 V4L2_MBUS_FMT_YUV8_1X24; 1535 if (exynos_subdev_s_fmt(gsc_handle->gsc_sd_entity->fd, &sd_fmt) < 0) { 1536 ALOGE("%s::GSC subdev set format failed", __func__); 1537 return -1; 1538 } 1539 1540 /* set crop: src crop of GSC sub-dev*/ 1541 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE; 1542 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1543 sd_crop.rect.left = gsc_handle->dst_img.x; 1544 sd_crop.rect.top = gsc_handle->dst_img.y; 1545 sd_crop.rect.width = gsc_handle->dst_img.w; 1546 sd_crop.rect.height = gsc_handle->dst_img.h; 1547 if (exynos_subdev_s_crop(gsc_handle->gsc_sd_entity->fd, &sd_crop) < 0) { 1548 ALOGE("%s::GSC subdev set crop failed", __func__); 1549 return -1; 1550 } 1551 1552 /* sink pad is connected to GSC out */ 1553 /* set format: sink sub-dev */ 1554 if (gsc_handle->out_mode == GSC_OUT_FIMD) 1555 sd_fmt.pad = FIMD_SUBDEV_PAD_SINK; 1556 else 1557 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SINK; 1558 1559 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1560 sd_fmt.format.width = gsc_handle->dst_img.w; 1561 sd_fmt.format.height = gsc_handle->dst_img.h; 1562 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE : 1563 V4L2_MBUS_FMT_YUV8_1X24; 1564 if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) { 1565 ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad); 1566 return -1; 1567 } 1568 1569 /* set crop: sink sub-dev */ 1570 if (gsc_handle->out_mode == GSC_OUT_FIMD) 1571 sd_crop.pad = FIMD_SUBDEV_PAD_SINK; 1572 else 1573 sd_crop.pad = MIXER_V_SUBDEV_PAD_SINK; 1574 1575 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1576 sd_crop.rect.left = gsc_handle->dst_img.x; 1577 sd_crop.rect.top = gsc_handle->dst_img.y; 1578 sd_crop.rect.width = gsc_handle->dst_img.w; 1579 sd_crop.rect.height = gsc_handle->dst_img.h; 1580 if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) { 1581 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad); 1582 return -1; 1583 } 1584 1585 /*set GSC ctrls */ 1586 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_ROTATE, rotate) < 0) { 1587 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed", __func__, rotate); 1588 return -1; 1589 } 1590 1591 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_HFLIP, hflip) < 0) { 1592 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed", __func__, hflip); 1593 return -1; 1594 } 1595 1596 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_VFLIP, vflip) < 0) { 1597 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed", __func__, vflip); 1598 return -1; 1599 } 1600 1601 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CACHEABLE, 1) < 0) { 1602 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed", __func__); 1603 return -1; 1604 } 1605 1606 /* set src format :GSC video dev*/ 1607 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1608 fmt.fmt.pix_mp.width = gsc_handle->src_img.fw; 1609 fmt.fmt.pix_mp.height = gsc_handle->src_img.fh; 1610 fmt.fmt.pix_mp.pixelformat = src_color_space; 1611 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; 1612 fmt.fmt.pix_mp.num_planes = src_planes; 1613 1614 if (exynos_v4l2_s_fmt(gsc_handle->gsc_vd_entity->fd, &fmt) < 0) { 1615 ALOGE("%s::videodev set format failed", __func__); 1616 return -1; 1617 } 1618 1619 /* set src crop info :GSC video dev*/ 1620 crop.type = fmt.type; 1621 crop.c.left = gsc_handle->src_img.x; 1622 crop.c.top = gsc_handle->src_img.y; 1623 crop.c.width = gsc_handle->src_img.w; 1624 crop.c.height = gsc_handle->src_img.h; 1625 1626 if (exynos_v4l2_s_crop(gsc_handle->gsc_vd_entity->fd, &crop) < 0) { 1627 ALOGE("%s::videodev set crop failed", __func__); 1628 return -1; 1629 } 1630 1631 reqbuf.type = fmt.type; 1632 reqbuf.memory = V4L2_MEMORY_DMABUF; 1633 reqbuf.count = MAX_BUFFERS_GSCALER_OUT; 1634 1635 if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) { 1636 ALOGE("%s::request buffers failed", __func__); 1637 return -1; 1638 } 1639 1640 Exynos_gsc_Out(); 1641 1642 return 0; 1643} 1644 1645int exynos_gsc_out_run(void *handle, 1646 unsigned int yAddr, 1647 unsigned int uAddr, 1648 unsigned int vAddr) 1649{ 1650 struct GSC_HANDLE *gsc_handle; 1651 struct v4l2_plane planes[NUM_OF_GSC_PLANES]; 1652 struct v4l2_buffer buf; 1653 int32_t src_color_space; 1654 int32_t src_planes; 1655 int i; 1656 unsigned int plane_size[NUM_OF_GSC_PLANES]; 1657 1658 gsc_handle = (struct GSC_HANDLE *)handle; 1659 if (handle == NULL) { 1660 ALOGE("%s::handle == NULL() fail", __func__); 1661 return -1; 1662 } 1663 1664 memset(&buf, 0, sizeof(struct v4l2_buffer)); 1665 for (i = 0; i < NUM_OF_GSC_PLANES; i++) 1666 memset(&planes[i], 0, sizeof(struct v4l2_plane)); 1667 1668 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc_handle->src_img.format); 1669 src_planes = get_yuv_planes(src_color_space); 1670 src_planes = (src_planes == -1) ? 1 : src_planes; 1671 1672 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1673 buf.memory = V4L2_MEMORY_DMABUF; 1674 buf.length = src_planes; 1675 buf.index = gsc_handle->src.src_buf_idx; 1676 buf.m.planes = planes; 1677 1678 gsc_handle->src.addr[0] = (void *)yAddr; 1679 gsc_handle->src.addr[1] = (void *)uAddr; 1680 gsc_handle->src.addr[2] = (void *)vAddr; 1681 1682 if (get_plane_size(src_color_space, plane_size, 1683 gsc_handle->src_img.fw * gsc_handle->src_img.fh, src_planes) != true) { 1684 ALOGE("%s:get_plane_size:fail", __func__); 1685 return -1; 1686 } 1687 1688 for (i = 0; i < buf.length; i++) { 1689 buf.m.planes[i].m.fd = (int)gsc_handle->src.addr[i]; 1690 buf.m.planes[i].length = plane_size[i]; 1691 buf.m.planes[i].bytesused = plane_size[i]; 1692 } 1693 1694 /* Queue the buf */ 1695 if (exynos_v4l2_qbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) { 1696 ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)", __func__, 1697 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT); 1698 return -1; 1699 } 1700 gsc_handle->src.src_buf_idx++; 1701 gsc_handle->src.qbuf_cnt++; 1702 1703 if (gsc_handle->src.stream_on == false) { 1704 /* stream on after queing the second buffer 1705 to do: below logic should be changed to handle the single frame videos */ 1706#ifndef GSC_OUT_DELAYED_STREAMON 1707 if (gsc_handle->src.src_buf_idx == (MAX_BUFFERS_GSCALER_OUT - 2)) { 1708#else 1709 if (gsc_handle->src.src_buf_idx == (MAX_BUFFERS_GSCALER_OUT - 1)) { 1710#endif 1711 if (exynos_v4l2_streamon(gsc_handle->gsc_vd_entity->fd, buf.type) < 0) { 1712 ALOGE("%s::stream on failed", __func__); 1713 return -1; 1714 } 1715 gsc_handle->src.stream_on = true; 1716 } 1717 gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT; 1718#ifndef GSC_OUT_DMA_BLOCKING 1719 return 0; 1720#endif 1721 } 1722 1723 if (gsc_handle->src.qbuf_cnt < MAX_BUFFERS_GSCALER_OUT) 1724 return 0; 1725 1726 gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT; 1727 for (i = 0; i < MAX_BUFFERS_GSCALER_OUT; i++) 1728 memset(&planes[i], 0, sizeof(struct v4l2_plane)); 1729 1730 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1731 buf.memory = V4L2_MEMORY_DMABUF; 1732 buf.length = src_planes; 1733 buf.m.planes = planes; 1734 1735 /* DeQueue a buf */ 1736 if (exynos_v4l2_dqbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) { 1737 ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)", __func__, 1738 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT); 1739 return -1; 1740 } 1741 return 0; 1742} 1743 1744int exynos_gsc_out_stop(void *handle) 1745{ 1746 struct GSC_HANDLE *gsc_handle; 1747 struct v4l2_requestbuffers reqbuf; 1748 struct v4l2_buffer buf; 1749 struct v4l2_plane planes[NUM_OF_GSC_PLANES]; 1750 int i; 1751 1752 Exynos_gsc_In(); 1753 1754 gsc_handle = (struct GSC_HANDLE *)handle; 1755 if (handle == NULL) { 1756 ALOGE("%s::handle == NULL() fail", __func__); 1757 return -1; 1758 } 1759 1760 if (gsc_handle->src.stream_on == false) { 1761 /* to handle special scenario.*/ 1762 gsc_handle->src.src_buf_idx = 0; 1763 gsc_handle->src.qbuf_cnt = 0; 1764 ALOGD("%s::GSC is already stopped", __func__); 1765 goto SKIP_STREAMOFF; 1766 } 1767 gsc_handle->src.src_buf_idx = 0; 1768 gsc_handle->src.qbuf_cnt = 0; 1769 gsc_handle->src.stream_on = false; 1770 1771 if (exynos_v4l2_streamoff(gsc_handle->gsc_vd_entity->fd, 1772 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { 1773 ALOGE("%s::stream off failed", __func__); 1774 return -1; 1775 } 1776SKIP_STREAMOFF: 1777 /* Clear Buffer */ 1778 /*todo: support for other buffer type & memory */ 1779 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1780 reqbuf.memory = V4L2_MEMORY_DMABUF; 1781 reqbuf.count = 0; 1782 1783 if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) { 1784 ALOGE("%s::request buffers failed", __func__); 1785 return -1; 1786 } 1787 1788 Exynos_gsc_Out(); 1789 1790 return 0; 1791} 1792 1793static int exynos_gsc_m2m_run_core(void *handle) 1794{ 1795 struct GSC_HANDLE *gsc_handle; 1796 1797 gsc_handle = (struct GSC_HANDLE *)handle; 1798 1799 Exynos_gsc_In(); 1800 1801 if (handle == NULL) { 1802 ALOGE("%s::handle == NULL() fail", __func__); 1803 return -1; 1804 } 1805 1806 bool flag_new_gsc = false; 1807 1808 if (gsc_handle->flag_exclusive_open == false) { 1809 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) { 1810 if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) { 1811 ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__); 1812 goto done; 1813 } 1814 flag_new_gsc = true; 1815 } 1816 1817 if (m_exynos_gsc_check_src_size(&gsc_handle->src.width, &gsc_handle->src.height, 1818 &gsc_handle->src.crop_left, &gsc_handle->src.crop_top, 1819 &gsc_handle->src.crop_width, &gsc_handle->src.crop_height, 1820 gsc_handle->src.v4l2_colorformat) == false) { 1821 ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__); 1822 goto done; 1823 } 1824 1825 if (m_exynos_gsc_check_dst_size(&gsc_handle->dst.width, &gsc_handle->dst.height, 1826 &gsc_handle->dst.crop_left, &gsc_handle->dst.crop_top, 1827 &gsc_handle->dst.crop_width, &gsc_handle->dst.crop_height, 1828 gsc_handle->dst.v4l2_colorformat, 1829 gsc_handle->dst.rotation) == false) { 1830 ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__); 1831 goto done; 1832 } 1833 1834 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src, flag_new_gsc) == false) { 1835 ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__); 1836 goto done; 1837 } 1838 1839 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst, flag_new_gsc) == false) { 1840 ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__); 1841 goto done; 1842 } 1843 1844 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) { 1845 ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__); 1846 goto done; 1847 } 1848 1849 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) { 1850 ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__); 1851 goto done; 1852 } 1853 } 1854 1855 if (gsc_handle->src.stream_on == false) { 1856 if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) { 1857 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__); 1858 goto done; 1859 } 1860 gsc_handle->src.stream_on = true; 1861 } 1862 1863 if (gsc_handle->dst.stream_on == false) { 1864 if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) { 1865 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__); 1866 goto done; 1867 } 1868 gsc_handle->dst.stream_on = true; 1869 } 1870 1871 Exynos_gsc_Out(); 1872 1873 return 0; 1874 1875done: 1876 return -1; 1877} 1878 1879static int exynos_gsc_m2m_wait_frame_done(void *handle) 1880{ 1881 struct GSC_HANDLE *gsc_handle; 1882 struct v4l2_requestbuffers req_buf; 1883 1884 gsc_handle = (struct GSC_HANDLE *)handle; 1885 1886 Exynos_gsc_In(); 1887 1888 if (handle == NULL) { 1889 ALOGE("%s::handle == NULL() fail", __func__); 1890 return -1; 1891 } 1892 1893 if ((gsc_handle->src.stream_on == false) || (gsc_handle->dst.stream_on == false)) { 1894 ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__); 1895 return -1; 1896 } 1897 1898 if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->src.buffer) < 0) { 1899 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__); 1900 return -1; 1901 } 1902 1903 if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->dst.buffer) < 0) { 1904 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__); 1905 return -1; 1906 } 1907 1908 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) { 1909 ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__); 1910 return -1; 1911 } 1912 gsc_handle->src.stream_on = false; 1913 1914 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) { 1915 ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__); 1916 return -1; 1917 } 1918 gsc_handle->dst.stream_on = false; 1919 1920 /* src: clear_buf */ 1921 req_buf.count = 0; 1922 req_buf.type = gsc_handle->src.buf_type; 1923 req_buf.memory = V4L2_MEMORY_DMABUF; 1924 if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) { 1925 ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__); 1926 return -1; 1927 } 1928 1929 /* dst: clear_buf */ 1930 req_buf.count = 0; 1931 req_buf.type = gsc_handle->dst.buf_type; 1932 req_buf.memory = V4L2_MEMORY_DMABUF; 1933 if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) { 1934 ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__); 1935 return -1; 1936 } 1937 1938 Exynos_gsc_Out(); 1939 1940 return 0; 1941} 1942 1943int exynos_gsc_convert( 1944 void *handle) 1945{ 1946 struct GSC_HANDLE *gsc_handle; 1947 int ret = -1; 1948 gsc_handle = (struct GSC_HANDLE *)handle; 1949 1950 Exynos_gsc_In(); 1951 1952 if (handle == NULL) { 1953 ALOGE("%s::handle == NULL() fail", __func__); 1954 return -1; 1955 } 1956 1957 exynos_mutex_lock(gsc_handle->op_mutex); 1958 1959 if (gsc_handle->flag_local_path == true) { 1960 ALOGE("%s::this exynos_gsc is connected by another hw internaly. So, don't call exynos_gsc_convert()", __func__); 1961 goto done; 1962 } 1963 1964 if (exynos_gsc_m2m_run_core(handle) < 0) { 1965 ALOGE("%s::exynos_gsc_run_core fail", __func__); 1966 goto done; 1967 } 1968 1969 if (exynos_gsc_m2m_wait_frame_done(handle) < 0) { 1970 ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__); 1971 goto done; 1972 } 1973 1974 ret = 0; 1975 1976done: 1977 if (gsc_handle->flag_exclusive_open == false) { 1978 if (gsc_handle->flag_local_path == false) 1979 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 1980 } 1981 1982 exynos_mutex_unlock(gsc_handle->op_mutex); 1983 1984 Exynos_gsc_Out(); 1985 1986 return ret; 1987} 1988 1989int exynos_gsc_m2m_run(void *handle, 1990 exynos_gsc_img *src_img, 1991 exynos_gsc_img *dst_img) 1992{ 1993 void *addr[3] = {NULL, NULL, NULL}; 1994 int ret = 0; 1995 1996 Exynos_gsc_In(); 1997 1998 addr[0] = (void *)src_img->yaddr; 1999 addr[1] = (void *)src_img->uaddr; 2000 addr[2] = (void *)src_img->vaddr; 2001 2002 ret = exynos_gsc_set_src_addr(handle, addr); 2003 if (ret < 0) { 2004 ALOGE("%s::fail: exynos_gsc_set_src_addr[%x %x %x]", __func__, 2005 (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]); 2006 return -1; 2007 } 2008 2009 addr[0] = (void *)dst_img->yaddr; 2010 addr[1] = (void *)dst_img->uaddr; 2011 addr[2] = (void *)dst_img->vaddr; 2012 ret = exynos_gsc_set_dst_addr(handle, addr); 2013 if (ret < 0) { 2014 ALOGE("%s::fail: exynos_gsc_set_dst_addr[%x %x %x]", __func__, 2015 (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]); 2016 return -1; 2017 } 2018 2019 ret = exynos_gsc_m2m_run_core(handle); 2020 if (ret < 0) { 2021 ALOGE("%s::fail: exynos_gsc_m2m_run_core", __func__); 2022 return -1; 2023 } 2024 2025 Exynos_gsc_Out(); 2026 2027 return 0; 2028} 2029 2030int exynos_gsc_config_exclusive(void *handle, 2031 exynos_gsc_img *src_img, 2032 exynos_gsc_img *dst_img) 2033{ 2034 2035 Exynos_gsc_In(); 2036 2037 struct GSC_HANDLE *gsc_handle; 2038 int ret = 0; 2039 gsc_handle = (struct GSC_HANDLE *)handle; 2040 if (handle == NULL) { 2041 ALOGE("%s::handle == NULL() fail", __func__); 2042 return -1; 2043 } 2044 2045 switch (gsc_handle->gsc_mode) { 2046 case GSC_M2M_MODE: 2047 ret = exynos_gsc_m2m_config(handle, src_img, dst_img); 2048 break; 2049 case GSC_OUTPUT_MODE: 2050 ret = exynos_gsc_out_config(handle, src_img, dst_img); 2051 break; 2052 case GSC_CAPTURE_MODE: 2053 //to do 2054 break; 2055 default: 2056 break; 2057 } 2058 2059 Exynos_gsc_Out(); 2060 2061 return ret; 2062 2063} 2064 2065int exynos_gsc_run_exclusive(void *handle, 2066 exynos_gsc_img *src_img, 2067 exynos_gsc_img *dst_img) 2068{ 2069 struct GSC_HANDLE *gsc_handle; 2070 int ret = 0; 2071 2072 Exynos_gsc_In(); 2073 2074 gsc_handle = (struct GSC_HANDLE *)handle; 2075 if (handle == NULL) { 2076 ALOGE("%s::handle == NULL() fail", __func__); 2077 return -1; 2078 } 2079 2080 switch (gsc_handle->gsc_mode) { 2081 case GSC_M2M_MODE: 2082 ret = exynos_gsc_m2m_run(handle, src_img, dst_img); 2083 break; 2084 case GSC_OUTPUT_MODE: 2085 ret = exynos_gsc_out_run(handle, src_img->yaddr, 2086 src_img->uaddr, src_img->vaddr); 2087 break; 2088 case GSC_CAPTURE_MODE: 2089 //to do 2090 break; 2091 default: 2092 break; 2093 } 2094 2095 Exynos_gsc_Out(); 2096 2097 return ret; 2098} 2099 2100int exynos_gsc_stop_exclusive(void *handle) 2101{ 2102 struct GSC_HANDLE *gsc_handle; 2103 int ret = 0; 2104 gsc_handle = (struct GSC_HANDLE *)handle; 2105 2106 Exynos_gsc_In(); 2107 2108 if (handle == NULL) { 2109 ALOGE("%s::handle == NULL() fail", __func__); 2110 return -1; 2111 } 2112 2113 switch (gsc_handle->gsc_mode) { 2114 case GSC_M2M_MODE: 2115 ret = exynos_gsc_m2m_wait_frame_done(handle); 2116 break; 2117 case GSC_OUTPUT_MODE: 2118 ret = exynos_gsc_out_stop(handle); 2119 break; 2120 case GSC_CAPTURE_MODE: 2121 //to do 2122 break; 2123 default: 2124 break; 2125 } 2126 2127 Exynos_gsc_Out(); 2128 2129 return ret; 2130} 2131 2132int exynos_gsc_connect( 2133 void *handle, 2134 void *hw) 2135{ 2136 struct GSC_HANDLE *gsc_handle; 2137 int ret = -1; 2138 gsc_handle = (struct GSC_HANDLE *)handle; 2139 2140 Exynos_gsc_In(); 2141 2142 if (handle == NULL) { 2143 ALOGE("%s::handle == NULL() fail", __func__); 2144 return -1; 2145 } 2146 2147 exynos_mutex_lock(gsc_handle->op_mutex); 2148 2149 gsc_handle->flag_local_path = true; 2150 2151 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) { 2152 if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) { 2153 ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__); 2154 goto done; 2155 } 2156 } 2157 2158 ret = 0; 2159 2160 Exynos_gsc_Out(); 2161 2162done: 2163 exynos_mutex_unlock(gsc_handle->op_mutex); 2164 2165 return ret; 2166} 2167 2168int exynos_gsc_disconnect( 2169 void *handle, 2170 void *hw) 2171{ 2172 struct GSC_HANDLE *gsc_handle; 2173 gsc_handle = (struct GSC_HANDLE *)handle; 2174 2175 Exynos_gsc_In(); 2176 2177 if (handle == NULL) { 2178 ALOGE("%s::handle == NULL() fail", __func__); 2179 return -1; 2180 } 2181 2182 exynos_mutex_lock(gsc_handle->op_mutex); 2183 2184 gsc_handle->flag_local_path = false; 2185 2186 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 2187 2188 exynos_mutex_unlock(gsc_handle->op_mutex); 2189 2190 Exynos_gsc_Out(); 2191 2192 return 0; 2193} 2194