2 * Copyright (C) 2013 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 libgscaler_obj.cpp
20 * \brief source file for Gscaler HAL
21 * \author Sungchun Kang (sungchun.kang@samsung.com)
24 * <b>Revision History: </b>
25 * - 2013.06.01 : Sungchun Kang (sungchun.kang@samsung.com) \n
30 #include "libgscaler_obj.h"
31 #include <system/graphics.h>
32 #include <content_protect.h>
34 int CGscaler::m_gsc_output_create(void *handle, int dev_num, int out_mode)
38 struct media_device *media0;
39 struct media_entity *gsc_sd_entity;
40 struct media_entity *gsc_vd_entity;
41 struct media_entity *sink_sd_entity;
45 CGscaler* gsc = GetGscaler(handle);
47 ALOGE("%s::handle == NULL() fail", __func__);
51 if ((out_mode != GSC_OUT_FIMD) &&
52 (out_mode != GSC_OUT_TV))
55 gsc->out_mode = out_mode;
56 /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
57 if ((out_mode == GSC_OUT_FIMD) &&
58 #ifndef USES_ONLY_GSC0_GSC1
66 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 0);
67 media0 = exynos_media_open(node);
69 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
72 gsc->mdev.media0 = media0;
74 /* Get the sink subdev entity by name and make the node of sink subdev*/
75 if (out_mode == GSC_OUT_FIMD)
76 snprintf(devname, sizeof(devname), PFX_FIMD_ENTITY, dev_num);
78 snprintf(devname, sizeof(devname), PFX_MXR_ENTITY, 0);
80 sink_sd_entity = exynos_media_get_entity_by_name(media0, devname,
82 if (!sink_sd_entity) {
83 ALOGE("%s:: failed to get the sink sd entity", __func__);
86 gsc->mdev.sink_sd_entity = sink_sd_entity;
88 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
89 if (sink_sd_entity->fd < 0) {
90 ALOGE("%s:: failed to open sink subdev node", __func__);
94 /* get GSC video dev & sub dev entity by name*/
98 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
101 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
104 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
108 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
110 gsc_vd_entity = exynos_media_get_entity_by_name(media0, devname,
112 if (!gsc_vd_entity) {
113 ALOGE("%s:: failed to get the gsc vd entity", __func__);
116 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
118 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
119 gsc_sd_entity = exynos_media_get_entity_by_name(media0, devname,
121 if (!gsc_sd_entity) {
122 ALOGE("%s:: failed to get the gsc sd entity", __func__);
125 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
127 /* gsc sub-dev open */
128 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
129 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
130 if (gsc_sd_entity->fd < 0) {
131 ALOGE("%s: gsc sub-dev open fail", __func__);
135 /* gsc video-dev open */
139 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
142 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
145 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
149 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
151 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR | O_NONBLOCK);
152 if (gsc_vd_entity->fd < 0) {
153 ALOGE("%s: gsc video-dev open fail", __func__);
157 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
159 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
160 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
169 gsc->m_gsc_out_destroy(handle);
174 int CGscaler::m_gsc_capture_create(void *handle, int dev_num, int out_mode)
178 struct media_device *media1;
179 struct media_entity *gsc_sd_entity;
180 struct media_entity *gsc_vd_entity;
181 struct media_entity *sink_sd_entity;
185 CGscaler* gsc = GetGscaler(handle);
187 ALOGE("%s::handle == NULL() fail", __func__);
191 gsc->out_mode = out_mode;
197 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 1);
198 media1 = exynos_media_open(node);
199 if (media1 == NULL) {
200 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
203 gsc->mdev.media1 = media1;
205 /* DECON-TV sub-device Open */
206 snprintf(devname, sizeof(devname), DEX_WB_SD_NAME);
208 sink_sd_entity = exynos_media_get_entity_by_name(media1, devname,
210 if (!sink_sd_entity) {
211 ALOGE("%s:: failed to get the sink sd entity", __func__);
214 gsc->mdev.sink_sd_entity = sink_sd_entity;
216 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
217 if (sink_sd_entity->fd < 0) {
218 ALOGE("%s:: failed to open sink subdev node", __func__);
222 /* Gscaler2 capture video-device Open */
223 snprintf(devname, sizeof(devname), PFX_GSC_CAPTURE_ENTITY);
224 gsc_vd_entity = exynos_media_get_entity_by_name(media1, devname,
226 if (!gsc_vd_entity) {
227 ALOGE("%s:: failed to get the gsc vd entity", __func__);
230 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
232 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
233 if (gsc_vd_entity->fd < 0) {
234 ALOGE("%s: gsc video-dev open fail", __func__);
238 /* Gscaler2 capture sub-device Open */
239 snprintf(devname, sizeof(devname), GSC_WB_SD_NAME);
240 gsc_sd_entity = exynos_media_get_entity_by_name(media1, devname,
242 if (!gsc_sd_entity) {
243 ALOGE("%s:: failed to get the gsc sd entity", __func__);
246 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
248 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
249 if (gsc_sd_entity->fd < 0) {
250 ALOGE("%s: gsc sub-dev open fail", __func__);
254 if (exynos_media_setup_link(media1, sink_sd_entity->pads,
255 gsc_sd_entity->pads, MEDIA_LNK_FL_ENABLED) < 0) {
256 ALOGE("%s::exynos_media_setup_link failed", __func__);
260 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
262 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
263 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
272 gsc->m_gsc_cap_destroy(handle);
277 int CGscaler::m_gsc_out_stop(void *handle)
281 CGscaler* gsc = GetGscaler(handle);
283 ALOGE("%s::handle == NULL() fail", __func__);
287 if (gsc->src_info.stream_on == false) {
288 /* to handle special scenario.*/
289 gsc->src_info.qbuf_cnt = 0;
290 ALOGD("%s::GSC is already stopped", __func__);
293 gsc->src_info.qbuf_cnt = 0;
294 gsc->src_info.stream_on = false;
296 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
297 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
298 ALOGE("%s::stream off failed", __func__);
308 int CGscaler::m_gsc_cap_stop(void *handle)
312 CGscaler* gsc = GetGscaler(handle);
314 ALOGE("%s::handle == NULL() fail", __func__);
318 if (gsc->dst_info.stream_on == false) {
319 /* to handle special scenario.*/
320 gsc->dst_info.qbuf_cnt = 0;
321 ALOGD("%s::GSC is already stopped", __func__);
324 gsc->dst_info.qbuf_cnt = 0;
325 gsc->dst_info.stream_on = false;
327 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
328 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
329 ALOGE("%s::stream off failed", __func__);
339 bool CGscaler::m_gsc_out_destroy(void *handle)
343 CGscaler* gsc = GetGscaler(handle);
345 ALOGE("%s::handle == NULL() fail", __func__);
349 if (gsc->src_info.stream_on == true) {
350 if (gsc->m_gsc_out_stop(gsc) < 0)
351 ALOGE("%s::m_gsc_out_stop() fail", __func__);
353 gsc->src_info.stream_on = false;
356 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
357 close(gsc->mdev.gsc_vd_entity->fd);
358 gsc->mdev.gsc_vd_entity->fd = -1;
361 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
362 close(gsc->mdev.gsc_sd_entity->fd);
363 gsc->mdev.gsc_sd_entity->fd = -1;
366 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
367 close(gsc->mdev.sink_sd_entity->fd);
368 gsc->mdev.sink_sd_entity->fd = -1;
371 if (gsc->mdev.media0)
372 exynos_media_close(gsc->mdev.media0);
374 gsc->mdev.media0 = NULL;
375 gsc->mdev.gsc_sd_entity = NULL;
376 gsc->mdev.gsc_vd_entity = NULL;
377 gsc->mdev.sink_sd_entity = NULL;
383 bool CGscaler::m_gsc_cap_destroy(void *handle)
387 CGscaler* gsc = GetGscaler(handle);
389 ALOGE("%s::handle == NULL() fail", __func__);
393 if (gsc->dst_info.stream_on == true) {
394 if (gsc->m_gsc_cap_stop(gsc) < 0)
395 ALOGE("%s::m_gsc_cap_stop() fail", __func__);
397 gsc->dst_info.stream_on = false;
400 if (!gsc->mdev.media1 || !gsc->mdev.gsc_sd_entity ||
401 !gsc->mdev.gsc_vd_entity || !gsc->mdev.sink_sd_entity) {
402 ALOGE("%s::gsc->mdev information is null", __func__);
406 if (exynos_media_setup_link(gsc->mdev.media1,
407 gsc->mdev.sink_sd_entity->pads,
408 gsc->mdev.gsc_sd_entity->pads, 0) < 0) {
409 ALOGE("%s::exynos_media_setup_unlin failed", __func__);
412 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
413 close(gsc->mdev.gsc_vd_entity->fd);
414 gsc->mdev.gsc_vd_entity->fd = -1;
417 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
418 close(gsc->mdev.gsc_sd_entity->fd);
419 gsc->mdev.gsc_sd_entity->fd = -1;
422 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
423 close(gsc->mdev.sink_sd_entity->fd);
424 gsc->mdev.sink_sd_entity->fd = -1;
427 if (gsc->mdev.media1)
428 exynos_media_close(gsc->mdev.media1);
430 gsc->mdev.media1 = NULL;
431 gsc->mdev.gsc_sd_entity = NULL;
432 gsc->mdev.gsc_vd_entity = NULL;
433 gsc->mdev.sink_sd_entity = NULL;
439 int CGscaler::m_gsc_m2m_create(int dev)
450 video_node_num = NODE_NUM_GSC_0;
453 video_node_num = NODE_NUM_GSC_1;
455 #ifndef USES_ONLY_GSC0_GSC1
457 video_node_num = NODE_NUM_GSC_2;
460 video_node_num = NODE_NUM_GSC_3;
464 ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
469 snprintf(node, sizeof(node), "%s%d", PFX_NODE_GSC, video_node_num);
470 fd = exynos_v4l2_open(node, O_RDWR);
472 ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
476 cap = V4L2_CAP_STREAMING |
477 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
478 V4L2_CAP_VIDEO_CAPTURE_MPLANE;
480 if (exynos_v4l2_querycap(fd, cap) == false) {
481 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
492 bool CGscaler::m_gsc_find_and_create(void *handle)
497 bool flag_find_new_gsc = false;
498 unsigned int total_sleep_time = 0;
499 CGscaler* gsc = GetGscaler(handle);
501 ALOGE("%s::handle == NULL() fail", __func__);
506 for (i = 0; i < NUM_OF_GSC_HW; i++) {
507 #ifndef USES_ONLY_GSC0_GSC1
508 if (i == 0 || i == 3)
515 gsc->gsc_fd = gsc->m_gsc_m2m_create(i);
516 if (gsc->gsc_fd < 0) {
521 flag_find_new_gsc = true;
525 if (flag_find_new_gsc == false) {
526 usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
527 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
528 ALOGV("%s::waiting for the gscaler availability", __func__);
531 } while(flag_find_new_gsc == false
532 && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
534 if (flag_find_new_gsc == false)
535 ALOGE("%s::we don't have any available gsc.. fail", __func__);
539 return flag_find_new_gsc;
542 bool CGscaler::m_gsc_m2m_destroy(void *handle)
546 CGscaler* gsc = GetGscaler(handle);
548 ALOGE("%s::handle == NULL() fail", __func__);
553 * just in case, we call stop here because we cannot afford to leave
554 * secure side protection on if things failed.
556 gsc->m_gsc_m2m_stop(handle);
558 if (gsc->gsc_id >= HW_SCAL0) {
559 bool ret = exynos_sc_free_and_close(gsc->scaler);
573 int CGscaler::m_gsc_m2m_stop(void *handle)
577 struct v4l2_requestbuffers req_buf;
579 CGscaler* gsc = GetGscaler(handle);
581 ALOGE("%s::handle == NULL() fail", __func__);
585 if (!gsc->src_info.stream_on && !gsc->dst_info.stream_on) {
586 /* wasn't streaming, return success */
588 } else if (gsc->src_info.stream_on != gsc->dst_info.stream_on) {
589 ALOGE("%s: invalid state, queue stream state doesn't match \
590 (%d != %d)", __func__, gsc->src_info.stream_on,
591 gsc->dst_info.stream_on);
596 * we need to plow forward on errors below to make sure that if we had
597 * turned on content protection on secure side, we turn it off.
599 * also, if we only failed to turn on one of the streams, we'll turn
600 * the other one off correctly.
602 if (gsc->src_info.stream_on == true) {
603 if (exynos_v4l2_streamoff(gsc->gsc_fd,
604 gsc->src_info.buf.buf_type) < 0) {
605 ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
608 gsc->src_info.stream_on = false;
611 if (gsc->dst_info.stream_on == true) {
612 if (exynos_v4l2_streamoff(gsc->gsc_fd,
613 gsc->dst_info.buf.buf_type) < 0) {
614 ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
617 gsc->dst_info.stream_on = false;
620 /* if drm is enabled */
621 if (gsc->allow_drm && gsc->protection_enabled) {
623 if (gsc->gsc_id == 0)
624 protect_id = CP_PROTECT_GSC0;
625 else if (gsc->gsc_id == 1)
626 protect_id = CP_PROTECT_GSC1;
627 else if (gsc->gsc_id == 2)
628 protect_id = CP_PROTECT_GSC2;
629 else if (gsc->gsc_id == 3)
630 protect_id = CP_PROTECT_GSC3;
632 /* CP_Disable_Path_Protection(protect_id); */
633 gsc->protection_enabled = false;
636 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
637 V4L2_CID_CONTENT_PROTECTION, 0) < 0) {
638 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
645 req_buf.type = gsc->src_info.buf.buf_type;
646 req_buf.memory = gsc->src_info.buf.mem_type;
647 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
648 ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
654 req_buf.type = gsc->dst_info.buf.buf_type;
655 req_buf.memory = gsc->dst_info.buf.mem_type;;
656 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
657 ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
666 int CGscaler::m_gsc_m2m_run_core(void *handle)
670 unsigned int rotate, hflip, vflip;
673 CGscaler* gsc = GetGscaler(handle);
675 ALOGE("%s::handle == NULL() fail", __func__);
679 is_dirty = gsc->src_info.dirty || gsc->dst_info.dirty;
680 is_drm = gsc->src_info.mode_drm;
682 if (is_dirty && (gsc->src_info.mode_drm != gsc->dst_info.mode_drm)) {
683 ALOGE("%s: drm mode mismatch between src and dst, \
684 gsc%d (s=%d d=%d)", __func__, gsc->gsc_id,
685 gsc->src_info.mode_drm, gsc->dst_info.mode_drm);
687 } else if (is_drm && !gsc->allow_drm) {
688 ALOGE("%s: drm mode is not supported on gsc%d", __func__,
693 CGscaler::rotateValueHAL2GSC(gsc->dst_img.rot, &rotate, &hflip, &vflip);
695 if (CGscaler::m_gsc_check_src_size(&gsc->src_info.width,
696 &gsc->src_info.height, &gsc->src_info.crop_left,
697 &gsc->src_info.crop_top, &gsc->src_info.crop_width,
698 &gsc->src_info.crop_height, gsc->src_info.v4l2_colorformat,
699 (rotate == 90 || rotate == 270)) == false) {
700 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
704 if (CGscaler::m_gsc_check_dst_size(&gsc->dst_info.width,
705 &gsc->dst_info.height, &gsc->dst_info.crop_left,
706 &gsc->dst_info.crop_top, &gsc->dst_info.crop_width,
707 &gsc->dst_info.crop_height, gsc->dst_info.v4l2_colorformat,
708 gsc->dst_info.rotation) == false) {
709 ALOGE("%s::m_gsc_check_dst_size() fail", __func__);
713 /* dequeue buffers from previous work if necessary */
714 if (gsc->src_info.stream_on == true) {
715 if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
716 ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__);
722 * need to set the content protection flag before doing reqbufs
725 if (is_dirty && gsc->allow_drm && is_drm) {
726 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
727 V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) {
728 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
734 * from this point on, we have to ensure to call stop to clean up
735 * whatever state we have set.
738 if (gsc->src_info.dirty) {
739 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->src_info) == false) {
740 ALOGE("%s::m_gsc_set_format(src) fail", __func__);
743 gsc->src_info.dirty = false;
746 if (gsc->dst_info.dirty) {
747 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->dst_info) == false) {
748 ALOGE("%s::m_gsc_set_format(dst) fail", __func__);
751 gsc->dst_info.dirty = false;
755 * set up csc equation property
758 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
759 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
760 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
764 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
765 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
766 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
770 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
771 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
772 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
777 /* if we are enabling drm, make sure to enable hw protection.
778 * Need to do this before queuing buffers so that the mmu is reserved
779 * and power domain is kept on.
781 if (is_dirty && gsc->allow_drm && is_drm) {
783 if (gsc->gsc_id == 0) {
784 protect_id = CP_PROTECT_GSC0;
785 } else if (gsc->gsc_id == 1) {
786 protect_id = CP_PROTECT_GSC1;
787 } else if (gsc->gsc_id == 2) {
788 protect_id = CP_PROTECT_GSC2;
789 } else if (gsc->gsc_id == 3) {
790 protect_id = CP_PROTECT_GSC3;
792 ALOGE("%s::invalid gscaler id %d for content protection",
793 __func__, gsc->gsc_id);
797 /* if (CP_Enable_Path_Protection(protect_id) != 0) {
798 ALOGE("%s::CP_Enable_Path_Protection failed", __func__);
801 gsc->protection_enabled = true;
804 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->src_info) == false) {
805 ALOGE("%s::m_gsc_set_addr(src) fail", __func__);
809 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->dst_info) == false) {
810 ALOGE("%s::m_gsc_set_addr(dst) fail", __func__);
814 if (gsc->src_info.stream_on == false) {
815 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->src_info.buf.buf_type) < 0) {
816 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
819 gsc->src_info.stream_on = true;
822 if (gsc->dst_info.stream_on == false) {
823 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->dst_info.buf.buf_type) < 0) {
824 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
827 gsc->dst_info.stream_on = true;
835 gsc->m_gsc_m2m_stop(handle);
839 bool CGscaler::m_gsc_check_src_size(
840 unsigned int *w, unsigned int *h,
841 unsigned int *crop_x, unsigned int *crop_y,
842 unsigned int *crop_w, unsigned int *crop_h,
843 int v4l2_colorformat, bool rotation)
845 unsigned int minWidth, minHeight, shift = 0;
846 if (v4l2_colorformat == V4L2_PIX_FMT_RGB32 || v4l2_colorformat == V4L2_PIX_FMT_RGB565)
849 minWidth = GSC_MIN_SRC_H_SIZE >> shift;
850 minHeight = GSC_MIN_SRC_W_SIZE >> shift;
852 minWidth = GSC_MIN_SRC_W_SIZE >> shift;
853 minHeight = GSC_MIN_SRC_H_SIZE >> shift;
856 if (*w < minWidth || *h < minHeight) {
857 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
858 __func__, GSC_MIN_SRC_W_SIZE, *w, GSC_MIN_SRC_H_SIZE, *h);
862 if (*crop_w < minWidth || *crop_h < minHeight) {
863 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
864 __func__, GSC_MIN_SRC_W_SIZE,* crop_w, GSC_MIN_SRC_H_SIZE, *crop_h);
871 bool CGscaler::m_gsc_check_dst_size(
872 unsigned int *w, unsigned int *h,
873 unsigned int *crop_x, unsigned int *crop_y,
874 unsigned int *crop_w, unsigned int *crop_h,
875 int v4l2_colorformat,
878 if (*w < GSC_MIN_DST_W_SIZE || *h < GSC_MIN_DST_H_SIZE) {
879 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
880 __func__, GSC_MIN_DST_W_SIZE, *w, GSC_MIN_DST_H_SIZE, *h);
884 if (*crop_w < GSC_MIN_DST_W_SIZE || *crop_h < GSC_MIN_DST_H_SIZE) {
885 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
886 __func__, GSC_MIN_DST_W_SIZE,* crop_w, GSC_MIN_DST_H_SIZE, *crop_h);
894 int CGscaler::m_gsc_multiple_of_n(int number, int N)
907 result = (number - (number & (N-1)));
910 result = number - (number % N);
916 int CGscaler::m_gsc_m2m_wait_frame_done(void *handle)
920 CGscaler* gsc = GetGscaler(handle);
922 ALOGE("%s::handle == NULL() fail", __func__);
926 if ((gsc->src_info.stream_on == false) ||
927 (gsc->dst_info.stream_on == false)) {
928 ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
932 if (gsc->src_info.buf.buffer_queued) {
933 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->src_info.buf.buffer) < 0) {
934 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
937 gsc->src_info.buf.buffer_queued = false;
940 if (gsc->dst_info.buf.buffer_queued) {
941 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->dst_info.buf.buffer) < 0) {
942 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
945 gsc->dst_info.buf.buffer_queued = false;
953 bool CGscaler::m_gsc_set_format(int fd, GscInfo *info)
957 struct v4l2_requestbuffers req_buf;
960 plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
961 if (plane_count < 0) {
962 ALOGE("%s::not supported v4l2_colorformat", __func__);
966 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
967 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
971 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
972 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
976 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
977 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
981 info->format.type = info->buf.buf_type;
982 info->format.fmt.pix_mp.width = info->width;
983 info->format.fmt.pix_mp.height = info->height;
984 info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
985 info->format.fmt.pix_mp.field = V4L2_FIELD_ANY;
986 info->format.fmt.pix_mp.num_planes = plane_count;
988 if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
989 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
993 info->crop.type = info->buf.buf_type;
994 info->crop.c.left = info->crop_left;
995 info->crop.c.top = info->crop_top;
996 info->crop.c.width = info->crop_width;
997 info->crop.c.height = info->crop_height;
999 if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
1000 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
1004 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
1005 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
1010 req_buf.type = info->buf.buf_type;
1011 req_buf.memory = info->buf.mem_type;
1012 if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
1013 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
1022 unsigned int CGscaler::m_gsc_get_plane_count(int v4l_pixel_format)
1024 int plane_count = 0;
1026 switch (v4l_pixel_format) {
1027 case V4L2_PIX_FMT_RGB32:
1028 case V4L2_PIX_FMT_BGR32:
1029 case V4L2_PIX_FMT_RGB24:
1030 case V4L2_PIX_FMT_RGB565:
1031 case V4L2_PIX_FMT_RGB555X:
1032 case V4L2_PIX_FMT_RGB444:
1033 case V4L2_PIX_FMT_YUYV:
1034 case V4L2_PIX_FMT_UYVY:
1035 case V4L2_PIX_FMT_NV16:
1036 case V4L2_PIX_FMT_NV61:
1037 case V4L2_PIX_FMT_YVU420:
1038 case V4L2_PIX_FMT_YUV420:
1039 case V4L2_PIX_FMT_NV12:
1040 case V4L2_PIX_FMT_NV21:
1041 case V4L2_PIX_FMT_YUV422P:
1044 case V4L2_PIX_FMT_NV12M:
1045 case V4L2_PIX_FMT_NV12MT_16X16:
1046 case V4L2_PIX_FMT_NV21M:
1049 case V4L2_PIX_FMT_YVU420M:
1050 case V4L2_PIX_FMT_YUV420M:
1054 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1055 __func__, v4l_pixel_format);
1063 bool CGscaler::m_gsc_set_addr(int fd, GscInfo *info)
1066 unsigned int plane_size[NUM_OF_GSC_PLANES];
1068 CGscaler::m_gsc_get_plane_size(plane_size, info->width,
1069 info->height, info->v4l2_colorformat);
1071 info->buf.buffer.index = 0;
1072 info->buf.buffer.flags = V4L2_BUF_FLAG_USE_SYNC;
1073 info->buf.buffer.type = info->buf.buf_type;
1074 info->buf.buffer.memory = info->buf.mem_type;
1075 info->buf.buffer.m.planes = info->buf.planes;
1076 info->buf.buffer.length = info->format.fmt.pix_mp.num_planes;
1077 info->buf.buffer.reserved = info->acquireFenceFd;
1079 for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
1080 if (info->buf.buffer.memory == V4L2_MEMORY_DMABUF)
1081 info->buf.buffer.m.planes[i].m.fd = (long)info->buf.addr[i];
1083 info->buf.buffer.m.planes[i].m.userptr =
1084 (unsigned long)info->buf.addr[i];
1085 info->buf.buffer.m.planes[i].length = plane_size[i];
1086 info->buf.buffer.m.planes[i].bytesused = 0;
1089 if (exynos_v4l2_qbuf(fd, &info->buf.buffer) < 0) {
1090 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
1093 info->buf.buffer_queued = true;
1095 info->releaseFenceFd = info->buf.buffer.reserved;
1100 unsigned int CGscaler::m_gsc_get_plane_size(
1101 unsigned int *plane_size,
1103 unsigned int height,
1104 int v4l_pixel_format)
1106 switch (v4l_pixel_format) {
1108 case V4L2_PIX_FMT_RGB32:
1109 case V4L2_PIX_FMT_BGR32:
1110 plane_size[0] = width * height * 4;
1114 case V4L2_PIX_FMT_RGB24:
1115 plane_size[0] = width * height * 3;
1119 case V4L2_PIX_FMT_RGB565:
1120 case V4L2_PIX_FMT_RGB555X:
1121 case V4L2_PIX_FMT_RGB444:
1122 case V4L2_PIX_FMT_YUYV:
1123 case V4L2_PIX_FMT_UYVY:
1124 plane_size[0] = width * height * 2;
1129 case V4L2_PIX_FMT_NV12M:
1130 case V4L2_PIX_FMT_NV21M:
1131 plane_size[0] = width * height;
1132 plane_size[1] = width * (height / 2);
1135 case V4L2_PIX_FMT_NV12:
1136 case V4L2_PIX_FMT_NV21:
1137 plane_size[0] = width * height * 3 / 2;
1141 case V4L2_PIX_FMT_NV16:
1142 case V4L2_PIX_FMT_NV61:
1143 case V4L2_PIX_FMT_YUV422P:
1144 plane_size[0] = width * height * 2;
1148 case V4L2_PIX_FMT_NV12MT_16X16:
1149 plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
1150 plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
1154 case V4L2_PIX_FMT_YUV420M:
1155 plane_size[0] = width * height;
1156 plane_size[1] = (width / 2) * (height / 2);
1157 plane_size[2] = (width / 2) * (height / 2);
1159 case V4L2_PIX_FMT_YVU420:
1160 plane_size[0] = ALIGN(width, 16) * height + ALIGN(width / 2, 16) * height;
1164 case V4L2_PIX_FMT_YUV420:
1165 plane_size[0] = width * height * 3 / 2;
1169 case V4L2_PIX_FMT_YVU420M:
1170 plane_size[0] = ALIGN(width, 16) * height;
1171 plane_size[1] = ALIGN(width / 2, 16) * (height / 2);
1172 plane_size[2] = plane_size[1];
1175 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1176 __func__, v4l_pixel_format);
1183 int CGscaler::m_gsc_m2m_config(void *handle,
1184 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1188 int32_t src_color_space;
1189 int32_t dst_color_space;
1191 unsigned int rotate;
1194 CGscaler* gsc = GetGscaler(handle);
1196 ALOGE("%s::handle == NULL() fail", __func__);
1200 if ((src_img->drmMode && !gsc->allow_drm) ||
1201 (src_img->drmMode != dst_img->drmMode)) {
1202 ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)",
1203 __func__, gsc->gsc_id, src_img->drmMode, dst_img->drmMode);
1207 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1208 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1209 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1210 exynos_gsc_set_rotation(gsc, rotate, hflip, vflip);
1212 ret = exynos_gsc_set_src_format(gsc, src_img->fw, src_img->fh,
1213 src_img->x, src_img->y, src_img->w, src_img->h,
1214 src_color_space, src_img->cacheable, src_img->drmMode);
1216 ALOGE("%s: fail: exynos_gsc_set_src_format \
1217 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1218 __func__, src_img->fw, src_img->fh, src_img->x, src_img->y,
1219 src_img->w, src_img->h, src_color_space, src_img->rot);
1223 ret = exynos_gsc_set_dst_format(gsc, dst_img->fw, dst_img->fh,
1224 dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1225 dst_color_space, dst_img->cacheable, dst_img->drmMode);
1227 ALOGE("%s: fail: exynos_gsc_set_dst_format \
1228 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1229 __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y,
1230 dst_img->w, dst_img->h, src_color_space, dst_img->rot);
1239 int CGscaler::m_gsc_out_config(void *handle,
1240 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1244 struct v4l2_format fmt;
1245 struct v4l2_crop crop;
1246 struct v4l2_requestbuffers reqbuf;
1247 struct v4l2_subdev_format sd_fmt;
1248 struct v4l2_subdev_crop sd_crop;
1249 unsigned int rotate;
1254 int32_t src_color_space;
1255 int32_t dst_color_space;
1258 CGscaler* gsc = GetGscaler(handle);
1260 ALOGE("%s::handle == NULL() fail", __func__);
1264 if (gsc->src_info.stream_on != false) {
1265 ALOGE("Error: Src is already streamed on !!!!");
1269 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1270 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1271 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1272 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1273 src_planes = m_gsc_get_plane_count(src_color_space);
1274 src_planes = (src_planes == -1) ? 1 : src_planes;
1275 rgb = get_yuv_planes(dst_color_space) == -1;
1276 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1278 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1279 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1280 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1281 (rotate == 90 || rotate == 270)) == false) {
1282 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1286 /*set: src v4l2_buffer*/
1287 gsc->src_info.buf.buf_idx = 0;
1288 gsc->src_info.qbuf_cnt = 0;
1289 /* set format: src pad of GSC sub-dev*/
1290 sd_fmt.pad = GSCALER_SUBDEV_PAD_SOURCE;
1291 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1292 if (gsc->out_mode == GSC_OUT_FIMD) {
1293 sd_fmt.format.width = gsc->dst_img.fw;
1294 sd_fmt.format.height = gsc->dst_img.fh;
1296 sd_fmt.format.width = gsc->dst_img.w;
1297 sd_fmt.format.height = gsc->dst_img.h;
1299 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_RGB666_1X18 :
1300 V4L2_MBUS_FMT_YDYUYDYV8_1X16;
1301 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1302 ALOGE("%s::GSC subdev set format failed", __func__);
1306 /* set crop: src crop of GSC sub-dev*/
1307 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE;
1308 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1309 if (gsc->out_mode == GSC_OUT_FIMD) {
1310 sd_crop.rect.left = gsc->dst_img.x;
1311 sd_crop.rect.top = gsc->dst_img.y;
1312 sd_crop.rect.width = gsc->dst_img.w;
1313 sd_crop.rect.height = gsc->dst_img.h;
1315 sd_crop.rect.left = 0;
1316 sd_crop.rect.top = 0;
1317 sd_crop.rect.width = gsc->dst_img.w;
1318 sd_crop.rect.height = gsc->dst_img.h;
1321 /* sink pad is connected to GSC out */
1322 /* set format: sink sub-dev */
1323 if (gsc->out_mode == GSC_OUT_FIMD) {
1324 sd_fmt.pad = FIMD_SUBDEV_PAD_SINK;
1325 sd_fmt.format.width = gsc->dst_img.w;
1326 sd_fmt.format.height = gsc->dst_img.h;
1328 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SINK;
1329 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1330 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1333 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1334 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_RGB666_1X18 :
1335 V4L2_MBUS_FMT_YDYUYDYV8_1X16;
1336 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1337 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1342 /* set crop: sink sub-dev */
1343 if (gsc->out_mode == GSC_OUT_FIMD)
1344 sd_crop.pad = FIMD_SUBDEV_PAD_SINK;
1346 sd_crop.pad = MIXER_V_SUBDEV_PAD_SINK;
1348 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1349 if (gsc->out_mode == GSC_OUT_FIMD) {
1350 sd_crop.rect.left = gsc->dst_img.x;
1351 sd_crop.rect.top = gsc->dst_img.y;
1352 sd_crop.rect.width = gsc->dst_img.w;
1353 sd_crop.rect.height = gsc->dst_img.h;
1355 sd_crop.rect.left = 0;
1356 sd_crop.rect.top = 0;
1357 sd_crop.rect.width = gsc->dst_img.w;
1358 sd_crop.rect.height = gsc->dst_img.h;
1361 if (gsc->out_mode != GSC_OUT_FIMD) {
1362 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1363 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1364 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1365 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1366 sd_fmt.format.code = V4L2_MBUS_FMT_RGB666_1X18;
1367 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1368 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1373 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1374 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1375 sd_crop.rect.left = gsc->dst_img.x;
1376 sd_crop.rect.top = gsc->dst_img.y;
1377 sd_crop.rect.width = gsc->dst_img.w;
1378 sd_crop.rect.height = gsc->dst_img.h;
1379 if (exynos_subdev_s_crop(gsc->mdev.sink_sd_entity->fd, &sd_crop) < 0) {
1380 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__,
1387 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1389 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1394 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1396 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1401 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1403 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1408 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1409 V4L2_CID_CACHEABLE, 1) < 0) {
1410 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1415 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1416 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1417 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1422 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1423 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
1424 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
1428 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1429 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
1430 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
1434 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1435 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
1436 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
1440 /* set src format :GSC video dev*/
1441 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1442 fmt.fmt.pix_mp.width = gsc->src_img.fw;
1443 fmt.fmt.pix_mp.height = gsc->src_img.fh;
1444 fmt.fmt.pix_mp.pixelformat = src_color_space;
1445 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1446 fmt.fmt.pix_mp.num_planes = src_planes;
1448 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1449 ALOGE("%s::videodev set format failed", __func__);
1453 /* set src crop info :GSC video dev*/
1454 crop.type = fmt.type;
1455 crop.c.left = gsc->src_img.x;
1456 crop.c.top = gsc->src_img.y;
1457 crop.c.width = gsc->src_img.w;
1458 crop.c.height = gsc->src_img.h;
1460 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1461 ALOGE("%s::videodev set crop failed", __func__);
1465 reqbuf.type = fmt.type;
1466 reqbuf.memory = V4L2_MEMORY_DMABUF;
1467 reqbuf.count = MAX_BUFFERS_GSCALER_OUT;
1469 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1470 ALOGE("%s::request buffers failed", __func__);
1479 int CGscaler::m_gsc_cap_config(void *handle,
1480 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1484 struct v4l2_format fmt;
1485 struct v4l2_crop crop;
1486 struct v4l2_requestbuffers reqbuf;
1487 struct v4l2_subdev_format sd_fmt;
1488 struct v4l2_subdev_crop sd_crop;
1489 unsigned int rotate;
1493 int32_t src_color_space;
1494 int32_t dst_color_space;
1497 CGscaler* gsc = GetGscaler(handle);
1499 ALOGE("%s::handle == NULL() fail", __func__);
1503 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1504 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1505 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1506 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1507 dst_planes = m_gsc_get_plane_count(dst_color_space);
1508 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1509 CGscaler::rotateValueHAL2GSC(src_img->rot, &rotate, &hflip, &vflip);
1511 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1512 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1513 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1514 (rotate == 90 || rotate == 270)) == false) {
1515 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1520 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1522 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1526 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1528 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1532 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1534 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1538 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1539 V4L2_CID_CACHEABLE, 1) < 0) {
1540 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1544 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1545 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1546 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1550 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1551 V4L2_CID_CSC_RANGE, gsc->range_full)) {
1552 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail",
1553 __func__, gsc->range_full);
1556 /* set format: source pad of Decon-TV sub-dev*/
1557 sd_fmt.pad = DECON_TV_WB_PAD;
1558 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1559 sd_fmt.format.width = gsc->src_img.w;
1560 sd_fmt.format.height = gsc->src_img.h;
1561 sd_fmt.format.code = WB_PATH_FORMAT;
1562 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1563 ALOGE("%s::Decon-TV subdev set format failed", __func__);
1567 if (!gsc->dst_info.stream_on) {
1568 /* set src format: GSC video dev*/
1569 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1570 fmt.fmt.pix_mp.width = gsc->dst_img.fw;
1571 fmt.fmt.pix_mp.height = gsc->dst_img.fh;
1572 fmt.fmt.pix_mp.pixelformat = dst_color_space;
1573 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1574 fmt.fmt.pix_mp.num_planes = dst_planes;
1576 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1577 ALOGE("%s::videodev set format failed", __func__);
1580 gsc->dst_info.buf.buf_idx = 0;
1581 gsc->dst_info.qbuf_cnt = 0;
1584 /* set format: sink pad of GSC sub-dev*/
1585 sd_fmt.pad = GSCALER_SUBDEV_PAD_SINK;
1586 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1587 sd_fmt.format.width = gsc->src_img.w;
1588 sd_fmt.format.height = gsc->src_img.h;
1589 sd_fmt.format.code = WB_PATH_FORMAT;
1590 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1591 ALOGE("%s::GSC subdev set format failed", __func__);
1595 /* set src crop info :GSC video dev*/
1596 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1597 crop.c.left = gsc->dst_img.x;
1598 crop.c.top = gsc->dst_img.y;
1599 crop.c.width = gsc->dst_img.w;
1600 crop.c.height = gsc->dst_img.h;
1601 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1602 ALOGE("%s::videodev set crop failed", __func__);
1606 /* set crop: src crop of GSC sub-dev*/
1607 sd_crop.pad = GSCALER_SUBDEV_PAD_SINK;
1608 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1609 sd_crop.rect.left = 0;
1610 sd_crop.rect.top = 0;
1611 sd_crop.rect.width = gsc->src_img.w;
1612 sd_crop.rect.height = gsc->src_img.h;
1614 if (exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop) < 0) {
1615 ALOGE("%s::GSC subdev set crop failed(PAD=%d)", __func__,
1619 reqbuf.type = fmt.type;
1620 reqbuf.memory = V4L2_MEMORY_DMABUF;
1621 reqbuf.count = MAX_BUFFERS_GSCALER_CAP;
1623 if (!gsc->dst_info.stream_on) {
1624 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1625 ALOGE("%s::request buffers failed", __func__);
1636 void CGscaler::rotateValueHAL2GSC(unsigned int transform,
1637 unsigned int *rotate, unsigned int *hflip, unsigned int *vflip)
1639 int rotate_flag = transform & 0x7;
1644 switch (rotate_flag) {
1645 case HAL_TRANSFORM_ROT_90:
1648 case HAL_TRANSFORM_ROT_180:
1651 case HAL_TRANSFORM_ROT_270:
1654 case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
1656 *vflip = 1; /* set vflip to compensate the rot & flip order. */
1658 case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
1660 *hflip = 1; /* set hflip to compensate the rot & flip order. */
1662 case HAL_TRANSFORM_FLIP_H:
1665 case HAL_TRANSFORM_FLIP_V:
1673 int CGscaler::m_gsc_m2m_run(void *handle,
1674 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1678 CGscaler* gsc = GetGscaler(handle);
1680 ALOGE("%s::handle == NULL() fail", __func__);
1683 void *addr[3] = {NULL, NULL, NULL};
1686 addr[0] = (void *)src_img->yaddr;
1687 addr[1] = (void *)src_img->uaddr;
1688 addr[2] = (void *)src_img->vaddr;
1689 ret = exynos_gsc_set_src_addr(handle, addr, src_img->mem_type,
1690 src_img->acquireFenceFd);
1692 ALOGE("%s::fail: exynos_gsc_set_src_addr[%p %p %p]", __func__,
1693 addr[0], addr[1], addr[2]);
1697 addr[0] = (void *)dst_img->yaddr;
1698 addr[1] = (void *)dst_img->uaddr;
1699 addr[2] = (void *)dst_img->vaddr;
1700 ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->mem_type,
1701 dst_img->acquireFenceFd);
1703 ALOGE("%s::fail: exynos_gsc_set_dst_addr[%p %p %p]", __func__,
1704 addr[0], addr[1], addr[2]);
1708 ret = gsc->m_gsc_m2m_run_core(handle);
1710 ALOGE("%s::fail: m_gsc_m2m_run_core", __func__);
1714 if (src_img->acquireFenceFd >= 0) {
1715 close(src_img->acquireFenceFd);
1716 src_img->acquireFenceFd = -1;
1719 if (dst_img->acquireFenceFd >= 0) {
1720 close(dst_img->acquireFenceFd);
1721 dst_img->acquireFenceFd = -1;
1724 src_img->releaseFenceFd = gsc->src_info.releaseFenceFd;
1725 dst_img->releaseFenceFd = gsc->dst_info.releaseFenceFd;
1732 int CGscaler::m_gsc_out_run(void *handle, exynos_mpp_img *src_img)
1734 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1735 struct v4l2_buffer buf;
1736 int32_t src_color_space;
1739 unsigned int plane_size[NUM_OF_GSC_PLANES];
1741 unsigned int dq_retry_cnt = 0;
1743 CGscaler* gsc = GetGscaler(handle);
1745 ALOGE("%s::handle == NULL() fail", __func__);
1749 /* All buffers have been queued, dequeue one */
1750 if (gsc->src_info.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) {
1751 memset(&buf, 0, sizeof(struct v4l2_buffer));
1752 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1753 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1755 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1756 buf.memory = V4L2_MEMORY_DMABUF;
1757 buf.m.planes = planes;
1759 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1760 src_planes = m_gsc_get_plane_count(src_color_space);
1761 src_planes = (src_planes == -1) ? 1 : src_planes;
1762 buf.length = src_planes;
1766 ret = exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf);
1767 if (ret == -EAGAIN) {
1768 ALOGE("%s::Retry DQbuf(index=%d)", __func__, buf.index);
1774 } while (dq_retry_cnt <= 10);
1777 ALOGE("%s::dq buffer failed (index=%d)", __func__, buf.index);
1780 gsc->src_info.qbuf_cnt--;
1783 memset(&buf, 0, sizeof(struct v4l2_buffer));
1784 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1785 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1787 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1788 src_planes = m_gsc_get_plane_count(src_color_space);
1789 src_planes = (src_planes == -1) ? 1 : src_planes;
1791 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1792 buf.memory = V4L2_MEMORY_DMABUF;
1794 buf.length = src_planes;
1795 buf.index = gsc->src_info.buf.buf_idx;
1796 buf.m.planes = planes;
1799 gsc->src_info.buf.addr[0] = (void*)src_img->yaddr;
1800 gsc->src_info.buf.addr[1] = (void*)src_img->uaddr;
1801 gsc->src_info.buf.addr[2] = (void*)src_img->vaddr;
1803 if (CGscaler::tmp_get_plane_size(src_color_space, plane_size,
1804 gsc->src_img.fw, gsc->src_img.fh, src_planes) != true) {
1805 ALOGE("%s:get_plane_size:fail", __func__);
1809 for (i = 0; i < buf.length; i++) {
1810 buf.m.planes[i].m.fd = (long)gsc->src_info.buf.addr[i];
1811 buf.m.planes[i].length = plane_size[i];
1812 buf.m.planes[i].bytesused = plane_size[i];
1816 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1817 ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)",
1818 __func__, gsc->src_info.buf.buf_idx,
1819 MAX_BUFFERS_GSCALER_OUT);
1822 gsc->src_info.buf.buf_idx++;
1823 gsc->src_info.buf.buf_idx =
1824 gsc->src_info.buf.buf_idx % MAX_BUFFERS_GSCALER_OUT;
1825 gsc->src_info.qbuf_cnt++;
1827 if (gsc->src_info.stream_on == false) {
1828 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1829 (v4l2_buf_type)buf.type) < 0) {
1830 ALOGE("%s::stream on failed", __func__);
1833 gsc->src_info.stream_on = true;
1839 int CGscaler::m_gsc_cap_run(void *handle, exynos_mpp_img *dst_img)
1841 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1842 struct v4l2_buffer buf;
1843 int32_t dst_color_space;
1846 unsigned int plane_size[NUM_OF_GSC_PLANES];
1847 CGscaler* gsc = GetGscaler(handle);
1849 ALOGE("%s::handle == NULL() fail", __func__);
1853 /* All buffers have been queued, dequeue one */
1854 if (gsc->dst_info.qbuf_cnt == MAX_BUFFERS_GSCALER_CAP) {
1855 memset(&buf, 0, sizeof(struct v4l2_buffer));
1856 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1857 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1859 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1860 buf.memory = V4L2_MEMORY_DMABUF;
1861 buf.m.planes = planes;
1863 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1864 dst_planes = m_gsc_get_plane_count(dst_color_space);
1865 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1866 buf.length = dst_planes;
1869 if (exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1870 ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)",
1871 __func__, gsc->src_info.buf.buf_idx,
1872 MAX_BUFFERS_GSCALER_CAP);
1875 gsc->dst_info.qbuf_cnt--;
1878 memset(&buf, 0, sizeof(struct v4l2_buffer));
1879 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1880 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1882 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1883 dst_planes = m_gsc_get_plane_count(dst_color_space);
1884 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1886 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1887 buf.memory = V4L2_MEMORY_DMABUF;
1888 buf.flags = V4L2_BUF_FLAG_USE_SYNC;
1889 buf.length = dst_planes;
1890 buf.index = gsc->dst_info.buf.buf_idx;
1891 buf.m.planes = planes;
1892 buf.reserved = dst_img->acquireFenceFd;
1894 gsc->dst_info.buf.addr[0] = (void*)dst_img->yaddr;
1895 gsc->dst_info.buf.addr[1] = (void*)dst_img->uaddr;
1896 gsc->dst_info.buf.addr[2] = (void*)dst_img->vaddr;
1898 if (CGscaler::tmp_get_plane_size(dst_color_space, plane_size,
1899 gsc->dst_img.fw, gsc->dst_img.fh, dst_planes) != true) {
1900 ALOGE("%s:get_plane_size:fail", __func__);
1904 for (i = 0; i < buf.length; i++) {
1905 buf.m.planes[i].m.fd = (int)(long)gsc->dst_info.buf.addr[i];
1906 buf.m.planes[i].length = plane_size[i];
1907 buf.m.planes[i].bytesused = plane_size[i];
1911 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1912 ALOGE("%s::queue buffer failed (index=%d)(mDstBufNum=%d)",
1913 __func__, gsc->dst_info.buf.buf_idx,
1914 MAX_BUFFERS_GSCALER_CAP);
1918 gsc->dst_info.buf.buf_idx++;
1919 gsc->dst_info.buf.buf_idx =
1920 gsc->dst_info.buf.buf_idx % MAX_BUFFERS_GSCALER_CAP;
1921 gsc->dst_info.qbuf_cnt++;
1923 if (gsc->dst_info.stream_on == false) {
1924 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1925 (v4l2_buf_type)buf.type) < 0) {
1926 ALOGE("%s::stream on failed", __func__);
1929 gsc->dst_info.stream_on = true;
1932 dst_img->releaseFenceFd = buf.reserved;
1936 bool CGscaler::tmp_get_plane_size(int V4L2_PIX,
1937 unsigned int * size, unsigned int width, unsigned int height, int src_planes)
1939 unsigned int frame_ratio = 1;
1940 int src_bpp = get_yuv_bpp(V4L2_PIX);
1941 unsigned int frame_size = width * height;
1943 src_planes = (src_planes == -1) ? 1 : src_planes;
1944 frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
1946 switch (src_planes) {
1949 case V4L2_PIX_FMT_BGR32:
1950 case V4L2_PIX_FMT_RGB32:
1951 size[0] = frame_size << 2;
1953 case V4L2_PIX_FMT_RGB565:
1954 case V4L2_PIX_FMT_NV16:
1955 case V4L2_PIX_FMT_NV61:
1956 case V4L2_PIX_FMT_YUYV:
1957 case V4L2_PIX_FMT_UYVY:
1958 case V4L2_PIX_FMT_VYUY:
1959 case V4L2_PIX_FMT_YVYU:
1960 size[0] = frame_size << 1;
1962 case V4L2_PIX_FMT_YUV420:
1963 case V4L2_PIX_FMT_NV12:
1964 case V4L2_PIX_FMT_NV21:
1965 case V4L2_PIX_FMT_NV21M:
1966 size[0] = (frame_size * 3) >> 1;
1968 case V4L2_PIX_FMT_YVU420:
1969 size[0] = frame_size + (ALIGN((width >> 1), 16) * ((height >> 1) * 2));
1972 ALOGE("%s::invalid color type (%x)", __func__, V4L2_PIX);
1980 size[0] = frame_size;
1981 size[1] = frame_size / frame_ratio;
1985 size[0] = frame_size;
1986 size[1] = frame_size / frame_ratio;
1987 size[2] = frame_size / frame_ratio;
1990 ALOGE("%s::invalid color foarmt", __func__);
1998 int CGscaler::ConfigMpp(void *handle, exynos_mpp_img *src,
1999 exynos_mpp_img *dst)
2001 return exynos_gsc_config_exclusive(handle, src, dst);
2004 int CGscaler::ConfigBlendMpp(void *handle, exynos_mpp_img *src,
2005 exynos_mpp_img *dst,
2006 SrcBlendInfo *srcblendinfo)
2008 return exynos_gsc_config_blend_exclusive(handle, src, dst, srcblendinfo);
2011 int CGscaler::RunMpp(void *handle, exynos_mpp_img *src,
2012 exynos_mpp_img *dst)
2014 return exynos_gsc_run_exclusive(handle, src, dst);
2017 int CGscaler::StopMpp(void *handle)
2019 return exynos_gsc_stop_exclusive(handle);
2022 void CGscaler::DestroyMpp(void *handle)
2024 return exynos_gsc_destroy(handle);
2027 int CGscaler::SetCSCProperty(void *handle, unsigned int eqAuto,
2028 unsigned int fullRange, unsigned int colorspace)
2030 return exynos_gsc_set_csc_property(handle, eqAuto, fullRange,
2034 int CGscaler::FreeMpp(void *handle)
2036 return exynos_gsc_free_and_close(handle);
2039 int CGscaler::SetInputCrop(void *handle,
2040 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
2042 struct v4l2_crop crop;
2043 CGscaler *gsc = GetGscaler(handle);
2045 ALOGE("%s::handle == NULL() fail", __func__);
2049 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2050 crop.c.left = src_img->x;
2051 crop.c.top = src_img->y;
2052 crop.c.width = src_img->w;
2053 crop.c.height = src_img->h;
2055 return exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop);