2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright@ Samsung Electronics Co. LTD
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \file exynos_rotator.c
20 * \brief source file for exynos_rotator HAL
21 * \author Sunmi Lee (carrotsm.lee@samsung.com)
24 * <b>Revision History: </b>
25 * - 2012/03/05 : Sunmi Lee (carrotsm.lee@samsung.com) \n
30 //#define LOG_NDEBUG 0
31 #define LOG_TAG "libexynosrotator"
32 #include <cutils/log.h>
34 #include <sys/types.h>
35 #include <sys/ioctl.h>
36 #include <videodev2.h>
45 #include "exynos_rotator.h"
47 #include "exynos_format.h"
48 #include "ExynosMutex.h"
49 #include "exynos_v4l2.h"
51 #define NUM_OF_ROTATOR_PLANES (3)
52 #define NODE_NUM_ROTATOR (21)
53 #define PFX_NODE_ROTATOR "/dev/video"
55 #define ROTATOR_MIN_W_SIZE (8)
56 #define ROTATOR_MIN_H_SIZE (8)
58 #define MAX_ROTATOR_WAITING_TIME_FOR_TRYLOCK (16000) // 16msec
59 #define ROTATOR_WAITING_TIME_FOR_TRYLOCK (8000) // 8msec
64 unsigned int crop_left
;
65 unsigned int crop_top
;
66 unsigned int crop_width
;
67 unsigned int crop_height
;
68 unsigned int v4l2_colorformat
;
69 unsigned int cacheable
;
73 void *addr
[NUM_OF_ROTATOR_PLANES
];
76 enum v4l2_buf_type buf_type
;
77 struct v4l2_format format
;
78 struct v4l2_buffer buffer
;
79 struct v4l2_plane planes
[NUM_OF_ROTATOR_PLANES
];
80 struct v4l2_crop crop
;
83 struct ROTATOR_HANDLE
{
85 struct rotator_info src
;
86 struct rotator_info dst
;
92 static unsigned int m_rotator_get_plane_count(
97 switch (v4l_pixel_format
) {
98 case V4L2_PIX_FMT_RGB32
:
99 case V4L2_PIX_FMT_BGR32
:
100 case V4L2_PIX_FMT_RGB24
:
101 case V4L2_PIX_FMT_RGB565
:
102 case V4L2_PIX_FMT_RGB555X
:
103 case V4L2_PIX_FMT_RGB444
:
106 case V4L2_PIX_FMT_NV12M
:
107 case V4L2_PIX_FMT_NV12MT_16X16
:
108 case V4L2_PIX_FMT_NV21
:
109 case V4L2_PIX_FMT_NV16
:
110 case V4L2_PIX_FMT_NV61
:
113 case V4L2_PIX_FMT_YVU420M
:
114 case V4L2_PIX_FMT_YUV422P
:
115 case V4L2_PIX_FMT_YUYV
:
116 case V4L2_PIX_FMT_UYVY
:
120 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)",
121 __func__
, v4l_pixel_format
);
129 static unsigned int m_rotator_get_plane_size(
130 unsigned int *plane_size
,
133 int v4l_pixel_format
)
135 switch (v4l_pixel_format
) {
136 case V4L2_PIX_FMT_RGB32
:
137 case V4L2_PIX_FMT_BGR32
:
138 plane_size
[0] = width
* height
* 4;
140 case V4L2_PIX_FMT_RGB24
:
141 plane_size
[0] = width
* height
* 3;
143 case V4L2_PIX_FMT_RGB565
:
144 case V4L2_PIX_FMT_RGB555X
:
145 case V4L2_PIX_FMT_RGB444
:
146 plane_size
[0] = width
* height
* 2;
148 case V4L2_PIX_FMT_NV12M
:
149 case V4L2_PIX_FMT_NV21
:
150 case V4L2_PIX_FMT_NV16
:
151 case V4L2_PIX_FMT_NV61
:
152 plane_size
[0] = width
* height
;
153 plane_size
[1] = width
* (height
/ 2);
155 case V4L2_PIX_FMT_NV12MT_16X16
:
156 plane_size
[0] = ALIGN(width
, 16) * ALIGN(height
, 16);
157 plane_size
[1] = ALIGN(width
, 16) * ALIGN(height
/ 2, 8);
159 case V4L2_PIX_FMT_YVU420M
:
160 case V4L2_PIX_FMT_YUV422P
:
161 case V4L2_PIX_FMT_YUYV
:
162 case V4L2_PIX_FMT_UYVY
:
163 plane_size
[0] = width
* height
;
164 plane_size
[1] = (width
/ 2) * (height
/ 2);
165 plane_size
[2] = (width
/ 2) * (height
/ 2);
168 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)",
169 __func__
, v4l_pixel_format
);
177 static int m_exynos_rotator_multiple_of_n(
191 result
= (number
- (number
& (N
-1)));
194 result
= number
- (number
% N
);
200 static bool m_exynos_rotator_check_src_size(
201 unsigned int *w
, unsigned int *h
,
202 unsigned int *crop_x
, unsigned int *crop_y
,
203 unsigned int *crop_w
, unsigned int *crop_h
,
204 int v4l2_colorformat
)
206 if (*w
< ROTATOR_MIN_W_SIZE
|| *h
< ROTATOR_MIN_H_SIZE
) {
207 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
208 __func__
, ROTATOR_MIN_W_SIZE
, *w
, ROTATOR_MIN_H_SIZE
, *h
);
212 if (*crop_w
< ROTATOR_MIN_W_SIZE
|| *crop_h
< ROTATOR_MIN_H_SIZE
) {
213 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
214 __func__
, ROTATOR_MIN_W_SIZE
,* crop_w
, ROTATOR_MIN_H_SIZE
, *crop_h
);
218 switch (v4l2_colorformat
) {
220 case V4L2_PIX_FMT_YUV420M
:
221 case V4L2_PIX_FMT_YVU420M
:
226 case V4L2_PIX_FMT_NV12M
:
227 case V4L2_PIX_FMT_NV12MT
:
228 case V4L2_PIX_FMT_NV21M
:
233 case V4L2_PIX_FMT_YUYV
:
234 case V4L2_PIX_FMT_YUV422P
:
235 case V4L2_PIX_FMT_UYVY
:
236 case V4L2_PIX_FMT_NV21
:
237 case V4L2_PIX_FMT_NV16
:
238 case V4L2_PIX_FMT_YVYU
:
239 case V4L2_PIX_FMT_VYUY
:
241 case V4L2_PIX_FMT_RGB32
:
242 case V4L2_PIX_FMT_RGB24
:
243 case V4L2_PIX_FMT_RGB565
:
244 case V4L2_PIX_FMT_BGR32
:
245 case V4L2_PIX_FMT_RGB555X
:
246 case V4L2_PIX_FMT_RGB444
:
252 *crop_w
= m_exynos_rotator_multiple_of_n(*crop_w
, 4);
253 *crop_h
= m_exynos_rotator_multiple_of_n(*crop_h
, 4);
258 static bool m_exynos_rotator_check_dst_size(
259 unsigned int *w
, unsigned int *h
,
260 unsigned int *crop_x
, unsigned int *crop_y
,
261 unsigned int *crop_w
, unsigned int *crop_h
,
262 int v4l2_colorformat
,
267 unsigned int *new_crop_w
;
268 unsigned int *new_crop_h
;
270 if (rotation
== 90 || rotation
== 270) {
282 if (*w
< ROTATOR_MIN_W_SIZE
|| *h
< ROTATOR_MIN_H_SIZE
) {
283 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
284 __func__
, ROTATOR_MIN_W_SIZE
, *w
, ROTATOR_MIN_H_SIZE
, *h
);
288 if (*crop_w
< ROTATOR_MIN_W_SIZE
|| *crop_h
< ROTATOR_MIN_H_SIZE
) {
289 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
290 __func__
, ROTATOR_MIN_W_SIZE
,* crop_w
, ROTATOR_MIN_H_SIZE
, *crop_h
);
294 switch (v4l2_colorformat
) {
296 case V4L2_PIX_FMT_YUV420M
:
297 case V4L2_PIX_FMT_YVU420M
:
298 *new_w
= ALIGN(*new_w
, 16);
299 *new_h
= ALIGN(*new_h
, 16);
302 case V4L2_PIX_FMT_NV12M
:
303 case V4L2_PIX_FMT_NV12MT
:
304 case V4L2_PIX_FMT_NV21M
:
305 *new_w
= ALIGN(*new_w
, 8);
306 *new_h
= ALIGN(*new_h
, 8);
309 case V4L2_PIX_FMT_YUYV
:
310 case V4L2_PIX_FMT_YUV422P
:
311 case V4L2_PIX_FMT_UYVY
:
312 case V4L2_PIX_FMT_NV21
:
313 case V4L2_PIX_FMT_NV16
:
314 case V4L2_PIX_FMT_YVYU
:
315 case V4L2_PIX_FMT_VYUY
:
317 case V4L2_PIX_FMT_RGB32
:
318 case V4L2_PIX_FMT_RGB24
:
319 case V4L2_PIX_FMT_RGB565
:
320 case V4L2_PIX_FMT_BGR32
:
321 case V4L2_PIX_FMT_RGB555X
:
322 case V4L2_PIX_FMT_RGB444
:
324 *new_w
= ALIGN(*new_w
, 4);
325 *new_h
= ALIGN(*new_h
, 4);
328 *new_crop_w
= m_exynos_rotator_multiple_of_n(*new_crop_w
, 4);
329 *new_crop_h
= m_exynos_rotator_multiple_of_n(*new_crop_h
, 4);
334 static int m_exynos_rotator_create(void)
340 sprintf(node
, "%s%d", PFX_NODE_ROTATOR
, NODE_NUM_ROTATOR
);
341 fd
= exynos_v4l2_open(node
, O_RDWR
);
343 ALOGE("%s::exynos_v4l2_open(%s) fail", __func__
, node
);
347 cap
= V4L2_CAP_STREAMING
|
348 V4L2_CAP_VIDEO_OUTPUT_MPLANE
|
349 V4L2_CAP_VIDEO_CAPTURE_MPLANE
;
351 if (exynos_v4l2_querycap(fd
, cap
) == false) {
352 ALOGE("%s::exynos_v4l2_querycap() fail", __func__
);
361 static bool m_exynos_rotator_destroy(
362 struct ROTATOR_HANDLE
*rotator_handle
)
364 if (rotator_handle
->src
.stream_on
== true) {
365 if (exynos_v4l2_streamoff(rotator_handle
->rotator_fd
, rotator_handle
->src
.buf_type
) < 0)
366 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__
);
368 rotator_handle
->src
.stream_on
= false;
371 if (rotator_handle
->dst
.stream_on
== true) {
372 if (exynos_v4l2_streamoff(rotator_handle
->rotator_fd
, rotator_handle
->dst
.buf_type
) < 0)
373 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__
);
375 rotator_handle
->dst
.stream_on
= false;
378 if (0 < rotator_handle
->rotator_fd
)
379 close(rotator_handle
->rotator_fd
);
380 rotator_handle
->rotator_fd
= 0;
385 bool m_exynos_rotator_find_and_trylock_and_create(
386 struct ROTATOR_HANDLE
*rotator_handle
)
389 bool flag_find_new_rotator
= false;
390 unsigned int total_sleep_time
= 0;
393 if (exynos_mutex_trylock(rotator_handle
->obj_mutex
) == true) {
396 m_exynos_rotator_destroy(rotator_handle
);
399 rotator_handle
->rotator_fd
= m_exynos_rotator_create();
400 if (rotator_handle
->rotator_fd
< 0) {
401 rotator_handle
->rotator_fd
= 0;
402 exynos_mutex_unlock(rotator_handle
->obj_mutex
);
406 if (rotator_handle
->cur_obj_mutex
)
407 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
409 rotator_handle
->cur_obj_mutex
= rotator_handle
->obj_mutex
;
411 flag_find_new_rotator
= true;
415 // waiting for another process doesn't use rotator.
416 // we need to make decision how to do.
417 if (flag_find_new_rotator
== false) {
418 usleep(ROTATOR_WAITING_TIME_FOR_TRYLOCK
);
419 total_sleep_time
+= ROTATOR_WAITING_TIME_FOR_TRYLOCK
;
420 ALOGV("%s::waiting for anthere process doens't use rotator", __func__
);
423 } while( flag_find_new_rotator
== false
424 && total_sleep_time
< MAX_ROTATOR_WAITING_TIME_FOR_TRYLOCK
);
426 if (flag_find_new_rotator
== false)
427 ALOGE("%s::we don't have no available rotator.. fail", __func__
);
429 return flag_find_new_rotator
;
432 static bool m_exynos_rotator_set_format(
434 struct rotator_info
*info
,
437 struct v4l2_requestbuffers req_buf
;
440 plane_count
= m_rotator_get_plane_count(info
->v4l2_colorformat
);
441 if (plane_count
< 0) {
442 ALOGE("%s::not supported v4l2_colorformat", __func__
);
446 if (force
== false) {
448 info
->format
.type
= info
->buf_type
;
449 if (exynos_v4l2_g_fmt(fd
, &info
->format
) < 0) {
450 ALOGE("%s::exynos_v4l2_g_fmt() fail type=%d", __func__
, info
->buf_type
);
454 if (info
->width
!= info
->format
.fmt
.pix_mp
.width
||
455 info
->height
!= info
->format
.fmt
.pix_mp
.height
||
456 info
->v4l2_colorformat
!= info
->format
.fmt
.pix_mp
.pixelformat
) {
457 ALOGV("%s::info is different..)", __func__
);
462 if (info
->buf_type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
463 info
->crop
.type
= info
->buf_type
;
464 if (exynos_v4l2_g_crop(fd
, &info
->crop
) < 0) {
465 ALOGE("%s::exynos_v4l2_g_crop() fail", __func__
);
469 if (info
->crop_left
!= info
->crop
.c
.left
||
470 info
->crop_top
!= info
->crop
.c
.top
||
471 info
->crop_width
!= info
->crop
.c
.width
||
472 info
->crop_height
!= info
->crop
.c
.height
) {
473 ALOGV("%s::crop is different..", __func__
);
482 if (exynos_v4l2_g_ctrl(fd
, V4L2_CID_ROTATE
, &value
) < 0) {
483 ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__
);
487 if (info
->rotation
!= value
) {
488 ALOGV("%s::rotation is different..", __func__
);
493 ALOGV("%s::fmt, crop is same with old-one, so skip s_fmt crop..", __func__
);
499 if (info
->stream_on
== true) {
500 if (exynos_v4l2_streamoff(fd
, info
->buf_type
) < 0) {
501 ALOGE("%s::exynos_v4l2_streamoff() fail", __func__
);
504 info
->stream_on
= false;
507 if (exynos_v4l2_s_ctrl(fd
, V4L2_CID_ROTATE
, info
->rotation
) < 0) {
508 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__
);
512 info
->format
.fmt
.pix_mp
.width
= info
->width
;
513 info
->format
.fmt
.pix_mp
.height
= info
->height
;
514 info
->format
.fmt
.pix_mp
.pixelformat
= info
->v4l2_colorformat
;
515 info
->format
.fmt
.pix_mp
.field
= V4L2_FIELD_ANY
;
516 info
->format
.fmt
.pix_mp
.num_planes
= plane_count
;
518 if (exynos_v4l2_s_fmt(fd
, &info
->format
) < 0) {
519 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__
);
523 if (info
->buf_type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
524 info
->crop
.type
= info
->buf_type
;
525 info
->crop
.c
.left
= info
->crop_left
;
526 info
->crop
.c
.top
= info
->crop_top
;
527 info
->crop
.c
.width
= info
->crop_width
;
528 info
->crop
.c
.height
= info
->crop_height
;
530 if (exynos_v4l2_s_crop(fd
, &info
->crop
) < 0) {
531 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__
);
536 if (exynos_v4l2_s_ctrl(fd
, V4L2_CID_CACHEABLE
, info
->cacheable
) < 0) {
537 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__
);
542 req_buf
.type
= info
->buf_type
;
543 req_buf
.memory
= V4L2_MEMORY_USERPTR
;
544 if (exynos_v4l2_reqbufs(fd
, &req_buf
) < 0) {
545 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__
);
552 static bool m_exynos_rotator_set_addr(
554 struct rotator_info
*info
)
557 unsigned int plane_size
[NUM_OF_ROTATOR_PLANES
];
559 m_rotator_get_plane_size(plane_size
,
562 info
->v4l2_colorformat
);
564 info
->buffer
.index
= 0;
565 info
->buffer
.type
= info
->buf_type
;
566 info
->buffer
.memory
= V4L2_MEMORY_USERPTR
;
567 info
->buffer
.m
.planes
= info
->planes
;
568 info
->buffer
.length
= info
->format
.fmt
.pix_mp
.num_planes
;
570 for (i
= 0; i
< info
->format
.fmt
.pix_mp
.num_planes
; i
++) {
571 info
->buffer
.m
.planes
[i
].m
.userptr
= (unsigned long)info
->addr
[i
];
572 info
->buffer
.m
.planes
[i
].length
= plane_size
[i
];
573 info
->buffer
.m
.planes
[i
].bytesused
= 0;
576 if (exynos_v4l2_qbuf(fd
, &info
->buffer
) < 0) {
577 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__
);
584 void *exynos_rotator_create(void)
590 struct ROTATOR_HANDLE
*rotator_handle
= (struct ROTATOR_HANDLE
*)malloc(sizeof(struct ROTATOR_HANDLE
));
591 if (rotator_handle
== NULL
) {
592 ALOGE("%s::malloc(struct ROTATOR_HANDLE) fail", __func__
);
596 rotator_handle
->rotator_fd
= 0;
597 memset(&rotator_handle
->src
, 0, sizeof(struct rotator_info
));
598 memset(&rotator_handle
->dst
, 0, sizeof(struct rotator_info
));
600 rotator_handle
->src
.buf_type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
601 rotator_handle
->dst
.buf_type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
603 rotator_handle
->op_mutex
= NULL
;
604 rotator_handle
->obj_mutex
= NULL
;
605 rotator_handle
->cur_obj_mutex
= NULL
;
608 op_id
= rand() % 1000000; // just make random id
609 sprintf(mutex_name
, "%sOp%d", LOG_TAG
, op_id
);
610 rotator_handle
->op_mutex
= exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE
, mutex_name
);
611 if (rotator_handle
->op_mutex
== NULL
) {
612 ALOGE("%s::exynos_mutex_create(%s) fail", __func__
, mutex_name
);
616 exynos_mutex_lock(rotator_handle
->op_mutex
);
618 sprintf(mutex_name
, "%sObject%d", LOG_TAG
, i
);
620 rotator_handle
->obj_mutex
= exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED
, mutex_name
);
621 if (rotator_handle
->obj_mutex
== NULL
) {
622 ALOGE("%s::exynos_mutex_create(%s) fail", __func__
, mutex_name
);
626 if (m_exynos_rotator_find_and_trylock_and_create(rotator_handle
) == false) {
627 ALOGE("%s::m_exynos_rotator_find_and_trylock_and_create() fail", __func__
);
631 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
632 exynos_mutex_unlock(rotator_handle
->op_mutex
);
634 return (void *)rotator_handle
;
637 if (rotator_handle
) {
638 m_exynos_rotator_destroy(rotator_handle
);
640 if (rotator_handle
->cur_obj_mutex
)
641 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
643 if ((rotator_handle
->obj_mutex
!= NULL
) &&
644 (exynos_mutex_get_created_status(rotator_handle
->obj_mutex
) == true)) {
645 if (exynos_mutex_destroy(rotator_handle
->obj_mutex
) == false)
646 ALOGE("%s::exynos_mutex_destroy() fail", __func__
);
649 if (rotator_handle
->op_mutex
)
650 exynos_mutex_unlock(rotator_handle
->op_mutex
);
652 free(rotator_handle
);
658 void exynos_rotator_destroy(
662 struct ROTATOR_HANDLE
*rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
664 if (handle
== NULL
) {
665 ALOGE("%s::handle == NULL() fail", __func__
);
669 exynos_mutex_lock(rotator_handle
->op_mutex
);
670 exynos_mutex_lock(rotator_handle
->cur_obj_mutex
);
672 m_exynos_rotator_destroy(rotator_handle
);
674 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
676 if ((rotator_handle
->obj_mutex
!= NULL
) &&
677 (exynos_mutex_get_created_status(rotator_handle
->obj_mutex
) == true)) {
678 if (exynos_mutex_destroy(rotator_handle
->obj_mutex
) == false)
679 ALOGE("%s::exynos_mutex_destroy() fail", __func__
);
682 exynos_mutex_unlock(rotator_handle
->op_mutex
);
685 free(rotator_handle
);
688 int exynos_rotator_set_src_format(
692 unsigned int crop_left
,
693 unsigned int crop_top
,
694 unsigned int crop_width
,
695 unsigned int crop_height
,
696 unsigned int v4l2_colorformat
,
697 unsigned int cacheable
)
699 struct ROTATOR_HANDLE
*rotator_handle
;
700 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
702 if (handle
== NULL
) {
703 ALOGE("%s::handle == NULL() fail", __func__
);
707 exynos_mutex_lock(rotator_handle
->op_mutex
);
709 rotator_handle
->src
.width
= width
;
710 rotator_handle
->src
.height
= height
;
711 rotator_handle
->src
.crop_left
= crop_left
;
712 rotator_handle
->src
.crop_top
= crop_top
;
713 rotator_handle
->src
.crop_width
= crop_width
;
714 rotator_handle
->src
.crop_height
= crop_height
;
715 rotator_handle
->src
.v4l2_colorformat
= v4l2_colorformat
;
716 rotator_handle
->src
.cacheable
= cacheable
;
718 exynos_mutex_unlock(rotator_handle
->op_mutex
);
723 int exynos_rotator_set_dst_format(
727 unsigned int crop_left
,
728 unsigned int crop_top
,
729 unsigned int v4l2_colorformat
,
730 unsigned int cacheable
)
732 struct ROTATOR_HANDLE
*rotator_handle
;
733 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
735 if (handle
== NULL
) {
736 ALOGE("%s::handle == NULL() fail", __func__
);
740 exynos_mutex_lock(rotator_handle
->op_mutex
);
742 rotator_handle
->dst
.width
= width
;
743 rotator_handle
->dst
.height
= height
;
744 rotator_handle
->dst
.crop_left
= crop_left
;
745 rotator_handle
->dst
.crop_top
= crop_top
;
746 rotator_handle
->dst
.crop_width
= rotator_handle
->src
.crop_width
;
747 rotator_handle
->dst
.crop_height
= rotator_handle
->src
.crop_height
;
748 rotator_handle
->dst
.v4l2_colorformat
= v4l2_colorformat
;
749 rotator_handle
->dst
.cacheable
= cacheable
;
751 exynos_mutex_unlock(rotator_handle
->op_mutex
);
756 int exynos_rotator_set_rotation(
761 struct ROTATOR_HANDLE
*rotator_handle
;
762 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
764 if (handle
== NULL
) {
765 ALOGE("%s::handle == NULL() fail", __func__
);
769 exynos_mutex_lock(rotator_handle
->op_mutex
);
771 int new_rotation
= rotation
% 360;
773 if (new_rotation
% 90 != 0) {
774 ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__
, rotation
);
779 new_rotation
= -new_rotation
;
781 rotator_handle
->src
.rotation
= new_rotation
;
782 rotator_handle
->dst
.rotation
= new_rotation
;
786 exynos_mutex_unlock(rotator_handle
->op_mutex
);
791 int exynos_rotator_set_src_addr(
795 struct ROTATOR_HANDLE
*rotator_handle
;
796 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
798 if (handle
== NULL
) {
799 ALOGE("%s::handle == NULL() fail", __func__
);
803 exynos_mutex_lock(rotator_handle
->op_mutex
);
805 rotator_handle
->src
.addr
[0] = addr
[0];
806 rotator_handle
->src
.addr
[1] = addr
[1];
807 rotator_handle
->src
.addr
[2] = addr
[2];
809 exynos_mutex_unlock(rotator_handle
->op_mutex
);
814 int exynos_rotator_set_dst_addr(
818 struct ROTATOR_HANDLE
*rotator_handle
;
819 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
821 if (handle
== NULL
) {
822 ALOGE("%s::handle == NULL() fail", __func__
);
826 exynos_mutex_lock(rotator_handle
->op_mutex
);
828 rotator_handle
->dst
.addr
[0] = addr
[0];
829 rotator_handle
->dst
.addr
[1] = addr
[1];
830 rotator_handle
->dst
.addr
[2] = addr
[2];
832 exynos_mutex_unlock(rotator_handle
->op_mutex
);
837 int exynos_rotator_convert(
840 struct ROTATOR_HANDLE
*rotator_handle
;
843 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
845 if (handle
== NULL
) {
846 ALOGE("%s::handle == NULL() fail", __func__
);
851 bool flag_new_rotator
= false;
853 exynos_mutex_lock(rotator_handle
->op_mutex
);
855 if (exynos_mutex_trylock(rotator_handle
->cur_obj_mutex
) == false) {
856 if (m_exynos_rotator_find_and_trylock_and_create(rotator_handle
) == false) {
857 ALOGE("%s::m_exynos_rotator_find_and_trylock_and_create() fail", __func__
);
860 flag_new_rotator
= true;
863 if (m_exynos_rotator_check_src_size(&rotator_handle
->src
.width
, &rotator_handle
->src
.width
,
864 &rotator_handle
->src
.crop_left
, &rotator_handle
->src
.crop_top
,
865 &rotator_handle
->src
.crop_width
, &rotator_handle
->src
.crop_height
,
866 rotator_handle
->src
.v4l2_colorformat
) == false) {
867 ALOGE("%s::m_exynos_rotator_check_size(src) fail", __func__
);
871 if (m_exynos_rotator_check_dst_size(&rotator_handle
->dst
.width
, &rotator_handle
->dst
.height
,
872 &rotator_handle
->dst
.crop_left
, &rotator_handle
->dst
.crop_top
,
873 &rotator_handle
->dst
.crop_width
, &rotator_handle
->dst
.crop_height
,
874 rotator_handle
->dst
.v4l2_colorformat
,
875 rotator_handle
->dst
.rotation
) == false) {
876 ALOGE("%s::m_exynos_rotator_check_size(dst) fail", __func__
);
880 if (m_exynos_rotator_set_format(rotator_handle
->rotator_fd
, &rotator_handle
->src
, flag_new_rotator
) == false) {
881 ALOGE("%s::m_exynos_rotator_set_format(src) fail", __func__
);
885 if (m_exynos_rotator_set_format(rotator_handle
->rotator_fd
, &rotator_handle
->dst
, flag_new_rotator
) == false) {
886 ALOGE("%s::m_exynos_rotator_set_format(dst) fail", __func__
);
890 if (m_exynos_rotator_set_addr(rotator_handle
->rotator_fd
, &rotator_handle
->src
) == false) {
891 ALOGE("%s::m_exynos_rotator_set_addr(src) fail", __func__
);
895 if (m_exynos_rotator_set_addr(rotator_handle
->rotator_fd
, &rotator_handle
->dst
) == false) {
896 ALOGE("%s::m_exynos_rotator_set_addr(dst) fail", __func__
);
900 if (rotator_handle
->src
.stream_on
== false) {
901 if (exynos_v4l2_streamon(rotator_handle
->rotator_fd
, rotator_handle
->src
.buf_type
) < 0) {
902 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__
);
905 rotator_handle
->src
.stream_on
= true;
908 if (rotator_handle
->dst
.stream_on
== false) {
909 if (exynos_v4l2_streamon(rotator_handle
->rotator_fd
, rotator_handle
->dst
.buf_type
) < 0) {
910 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__
);
913 rotator_handle
->dst
.stream_on
= true;
916 if (exynos_v4l2_dqbuf(rotator_handle
->rotator_fd
, &rotator_handle
->src
.buffer
) < 0) {
917 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__
);
921 if (exynos_v4l2_dqbuf(rotator_handle
->rotator_fd
, &rotator_handle
->dst
.buffer
) < 0) {
922 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__
);
926 if (rotator_handle
->src
.stream_on
== true) {
927 if (exynos_v4l2_streamoff(rotator_handle
->rotator_fd
, rotator_handle
->src
.buf_type
) < 0) {
928 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__
);
931 rotator_handle
->src
.stream_on
= false;
934 if (rotator_handle
->dst
.stream_on
== true) {
935 if (exynos_v4l2_streamoff(rotator_handle
->rotator_fd
, rotator_handle
->dst
.buf_type
) < 0) {
936 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__
);
939 rotator_handle
->dst
.stream_on
= false;
945 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
946 exynos_mutex_unlock(rotator_handle
->op_mutex
);
951 int exynos_rotator_connect(
955 struct ROTATOR_HANDLE
*rotator_handle
;
957 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
959 if (handle
== NULL
) {
960 ALOGE("%s::handle == NULL() fail", __func__
);
964 exynos_mutex_lock(rotator_handle
->op_mutex
);
966 if (exynos_mutex_trylock(rotator_handle
->cur_obj_mutex
) == false) {
967 if (m_exynos_rotator_find_and_trylock_and_create(rotator_handle
) == false) {
968 ALOGE("%s::m_exynos_rotator_find_and_trylock_and_create() fail", __func__
);
976 exynos_mutex_unlock(rotator_handle
->op_mutex
);
981 int exynos_rotator_disconnect(
985 struct ROTATOR_HANDLE
*rotator_handle
;
986 rotator_handle
= (struct ROTATOR_HANDLE
*)handle
;
988 if (handle
== NULL
) {
989 ALOGE("%s::handle == NULL() fail", __func__
);
993 exynos_mutex_lock(rotator_handle
->op_mutex
);
995 exynos_mutex_unlock(rotator_handle
->cur_obj_mutex
);
996 exynos_mutex_unlock(rotator_handle
->op_mutex
);