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;
47 CGscaler* gsc = GetGscaler(handle);
49 ALOGE("%s::handle == NULL() fail", __func__);
53 if ((out_mode != GSC_OUT_FIMD) &&
54 (out_mode != GSC_OUT_TV))
57 gsc->out_mode = out_mode;
58 /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
59 if ((out_mode == GSC_OUT_FIMD) &&
60 #ifndef USES_ONLY_GSC0_GSC1
68 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 0);
69 media0 = exynos_media_open(node);
71 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
74 gsc->mdev.media0 = media0;
76 /* Get the sink subdev entity by name and make the node of sink subdev*/
77 if (out_mode == GSC_OUT_FIMD)
78 snprintf(devname, sizeof(devname), PFX_FIMD_ENTITY, dev_num);
80 snprintf(devname, sizeof(devname), PFX_MXR_ENTITY, 0);
82 sink_sd_entity = exynos_media_get_entity_by_name(media0, devname,
84 if (!sink_sd_entity) {
85 ALOGE("%s:: failed to get the sink sd entity", __func__);
88 gsc->mdev.sink_sd_entity = sink_sd_entity;
90 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
91 if (sink_sd_entity->fd < 0) {
92 ALOGE("%s:: failed to open sink subdev node", __func__);
96 /* get GSC video dev & sub dev entity by name*/
100 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
103 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
106 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
110 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
112 gsc_vd_entity = exynos_media_get_entity_by_name(media0, devname,
114 if (!gsc_vd_entity) {
115 ALOGE("%s:: failed to get the gsc vd entity", __func__);
118 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
120 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
121 gsc_sd_entity = exynos_media_get_entity_by_name(media0, devname,
123 if (!gsc_sd_entity) {
124 ALOGE("%s:: failed to get the gsc sd entity", __func__);
127 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
129 /* gsc sub-dev open */
130 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
131 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
132 if (gsc_sd_entity->fd < 0) {
133 ALOGE("%s: gsc sub-dev open fail", __func__);
137 /* gsc video-dev open */
141 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
144 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
147 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
151 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
153 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR | O_NONBLOCK);
154 if (gsc_vd_entity->fd < 0) {
155 ALOGE("%s: gsc video-dev open fail", __func__);
159 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
161 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
162 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
171 gsc->m_gsc_out_destroy(handle);
176 int CGscaler::m_gsc_capture_create(void *handle, int dev_num, int out_mode)
180 struct media_device *media1;
181 struct media_entity *gsc_sd_entity;
182 struct media_entity *gsc_vd_entity;
183 struct media_entity *sink_sd_entity;
184 struct media_link *links;
190 CGscaler* gsc = GetGscaler(handle);
192 ALOGE("%s::handle == NULL() fail", __func__);
196 gsc->out_mode = out_mode;
202 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 1);
203 media1 = exynos_media_open(node);
204 if (media1 == NULL) {
205 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
208 gsc->mdev.media1 = media1;
210 /* DECON-TV sub-device Open */
211 snprintf(devname, sizeof(devname), DEX_WB_SD_NAME);
213 sink_sd_entity = exynos_media_get_entity_by_name(media1, devname,
215 if (!sink_sd_entity) {
216 ALOGE("%s:: failed to get the sink sd entity", __func__);
219 gsc->mdev.sink_sd_entity = sink_sd_entity;
221 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
222 if (sink_sd_entity->fd < 0) {
223 ALOGE("%s:: failed to open sink subdev node", __func__);
227 /* Gscaler2 capture video-device Open */
228 snprintf(devname, sizeof(devname), PFX_GSC_CAPTURE_ENTITY);
229 gsc_vd_entity = exynos_media_get_entity_by_name(media1, devname,
231 if (!gsc_vd_entity) {
232 ALOGE("%s:: failed to get the gsc vd entity", __func__);
235 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
237 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
238 if (gsc_vd_entity->fd < 0) {
239 ALOGE("%s: gsc video-dev open fail", __func__);
243 /* Gscaler2 capture sub-device Open */
244 snprintf(devname, sizeof(devname), GSC_WB_SD_NAME);
245 gsc_sd_entity = exynos_media_get_entity_by_name(media1, devname,
247 if (!gsc_sd_entity) {
248 ALOGE("%s:: failed to get the gsc sd entity", __func__);
251 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
253 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
254 if (gsc_sd_entity->fd < 0) {
255 ALOGE("%s: gsc sub-dev open fail", __func__);
259 if (exynos_media_setup_link(media1, sink_sd_entity->pads,
260 gsc_sd_entity->pads, MEDIA_LNK_FL_ENABLED) < 0) {
261 ALOGE("%s::exynos_media_setup_link failed", __func__);
265 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
267 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
268 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
277 gsc->m_gsc_cap_destroy(handle);
282 int CGscaler::m_gsc_out_stop(void *handle)
286 struct v4l2_requestbuffers reqbuf;
287 CGscaler* gsc = GetGscaler(handle);
289 ALOGE("%s::handle == NULL() fail", __func__);
293 if (gsc->src_info.stream_on == false) {
294 /* to handle special scenario.*/
295 gsc->src_info.qbuf_cnt = 0;
296 ALOGD("%s::GSC is already stopped", __func__);
299 gsc->src_info.qbuf_cnt = 0;
300 gsc->src_info.stream_on = false;
302 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
303 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
304 ALOGE("%s::stream off failed", __func__);
314 int CGscaler::m_gsc_cap_stop(void *handle)
318 CGscaler* gsc = GetGscaler(handle);
320 ALOGE("%s::handle == NULL() fail", __func__);
324 if (gsc->dst_info.stream_on == false) {
325 /* to handle special scenario.*/
326 gsc->dst_info.qbuf_cnt = 0;
327 ALOGD("%s::GSC is already stopped", __func__);
330 gsc->dst_info.qbuf_cnt = 0;
331 gsc->dst_info.stream_on = false;
333 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
334 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
335 ALOGE("%s::stream off failed", __func__);
345 bool CGscaler::m_gsc_out_destroy(void *handle)
350 CGscaler* gsc = GetGscaler(handle);
352 ALOGE("%s::handle == NULL() fail", __func__);
356 if (gsc->src_info.stream_on == true) {
357 if (gsc->m_gsc_out_stop(gsc) < 0)
358 ALOGE("%s::m_gsc_out_stop() fail", __func__);
360 gsc->src_info.stream_on = false;
363 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
364 close(gsc->mdev.gsc_vd_entity->fd);
365 gsc->mdev.gsc_vd_entity->fd = -1;
368 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
369 close(gsc->mdev.gsc_sd_entity->fd);
370 gsc->mdev.gsc_sd_entity->fd = -1;
373 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
374 close(gsc->mdev.sink_sd_entity->fd);
375 gsc->mdev.sink_sd_entity->fd = -1;
378 if (gsc->mdev.media0)
379 exynos_media_close(gsc->mdev.media0);
381 gsc->mdev.media0 = NULL;
382 gsc->mdev.gsc_sd_entity = NULL;
383 gsc->mdev.gsc_vd_entity = NULL;
384 gsc->mdev.sink_sd_entity = NULL;
390 bool CGscaler::m_gsc_cap_destroy(void *handle)
394 CGscaler* gsc = GetGscaler(handle);
396 ALOGE("%s::handle == NULL() fail", __func__);
400 if (gsc->dst_info.stream_on == true) {
401 if (gsc->m_gsc_cap_stop(gsc) < 0)
402 ALOGE("%s::m_gsc_cap_stop() fail", __func__);
404 gsc->dst_info.stream_on = false;
407 if (!gsc->mdev.media1 || !gsc->mdev.gsc_sd_entity ||
408 !gsc->mdev.gsc_vd_entity || !gsc->mdev.sink_sd_entity) {
409 ALOGE("%s::gsc->mdev information is null", __func__);
413 if (exynos_media_setup_link(gsc->mdev.media1,
414 gsc->mdev.sink_sd_entity->pads,
415 gsc->mdev.gsc_sd_entity->pads, 0) < 0) {
416 ALOGE("%s::exynos_media_setup_unlin failed", __func__);
419 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
420 close(gsc->mdev.gsc_vd_entity->fd);
421 gsc->mdev.gsc_vd_entity->fd = -1;
424 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
425 close(gsc->mdev.gsc_sd_entity->fd);
426 gsc->mdev.gsc_sd_entity->fd = -1;
429 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
430 close(gsc->mdev.sink_sd_entity->fd);
431 gsc->mdev.sink_sd_entity->fd = -1;
434 if (gsc->mdev.media1)
435 exynos_media_close(gsc->mdev.media1);
437 gsc->mdev.media1 = NULL;
438 gsc->mdev.gsc_sd_entity = NULL;
439 gsc->mdev.gsc_vd_entity = NULL;
440 gsc->mdev.sink_sd_entity = NULL;
446 int CGscaler::m_gsc_m2m_create(int dev)
457 video_node_num = NODE_NUM_GSC_0;
460 video_node_num = NODE_NUM_GSC_1;
462 #ifndef USES_ONLY_GSC0_GSC1
464 video_node_num = NODE_NUM_GSC_2;
467 video_node_num = NODE_NUM_GSC_3;
471 ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
476 snprintf(node, sizeof(node), "%s%d", PFX_NODE_GSC, video_node_num);
477 fd = exynos_v4l2_open(node, O_RDWR);
479 ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
483 cap = V4L2_CAP_STREAMING |
484 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
485 V4L2_CAP_VIDEO_CAPTURE_MPLANE;
487 if (exynos_v4l2_querycap(fd, cap) == false) {
488 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
499 bool CGscaler::m_gsc_find_and_create(void *handle)
504 bool flag_find_new_gsc = false;
505 unsigned int total_sleep_time = 0;
506 CGscaler* gsc = GetGscaler(handle);
508 ALOGE("%s::handle == NULL() fail", __func__);
513 for (i = 0; i < NUM_OF_GSC_HW; i++) {
514 #ifndef USES_ONLY_GSC0_GSC1
515 if (i == 0 || i == 3)
522 gsc->gsc_fd = gsc->m_gsc_m2m_create(i);
523 if (gsc->gsc_fd < 0) {
528 flag_find_new_gsc = true;
532 if (flag_find_new_gsc == false) {
533 usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
534 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
535 ALOGV("%s::waiting for the gscaler availability", __func__);
538 } while(flag_find_new_gsc == false
539 && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
541 if (flag_find_new_gsc == false)
542 ALOGE("%s::we don't have any available gsc.. fail", __func__);
546 return flag_find_new_gsc;
549 bool CGscaler::m_gsc_m2m_destroy(void *handle)
553 CGscaler* gsc = GetGscaler(handle);
555 ALOGE("%s::handle == NULL() fail", __func__);
560 * just in case, we call stop here because we cannot afford to leave
561 * secure side protection on if things failed.
563 gsc->m_gsc_m2m_stop(handle);
565 if (gsc->gsc_id >= HW_SCAL0) {
566 bool ret = exynos_sc_free_and_close(gsc->scaler);
580 int CGscaler::m_gsc_m2m_stop(void *handle)
584 struct v4l2_requestbuffers req_buf;
586 CGscaler* gsc = GetGscaler(handle);
588 ALOGE("%s::handle == NULL() fail", __func__);
592 if (!gsc->src_info.stream_on && !gsc->dst_info.stream_on) {
593 /* wasn't streaming, return success */
595 } else if (gsc->src_info.stream_on != gsc->dst_info.stream_on) {
596 ALOGE("%s: invalid state, queue stream state doesn't match \
597 (%d != %d)", __func__, gsc->src_info.stream_on,
598 gsc->dst_info.stream_on);
603 * we need to plow forward on errors below to make sure that if we had
604 * turned on content protection on secure side, we turn it off.
606 * also, if we only failed to turn on one of the streams, we'll turn
607 * the other one off correctly.
609 if (gsc->src_info.stream_on == true) {
610 if (exynos_v4l2_streamoff(gsc->gsc_fd,
611 gsc->src_info.buf.buf_type) < 0) {
612 ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
615 gsc->src_info.stream_on = false;
618 if (gsc->dst_info.stream_on == true) {
619 if (exynos_v4l2_streamoff(gsc->gsc_fd,
620 gsc->dst_info.buf.buf_type) < 0) {
621 ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
624 gsc->dst_info.stream_on = false;
627 /* if drm is enabled */
628 if (gsc->allow_drm && gsc->protection_enabled) {
629 unsigned int protect_id = 0;
631 if (gsc->gsc_id == 0)
632 protect_id = CP_PROTECT_GSC0;
633 else if (gsc->gsc_id == 1)
634 protect_id = CP_PROTECT_GSC1;
635 else if (gsc->gsc_id == 2)
636 protect_id = CP_PROTECT_GSC2;
637 else if (gsc->gsc_id == 3)
638 protect_id = CP_PROTECT_GSC3;
640 /* CP_Disable_Path_Protection(protect_id); */
641 gsc->protection_enabled = false;
644 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
645 V4L2_CID_CONTENT_PROTECTION, 0) < 0) {
646 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
653 req_buf.type = gsc->src_info.buf.buf_type;
654 req_buf.memory = gsc->src_info.buf.mem_type;
655 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
656 ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
662 req_buf.type = gsc->dst_info.buf.buf_type;
663 req_buf.memory = gsc->dst_info.buf.mem_type;;
664 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
665 ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
674 int CGscaler::m_gsc_m2m_run_core(void *handle)
678 unsigned int rotate, hflip, vflip;
681 CGscaler* gsc = GetGscaler(handle);
683 ALOGE("%s::handle == NULL() fail", __func__);
687 is_dirty = gsc->src_info.dirty || gsc->dst_info.dirty;
688 is_drm = gsc->src_info.mode_drm;
690 if (is_dirty && (gsc->src_info.mode_drm != gsc->dst_info.mode_drm)) {
691 ALOGE("%s: drm mode mismatch between src and dst, \
692 gsc%d (s=%d d=%d)", __func__, gsc->gsc_id,
693 gsc->src_info.mode_drm, gsc->dst_info.mode_drm);
695 } else if (is_drm && !gsc->allow_drm) {
696 ALOGE("%s: drm mode is not supported on gsc%d", __func__,
701 CGscaler::rotateValueHAL2GSC(gsc->dst_img.rot, &rotate, &hflip, &vflip);
703 if (CGscaler::m_gsc_check_src_size(&gsc->src_info.width,
704 &gsc->src_info.height, &gsc->src_info.crop_left,
705 &gsc->src_info.crop_top, &gsc->src_info.crop_width,
706 &gsc->src_info.crop_height, gsc->src_info.v4l2_colorformat,
707 (rotate == 90 || rotate == 270)) == false) {
708 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
712 if (CGscaler::m_gsc_check_dst_size(&gsc->dst_info.width,
713 &gsc->dst_info.height, &gsc->dst_info.crop_left,
714 &gsc->dst_info.crop_top, &gsc->dst_info.crop_width,
715 &gsc->dst_info.crop_height, gsc->dst_info.v4l2_colorformat,
716 gsc->dst_info.rotation) == false) {
717 ALOGE("%s::m_gsc_check_dst_size() fail", __func__);
721 /* dequeue buffers from previous work if necessary */
722 if (gsc->src_info.stream_on == true) {
723 if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
724 ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__);
730 * need to set the content protection flag before doing reqbufs
733 if (is_dirty && gsc->allow_drm && is_drm) {
734 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
735 V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) {
736 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
742 * from this point on, we have to ensure to call stop to clean up
743 * whatever state we have set.
746 if (gsc->src_info.dirty) {
747 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->src_info) == false) {
748 ALOGE("%s::m_gsc_set_format(src) fail", __func__);
751 gsc->src_info.dirty = false;
754 if (gsc->dst_info.dirty) {
755 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->dst_info) == false) {
756 ALOGE("%s::m_gsc_set_format(dst) fail", __func__);
759 gsc->dst_info.dirty = false;
763 * set up csc equation property
766 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
767 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
768 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
772 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
773 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
774 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
778 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
779 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
780 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
785 /* if we are enabling drm, make sure to enable hw protection.
786 * Need to do this before queuing buffers so that the mmu is reserved
787 * and power domain is kept on.
789 if (is_dirty && gsc->allow_drm && is_drm) {
790 unsigned int protect_id = 0;
792 if (gsc->gsc_id == 0) {
793 protect_id = CP_PROTECT_GSC0;
794 } else if (gsc->gsc_id == 1) {
795 protect_id = CP_PROTECT_GSC1;
796 } else if (gsc->gsc_id == 2) {
797 protect_id = CP_PROTECT_GSC2;
798 } else if (gsc->gsc_id == 3) {
799 protect_id = CP_PROTECT_GSC3;
801 ALOGE("%s::invalid gscaler id %d for content protection",
802 __func__, gsc->gsc_id);
806 /* if (CP_Enable_Path_Protection(protect_id) != 0) {
807 ALOGE("%s::CP_Enable_Path_Protection failed", __func__);
810 gsc->protection_enabled = true;
813 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->src_info) == false) {
814 ALOGE("%s::m_gsc_set_addr(src) fail", __func__);
818 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->dst_info) == false) {
819 ALOGE("%s::m_gsc_set_addr(dst) fail", __func__);
823 if (gsc->src_info.stream_on == false) {
824 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->src_info.buf.buf_type) < 0) {
825 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
828 gsc->src_info.stream_on = true;
831 if (gsc->dst_info.stream_on == false) {
832 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->dst_info.buf.buf_type) < 0) {
833 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
836 gsc->dst_info.stream_on = true;
844 gsc->m_gsc_m2m_stop(handle);
848 bool CGscaler::m_gsc_check_src_size(
849 unsigned int *w, unsigned int *h,
850 unsigned int *crop_x, unsigned int *crop_y,
851 unsigned int *crop_w, unsigned int *crop_h,
852 int v4l2_colorformat, bool rotation)
854 unsigned int minWidth, minHeight, shift = 0;
855 if (v4l2_colorformat == V4L2_PIX_FMT_RGB32 || v4l2_colorformat == V4L2_PIX_FMT_RGB565)
858 minWidth = GSC_MIN_SRC_H_SIZE >> shift;
859 minHeight = GSC_MIN_SRC_W_SIZE >> shift;
861 minWidth = GSC_MIN_SRC_W_SIZE >> shift;
862 minHeight = GSC_MIN_SRC_H_SIZE >> shift;
865 if (*w < minWidth || *h < minHeight) {
866 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
867 __func__, GSC_MIN_SRC_W_SIZE, *w, GSC_MIN_SRC_H_SIZE, *h);
871 if (*crop_w < minWidth || *crop_h < minHeight) {
872 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
873 __func__, GSC_MIN_SRC_W_SIZE,* crop_w, GSC_MIN_SRC_H_SIZE, *crop_h);
880 bool CGscaler::m_gsc_check_dst_size(
881 unsigned int *w, unsigned int *h,
882 unsigned int *crop_x, unsigned int *crop_y,
883 unsigned int *crop_w, unsigned int *crop_h,
884 int v4l2_colorformat,
887 if (*w < GSC_MIN_DST_W_SIZE || *h < GSC_MIN_DST_H_SIZE) {
888 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
889 __func__, GSC_MIN_DST_W_SIZE, *w, GSC_MIN_DST_H_SIZE, *h);
893 if (*crop_w < GSC_MIN_DST_W_SIZE || *crop_h < GSC_MIN_DST_H_SIZE) {
894 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
895 __func__, GSC_MIN_DST_W_SIZE,* crop_w, GSC_MIN_DST_H_SIZE, *crop_h);
903 int CGscaler::m_gsc_multiple_of_n(int number, int N)
916 result = (number - (number & (N-1)));
919 result = number - (number % N);
925 int CGscaler::m_gsc_m2m_wait_frame_done(void *handle)
929 CGscaler* gsc = GetGscaler(handle);
931 ALOGE("%s::handle == NULL() fail", __func__);
935 if ((gsc->src_info.stream_on == false) ||
936 (gsc->dst_info.stream_on == false)) {
937 ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
941 if (gsc->src_info.buf.buffer_queued) {
942 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->src_info.buf.buffer) < 0) {
943 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
946 gsc->src_info.buf.buffer_queued = false;
949 if (gsc->dst_info.buf.buffer_queued) {
950 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->dst_info.buf.buffer) < 0) {
951 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
954 gsc->dst_info.buf.buffer_queued = false;
962 bool CGscaler::m_gsc_set_format(int fd, GscInfo *info)
966 struct v4l2_requestbuffers req_buf;
969 plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
970 if (plane_count < 0) {
971 ALOGE("%s::not supported v4l2_colorformat", __func__);
975 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
976 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
980 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
981 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
985 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
986 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
990 info->format.type = info->buf.buf_type;
991 info->format.fmt.pix_mp.width = info->width;
992 info->format.fmt.pix_mp.height = info->height;
993 info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
994 info->format.fmt.pix_mp.field = V4L2_FIELD_ANY;
995 info->format.fmt.pix_mp.num_planes = plane_count;
997 if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
998 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
1002 info->crop.type = info->buf.buf_type;
1003 info->crop.c.left = info->crop_left;
1004 info->crop.c.top = info->crop_top;
1005 info->crop.c.width = info->crop_width;
1006 info->crop.c.height = info->crop_height;
1008 if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
1009 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
1013 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
1014 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
1019 req_buf.type = info->buf.buf_type;
1020 req_buf.memory = info->buf.mem_type;
1021 if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
1022 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
1031 unsigned int CGscaler::m_gsc_get_plane_count(int v4l_pixel_format)
1033 int plane_count = 0;
1035 switch (v4l_pixel_format) {
1036 case V4L2_PIX_FMT_RGB32:
1037 case V4L2_PIX_FMT_BGR32:
1038 case V4L2_PIX_FMT_RGB24:
1039 case V4L2_PIX_FMT_RGB565:
1040 case V4L2_PIX_FMT_RGB555X:
1041 case V4L2_PIX_FMT_RGB444:
1042 case V4L2_PIX_FMT_YUYV:
1043 case V4L2_PIX_FMT_UYVY:
1044 case V4L2_PIX_FMT_NV16:
1045 case V4L2_PIX_FMT_NV61:
1046 case V4L2_PIX_FMT_YVU420:
1047 case V4L2_PIX_FMT_YUV420:
1048 case V4L2_PIX_FMT_NV12:
1049 case V4L2_PIX_FMT_NV21:
1050 case V4L2_PIX_FMT_YUV422P:
1053 case V4L2_PIX_FMT_NV12M:
1054 case V4L2_PIX_FMT_NV12MT_16X16:
1055 case V4L2_PIX_FMT_NV21M:
1058 case V4L2_PIX_FMT_YVU420M:
1059 case V4L2_PIX_FMT_YUV420M:
1063 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1064 __func__, v4l_pixel_format);
1072 bool CGscaler::m_gsc_set_addr(int fd, GscInfo *info)
1075 unsigned int plane_size[NUM_OF_GSC_PLANES];
1077 CGscaler::m_gsc_get_plane_size(plane_size, info->width,
1078 info->height, info->v4l2_colorformat);
1080 info->buf.buffer.index = 0;
1081 info->buf.buffer.flags = V4L2_BUF_FLAG_USE_SYNC;
1082 info->buf.buffer.type = info->buf.buf_type;
1083 info->buf.buffer.memory = info->buf.mem_type;
1084 info->buf.buffer.m.planes = info->buf.planes;
1085 info->buf.buffer.length = info->format.fmt.pix_mp.num_planes;
1086 info->buf.buffer.reserved = info->acquireFenceFd;
1088 for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
1089 if (info->buf.buffer.memory == V4L2_MEMORY_DMABUF)
1090 info->buf.buffer.m.planes[i].m.fd = (long)info->buf.addr[i];
1092 info->buf.buffer.m.planes[i].m.userptr =
1093 (unsigned long)info->buf.addr[i];
1094 info->buf.buffer.m.planes[i].length = plane_size[i];
1095 info->buf.buffer.m.planes[i].bytesused = 0;
1098 if (exynos_v4l2_qbuf(fd, &info->buf.buffer) < 0) {
1099 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
1102 info->buf.buffer_queued = true;
1104 info->releaseFenceFd = info->buf.buffer.reserved;
1109 unsigned int CGscaler::m_gsc_get_plane_size(
1110 unsigned int *plane_size,
1112 unsigned int height,
1113 int v4l_pixel_format)
1115 switch (v4l_pixel_format) {
1117 case V4L2_PIX_FMT_RGB32:
1118 case V4L2_PIX_FMT_BGR32:
1119 plane_size[0] = width * height * 4;
1123 case V4L2_PIX_FMT_RGB24:
1124 plane_size[0] = width * height * 3;
1128 case V4L2_PIX_FMT_RGB565:
1129 case V4L2_PIX_FMT_RGB555X:
1130 case V4L2_PIX_FMT_RGB444:
1131 case V4L2_PIX_FMT_YUYV:
1132 case V4L2_PIX_FMT_UYVY:
1133 plane_size[0] = width * height * 2;
1138 case V4L2_PIX_FMT_NV12M:
1139 case V4L2_PIX_FMT_NV21M:
1140 plane_size[0] = width * height;
1141 plane_size[1] = width * (height / 2);
1144 case V4L2_PIX_FMT_NV12:
1145 case V4L2_PIX_FMT_NV21:
1146 plane_size[0] = width * height * 3 / 2;
1150 case V4L2_PIX_FMT_NV16:
1151 case V4L2_PIX_FMT_NV61:
1152 case V4L2_PIX_FMT_YUV422P:
1153 plane_size[0] = width * height * 2;
1157 case V4L2_PIX_FMT_NV12MT_16X16:
1158 plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
1159 plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
1163 case V4L2_PIX_FMT_YUV420M:
1164 plane_size[0] = width * height;
1165 plane_size[1] = (width / 2) * (height / 2);
1166 plane_size[2] = (width / 2) * (height / 2);
1168 case V4L2_PIX_FMT_YVU420:
1169 plane_size[0] = ALIGN(width, 16) * height + ALIGN(width / 2, 16) * height;
1173 case V4L2_PIX_FMT_YUV420:
1174 plane_size[0] = width * height * 3 / 2;
1178 case V4L2_PIX_FMT_YVU420M:
1179 plane_size[0] = ALIGN(width, 16) * height;
1180 plane_size[1] = ALIGN(width / 2, 16) * (height / 2);
1181 plane_size[2] = plane_size[1];
1184 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1185 __func__, v4l_pixel_format);
1192 int CGscaler::m_gsc_m2m_config(void *handle,
1193 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1197 int32_t src_color_space;
1198 int32_t dst_color_space;
1200 unsigned int rotate;
1203 CGscaler* gsc = GetGscaler(handle);
1205 ALOGE("%s::handle == NULL() fail", __func__);
1209 if ((src_img->drmMode && !gsc->allow_drm) ||
1210 (src_img->drmMode != dst_img->drmMode)) {
1211 ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)",
1212 __func__, gsc->gsc_id, src_img->drmMode, dst_img->drmMode);
1216 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1217 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1218 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1219 exynos_gsc_set_rotation(gsc, rotate, hflip, vflip);
1221 ret = exynos_gsc_set_src_format(gsc, src_img->fw, src_img->fh,
1222 src_img->x, src_img->y, src_img->w, src_img->h,
1223 src_color_space, src_img->cacheable, src_img->drmMode);
1225 ALOGE("%s: fail: exynos_gsc_set_src_format \
1226 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1227 __func__, src_img->fw, src_img->fh, src_img->x, src_img->y,
1228 src_img->w, src_img->h, src_color_space, src_img->rot);
1232 ret = exynos_gsc_set_dst_format(gsc, dst_img->fw, dst_img->fh,
1233 dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1234 dst_color_space, dst_img->cacheable, dst_img->drmMode);
1236 ALOGE("%s: fail: exynos_gsc_set_dst_format \
1237 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1238 __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y,
1239 dst_img->w, dst_img->h, src_color_space, dst_img->rot);
1248 int CGscaler::m_gsc_out_config(void *handle,
1249 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1253 struct v4l2_format fmt;
1254 struct v4l2_crop crop;
1255 struct v4l2_requestbuffers reqbuf;
1256 struct v4l2_subdev_format sd_fmt;
1257 struct v4l2_subdev_crop sd_crop;
1259 unsigned int rotate;
1262 unsigned int plane_size[NUM_OF_GSC_PLANES];
1265 struct v4l2_rect dst_rect;
1266 int32_t src_color_space;
1267 int32_t dst_color_space;
1270 CGscaler* gsc = GetGscaler(handle);
1272 ALOGE("%s::handle == NULL() fail", __func__);
1276 if (gsc->src_info.stream_on != false) {
1277 ALOGE("Error: Src is already streamed on !!!!");
1281 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1282 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1283 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1284 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1285 src_planes = m_gsc_get_plane_count(src_color_space);
1286 src_planes = (src_planes == -1) ? 1 : src_planes;
1287 rgb = get_yuv_planes(dst_color_space) == -1;
1288 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1290 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1291 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1292 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1293 (rotate == 90 || rotate == 270)) == false) {
1294 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1298 /*set: src v4l2_buffer*/
1299 gsc->src_info.buf.buf_idx = 0;
1300 gsc->src_info.qbuf_cnt = 0;
1301 /* set format: src pad of GSC sub-dev*/
1302 sd_fmt.pad = GSCALER_SUBDEV_PAD_SOURCE;
1303 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1304 if (gsc->out_mode == GSC_OUT_FIMD) {
1305 sd_fmt.format.width = gsc->dst_img.fw;
1306 sd_fmt.format.height = gsc->dst_img.fh;
1308 sd_fmt.format.width = gsc->dst_img.w;
1309 sd_fmt.format.height = gsc->dst_img.h;
1311 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_RGB666_1X18 :
1312 V4L2_MBUS_FMT_YDYUYDYV8_1X16;
1313 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1314 ALOGE("%s::GSC subdev set format failed", __func__);
1318 /* set crop: src crop of GSC sub-dev*/
1319 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE;
1320 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1321 if (gsc->out_mode == GSC_OUT_FIMD) {
1322 sd_crop.rect.left = gsc->dst_img.x;
1323 sd_crop.rect.top = gsc->dst_img.y;
1324 sd_crop.rect.width = gsc->dst_img.w;
1325 sd_crop.rect.height = gsc->dst_img.h;
1327 sd_crop.rect.left = 0;
1328 sd_crop.rect.top = 0;
1329 sd_crop.rect.width = gsc->dst_img.w;
1330 sd_crop.rect.height = gsc->dst_img.h;
1333 /* sink pad is connected to GSC out */
1334 /* set format: sink sub-dev */
1335 if (gsc->out_mode == GSC_OUT_FIMD) {
1336 sd_fmt.pad = FIMD_SUBDEV_PAD_SINK;
1337 sd_fmt.format.width = gsc->dst_img.w;
1338 sd_fmt.format.height = gsc->dst_img.h;
1340 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SINK;
1341 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1342 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1345 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1346 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_RGB666_1X18 :
1347 V4L2_MBUS_FMT_YDYUYDYV8_1X16;
1348 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1349 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1354 /* set crop: sink sub-dev */
1355 if (gsc->out_mode == GSC_OUT_FIMD)
1356 sd_crop.pad = FIMD_SUBDEV_PAD_SINK;
1358 sd_crop.pad = MIXER_V_SUBDEV_PAD_SINK;
1360 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1361 if (gsc->out_mode == GSC_OUT_FIMD) {
1362 sd_crop.rect.left = gsc->dst_img.x;
1363 sd_crop.rect.top = gsc->dst_img.y;
1364 sd_crop.rect.width = gsc->dst_img.w;
1365 sd_crop.rect.height = gsc->dst_img.h;
1367 sd_crop.rect.left = 0;
1368 sd_crop.rect.top = 0;
1369 sd_crop.rect.width = gsc->dst_img.w;
1370 sd_crop.rect.height = gsc->dst_img.h;
1373 if (gsc->out_mode != GSC_OUT_FIMD) {
1374 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1375 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1376 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1377 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1378 sd_fmt.format.code = V4L2_MBUS_FMT_RGB666_1X18;
1379 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1380 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1385 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1386 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1387 sd_crop.rect.left = gsc->dst_img.x;
1388 sd_crop.rect.top = gsc->dst_img.y;
1389 sd_crop.rect.width = gsc->dst_img.w;
1390 sd_crop.rect.height = gsc->dst_img.h;
1391 if (exynos_subdev_s_crop(gsc->mdev.sink_sd_entity->fd, &sd_crop) < 0) {
1392 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__,
1399 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1401 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1406 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1408 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1413 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1415 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1420 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1421 V4L2_CID_CACHEABLE, 1) < 0) {
1422 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1427 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1428 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1429 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1434 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1435 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
1436 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
1440 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1441 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
1442 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
1446 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1447 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
1448 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
1452 /* set src format :GSC video dev*/
1453 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1454 fmt.fmt.pix_mp.width = gsc->src_img.fw;
1455 fmt.fmt.pix_mp.height = gsc->src_img.fh;
1456 fmt.fmt.pix_mp.pixelformat = src_color_space;
1457 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1458 fmt.fmt.pix_mp.num_planes = src_planes;
1460 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1461 ALOGE("%s::videodev set format failed", __func__);
1465 /* set src crop info :GSC video dev*/
1466 crop.type = fmt.type;
1467 crop.c.left = gsc->src_img.x;
1468 crop.c.top = gsc->src_img.y;
1469 crop.c.width = gsc->src_img.w;
1470 crop.c.height = gsc->src_img.h;
1472 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1473 ALOGE("%s::videodev set crop failed", __func__);
1477 reqbuf.type = fmt.type;
1478 reqbuf.memory = V4L2_MEMORY_DMABUF;
1479 reqbuf.count = MAX_BUFFERS_GSCALER_OUT;
1481 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1482 ALOGE("%s::request buffers failed", __func__);
1491 int CGscaler::m_gsc_cap_config(void *handle,
1492 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1496 struct v4l2_format fmt;
1497 struct v4l2_crop crop;
1498 struct v4l2_requestbuffers reqbuf;
1499 struct v4l2_subdev_format sd_fmt;
1500 struct v4l2_subdev_crop sd_crop;
1502 unsigned int rotate;
1505 unsigned int plane_size[NUM_OF_GSC_PLANES];
1508 struct v4l2_rect dst_rect;
1509 int32_t src_color_space;
1510 int32_t dst_color_space;
1513 CGscaler* gsc = GetGscaler(handle);
1515 ALOGE("%s::handle == NULL() fail", __func__);
1519 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1520 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1521 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1522 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1523 dst_planes = m_gsc_get_plane_count(dst_color_space);
1524 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1525 rgb = get_yuv_planes(src_color_space) == -1;
1526 CGscaler::rotateValueHAL2GSC(src_img->rot, &rotate, &hflip, &vflip);
1528 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1529 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1530 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1531 (rotate == 90 || rotate == 270)) == false) {
1532 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1537 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1539 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1543 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1545 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1549 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1551 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1555 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1556 V4L2_CID_CACHEABLE, 1) < 0) {
1557 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1561 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1562 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1563 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1567 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1568 V4L2_CID_CSC_RANGE, gsc->range_full)) {
1569 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail",
1570 __func__, gsc->range_full);
1573 /* set format: source pad of Decon-TV sub-dev*/
1574 sd_fmt.pad = DECON_TV_WB_PAD;
1575 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1576 sd_fmt.format.width = gsc->src_img.w;
1577 sd_fmt.format.height = gsc->src_img.h;
1578 sd_fmt.format.code = WB_PATH_FORMAT;
1579 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1580 ALOGE("%s::Decon-TV subdev set format failed", __func__);
1584 if (!gsc->dst_info.stream_on) {
1585 /* set src format: GSC video dev*/
1586 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1587 fmt.fmt.pix_mp.width = gsc->dst_img.fw;
1588 fmt.fmt.pix_mp.height = gsc->dst_img.fh;
1589 fmt.fmt.pix_mp.pixelformat = dst_color_space;
1590 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1591 fmt.fmt.pix_mp.num_planes = dst_planes;
1593 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1594 ALOGE("%s::videodev set format failed", __func__);
1597 gsc->dst_info.buf.buf_idx = 0;
1598 gsc->dst_info.qbuf_cnt = 0;
1601 /* set format: sink pad of GSC sub-dev*/
1602 sd_fmt.pad = GSCALER_SUBDEV_PAD_SINK;
1603 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1604 sd_fmt.format.width = gsc->src_img.w;
1605 sd_fmt.format.height = gsc->src_img.h;
1606 sd_fmt.format.code = WB_PATH_FORMAT;
1607 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1608 ALOGE("%s::GSC subdev set format failed", __func__);
1612 /* set src crop info :GSC video dev*/
1613 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1614 crop.c.left = gsc->dst_img.x;
1615 crop.c.top = gsc->dst_img.y;
1616 crop.c.width = gsc->dst_img.w;
1617 crop.c.height = gsc->dst_img.h;
1618 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1619 ALOGE("%s::videodev set crop failed", __func__);
1623 /* set crop: src crop of GSC sub-dev*/
1624 sd_crop.pad = GSCALER_SUBDEV_PAD_SINK;
1625 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1626 sd_crop.rect.left = 0;
1627 sd_crop.rect.top = 0;
1628 sd_crop.rect.width = gsc->src_img.w;
1629 sd_crop.rect.height = gsc->src_img.h;
1631 if (exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop) < 0) {
1632 ALOGE("%s::GSC subdev set crop failed(PAD=%d)", __func__,
1636 reqbuf.type = fmt.type;
1637 reqbuf.memory = V4L2_MEMORY_DMABUF;
1638 reqbuf.count = MAX_BUFFERS_GSCALER_CAP;
1640 if (!gsc->dst_info.stream_on) {
1641 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1642 ALOGE("%s::request buffers failed", __func__);
1653 void CGscaler::rotateValueHAL2GSC(unsigned int transform,
1654 unsigned int *rotate, unsigned int *hflip, unsigned int *vflip)
1656 int rotate_flag = transform & 0x7;
1661 switch (rotate_flag) {
1662 case HAL_TRANSFORM_ROT_90:
1665 case HAL_TRANSFORM_ROT_180:
1668 case HAL_TRANSFORM_ROT_270:
1671 case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
1673 *vflip = 1; /* set vflip to compensate the rot & flip order. */
1675 case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
1677 *hflip = 1; /* set hflip to compensate the rot & flip order. */
1679 case HAL_TRANSFORM_FLIP_H:
1682 case HAL_TRANSFORM_FLIP_V:
1690 int CGscaler::m_gsc_m2m_run(void *handle,
1691 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1695 CGscaler* gsc = GetGscaler(handle);
1697 ALOGE("%s::handle == NULL() fail", __func__);
1700 void *addr[3] = {NULL, NULL, NULL};
1703 addr[0] = (void *)src_img->yaddr;
1704 addr[1] = (void *)src_img->uaddr;
1705 addr[2] = (void *)src_img->vaddr;
1706 ret = exynos_gsc_set_src_addr(handle, addr, src_img->mem_type,
1707 src_img->acquireFenceFd);
1709 ALOGE("%s::fail: exynos_gsc_set_src_addr[%p %p %p]", __func__,
1710 addr[0], addr[1], addr[2]);
1714 addr[0] = (void *)dst_img->yaddr;
1715 addr[1] = (void *)dst_img->uaddr;
1716 addr[2] = (void *)dst_img->vaddr;
1717 ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->mem_type,
1718 dst_img->acquireFenceFd);
1720 ALOGE("%s::fail: exynos_gsc_set_dst_addr[%p %p %p]", __func__,
1721 addr[0], addr[1], addr[2]);
1725 ret = gsc->m_gsc_m2m_run_core(handle);
1727 ALOGE("%s::fail: m_gsc_m2m_run_core", __func__);
1731 if (src_img->acquireFenceFd >= 0) {
1732 close(src_img->acquireFenceFd);
1733 src_img->acquireFenceFd = -1;
1736 if (dst_img->acquireFenceFd >= 0) {
1737 close(dst_img->acquireFenceFd);
1738 dst_img->acquireFenceFd = -1;
1741 src_img->releaseFenceFd = gsc->src_info.releaseFenceFd;
1742 dst_img->releaseFenceFd = gsc->dst_info.releaseFenceFd;
1749 int CGscaler::m_gsc_out_run(void *handle, exynos_mpp_img *src_img)
1751 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1752 struct v4l2_buffer buf;
1753 int32_t src_color_space;
1756 unsigned int plane_size[NUM_OF_GSC_PLANES];
1758 unsigned int dq_retry_cnt = 0;
1760 CGscaler* gsc = GetGscaler(handle);
1762 ALOGE("%s::handle == NULL() fail", __func__);
1766 /* All buffers have been queued, dequeue one */
1767 if (gsc->src_info.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) {
1768 memset(&buf, 0, sizeof(struct v4l2_buffer));
1769 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1770 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1772 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1773 buf.memory = V4L2_MEMORY_DMABUF;
1774 buf.m.planes = planes;
1776 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1777 src_planes = m_gsc_get_plane_count(src_color_space);
1778 src_planes = (src_planes == -1) ? 1 : src_planes;
1779 buf.length = src_planes;
1783 ret = exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf);
1784 if (ret == -EAGAIN) {
1785 ALOGE("%s::Retry DQbuf(index=%d)", __func__, buf.index);
1791 } while (dq_retry_cnt <= 10);
1794 ALOGE("%s::dq buffer failed (index=%d)", __func__, buf.index);
1797 gsc->src_info.qbuf_cnt--;
1800 memset(&buf, 0, sizeof(struct v4l2_buffer));
1801 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1802 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1804 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1805 src_planes = m_gsc_get_plane_count(src_color_space);
1806 src_planes = (src_planes == -1) ? 1 : src_planes;
1808 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1809 buf.memory = V4L2_MEMORY_DMABUF;
1811 buf.length = src_planes;
1812 buf.index = gsc->src_info.buf.buf_idx;
1813 buf.m.planes = planes;
1816 gsc->src_info.buf.addr[0] = (void*)src_img->yaddr;
1817 gsc->src_info.buf.addr[1] = (void*)src_img->uaddr;
1818 gsc->src_info.buf.addr[2] = (void*)src_img->vaddr;
1820 if (CGscaler::tmp_get_plane_size(src_color_space, plane_size,
1821 gsc->src_img.fw, gsc->src_img.fh, src_planes) != true) {
1822 ALOGE("%s:get_plane_size:fail", __func__);
1826 for (i = 0; i < buf.length; i++) {
1827 buf.m.planes[i].m.fd = (long)gsc->src_info.buf.addr[i];
1828 buf.m.planes[i].length = plane_size[i];
1829 buf.m.planes[i].bytesused = plane_size[i];
1833 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1834 ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)",
1835 __func__, gsc->src_info.buf.buf_idx,
1836 MAX_BUFFERS_GSCALER_OUT);
1839 gsc->src_info.buf.buf_idx++;
1840 gsc->src_info.buf.buf_idx =
1841 gsc->src_info.buf.buf_idx % MAX_BUFFERS_GSCALER_OUT;
1842 gsc->src_info.qbuf_cnt++;
1844 if (gsc->src_info.stream_on == false) {
1845 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1846 (v4l2_buf_type)buf.type) < 0) {
1847 ALOGE("%s::stream on failed", __func__);
1850 gsc->src_info.stream_on = true;
1856 int CGscaler::m_gsc_cap_run(void *handle, exynos_mpp_img *dst_img)
1858 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1859 struct v4l2_buffer buf;
1860 int32_t dst_color_space;
1863 unsigned int plane_size[NUM_OF_GSC_PLANES];
1864 CGscaler* gsc = GetGscaler(handle);
1866 ALOGE("%s::handle == NULL() fail", __func__);
1870 /* All buffers have been queued, dequeue one */
1871 if (gsc->dst_info.qbuf_cnt == MAX_BUFFERS_GSCALER_CAP) {
1872 memset(&buf, 0, sizeof(struct v4l2_buffer));
1873 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1874 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1876 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1877 buf.memory = V4L2_MEMORY_DMABUF;
1878 buf.m.planes = planes;
1880 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1881 dst_planes = m_gsc_get_plane_count(dst_color_space);
1882 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1883 buf.length = dst_planes;
1886 if (exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1887 ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)",
1888 __func__, gsc->src_info.buf.buf_idx,
1889 MAX_BUFFERS_GSCALER_CAP);
1892 gsc->dst_info.qbuf_cnt--;
1895 memset(&buf, 0, sizeof(struct v4l2_buffer));
1896 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1897 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1899 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1900 dst_planes = m_gsc_get_plane_count(dst_color_space);
1901 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1903 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1904 buf.memory = V4L2_MEMORY_DMABUF;
1905 buf.flags = V4L2_BUF_FLAG_USE_SYNC;
1906 buf.length = dst_planes;
1907 buf.index = gsc->dst_info.buf.buf_idx;
1908 buf.m.planes = planes;
1909 buf.reserved = dst_img->acquireFenceFd;
1911 gsc->dst_info.buf.addr[0] = (void*)dst_img->yaddr;
1912 gsc->dst_info.buf.addr[1] = (void*)dst_img->uaddr;
1913 gsc->dst_info.buf.addr[2] = (void*)dst_img->vaddr;
1915 if (CGscaler::tmp_get_plane_size(dst_color_space, plane_size,
1916 gsc->dst_img.fw, gsc->dst_img.fh, dst_planes) != true) {
1917 ALOGE("%s:get_plane_size:fail", __func__);
1921 for (i = 0; i < buf.length; i++) {
1922 buf.m.planes[i].m.fd = (int)(long)gsc->dst_info.buf.addr[i];
1923 buf.m.planes[i].length = plane_size[i];
1924 buf.m.planes[i].bytesused = plane_size[i];
1928 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1929 ALOGE("%s::queue buffer failed (index=%d)(mDstBufNum=%d)",
1930 __func__, gsc->dst_info.buf.buf_idx,
1931 MAX_BUFFERS_GSCALER_CAP);
1935 gsc->dst_info.buf.buf_idx++;
1936 gsc->dst_info.buf.buf_idx =
1937 gsc->dst_info.buf.buf_idx % MAX_BUFFERS_GSCALER_CAP;
1938 gsc->dst_info.qbuf_cnt++;
1940 if (gsc->dst_info.stream_on == false) {
1941 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1942 (v4l2_buf_type)buf.type) < 0) {
1943 ALOGE("%s::stream on failed", __func__);
1946 gsc->dst_info.stream_on = true;
1949 dst_img->releaseFenceFd = buf.reserved;
1953 bool CGscaler::tmp_get_plane_size(int V4L2_PIX,
1954 unsigned int * size, unsigned int width, unsigned int height, int src_planes)
1956 unsigned int frame_ratio = 1;
1957 int src_bpp = get_yuv_bpp(V4L2_PIX);
1958 unsigned int frame_size = width * height;
1960 src_planes = (src_planes == -1) ? 1 : src_planes;
1961 frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
1963 switch (src_planes) {
1966 case V4L2_PIX_FMT_BGR32:
1967 case V4L2_PIX_FMT_RGB32:
1968 size[0] = frame_size << 2;
1970 case V4L2_PIX_FMT_RGB565:
1971 case V4L2_PIX_FMT_NV16:
1972 case V4L2_PIX_FMT_NV61:
1973 case V4L2_PIX_FMT_YUYV:
1974 case V4L2_PIX_FMT_UYVY:
1975 case V4L2_PIX_FMT_VYUY:
1976 case V4L2_PIX_FMT_YVYU:
1977 size[0] = frame_size << 1;
1979 case V4L2_PIX_FMT_YUV420:
1980 case V4L2_PIX_FMT_NV12:
1981 case V4L2_PIX_FMT_NV21:
1982 case V4L2_PIX_FMT_NV21M:
1983 size[0] = (frame_size * 3) >> 1;
1985 case V4L2_PIX_FMT_YVU420:
1986 size[0] = frame_size + (ALIGN((width >> 1), 16) * ((height >> 1) * 2));
1989 ALOGE("%s::invalid color type (%x)", __func__, V4L2_PIX);
1997 size[0] = frame_size;
1998 size[1] = frame_size / frame_ratio;
2002 size[0] = frame_size;
2003 size[1] = frame_size / frame_ratio;
2004 size[2] = frame_size / frame_ratio;
2007 ALOGE("%s::invalid color foarmt", __func__);
2015 int CGscaler::ConfigMpp(void *handle, exynos_mpp_img *src,
2016 exynos_mpp_img *dst)
2018 return exynos_gsc_config_exclusive(handle, src, dst);
2021 int CGscaler::ConfigBlendMpp(void *handle, exynos_mpp_img *src,
2022 exynos_mpp_img *dst,
2023 SrcBlendInfo *srcblendinfo)
2025 return exynos_gsc_config_blend_exclusive(handle, src, dst, srcblendinfo);
2028 int CGscaler::RunMpp(void *handle, exynos_mpp_img *src,
2029 exynos_mpp_img *dst)
2031 return exynos_gsc_run_exclusive(handle, src, dst);
2034 int CGscaler::StopMpp(void *handle)
2036 return exynos_gsc_stop_exclusive(handle);
2039 void CGscaler::DestroyMpp(void *handle)
2041 return exynos_gsc_destroy(handle);
2044 int CGscaler::SetCSCProperty(void *handle, unsigned int eqAuto,
2045 unsigned int fullRange, unsigned int colorspace)
2047 return exynos_gsc_set_csc_property(handle, eqAuto, fullRange,
2051 int CGscaler::FreeMpp(void *handle)
2053 return exynos_gsc_free_and_close(handle);
2056 int CGscaler::SetInputCrop(void *handle,
2057 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
2059 struct v4l2_crop crop;
2061 CGscaler *gsc = GetGscaler(handle);
2063 ALOGE("%s::handle == NULL() fail", __func__);
2067 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2068 crop.c.left = src_img->x;
2069 crop.c.top = src_img->y;
2070 crop.c.width = src_img->w;
2071 crop.c.height = src_img->h;
2073 return exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop);