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