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.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
29 #include "libgscaler_obj.h"
31 void *exynos_gsc_create(void)
33 CGscaler *gsc = new CGscaler(GSC_M2M_MODE);
35 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
38 if (gsc->m_gsc_find_and_create(gsc) == false) {
39 ALOGE("%s::m_exynos_gsc_find_and_create() fail", __func__);
44 return reinterpret_cast<void *>(gsc);
47 void *exynos_gsc_create_exclusive(
55 unsigned int total_sleep_time = 0;
60 if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
61 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
65 if ((dev_num >= NUM_OF_GSC_HW) && (dev_num < HW_SCAL_MAX)) {
66 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
68 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
72 gsc->scaler = exynos_sc_create_exclusive(dev_num - HW_SCAL0,
76 ALOGE("%s::exynos_sc_create fail", __func__);
80 return reinterpret_cast<void *>(gsc);
83 if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
84 ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
88 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
90 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
94 if (mode == GSC_M2M_MODE) {
95 gsc->gsc_fd = gsc->m_gsc_m2m_create(dev_num);
96 if (gsc->gsc_fd < 0) {
97 ALOGE("%s::m_gsc_m2m_create(%i) fail", __func__, dev_num);
100 } else if (mode == GSC_OUTPUT_MODE) {
101 ret = gsc->m_gsc_output_create(gsc, dev_num, out_mode);
103 ALOGE("%s::m_gsc_output_create(%i) fail", __func__, dev_num);
106 } else if (mode == GSC_CAPTURE_MODE) {
107 ret = gsc->m_gsc_capture_create(gsc, dev_num, out_mode);
109 ALOGE("%s::m_gsc_capture_create(%i) fail", __func__, dev_num);
113 ALOGE("%s::Unsupported Mode(%i) fail", __func__, dev_num);
119 return reinterpret_cast<void *>(gsc);
123 gsc->m_gsc_m2m_destroy(gsc);
125 case GSC_OUTPUT_MODE:
126 gsc->m_gsc_out_destroy(gsc);
128 case GSC_CAPTURE_MODE:
129 gsc->m_gsc_cap_destroy(gsc);
140 void exynos_gsc_destroy(void *handle)
145 CGscaler* gsc = GetGscaler(handle);
147 ALOGE("%s::handle == NULL() fail", __func__);
151 if (gsc->mode == GSC_OUTPUT_MODE)
152 gsc->m_gsc_out_destroy(gsc);
153 else if (gsc->mode ==GSC_CAPTURE_MODE)
154 gsc->m_gsc_cap_destroy(gsc);
156 gsc->m_gsc_m2m_destroy(gsc);
163 int exynos_gsc_set_csc_property(
165 unsigned int eq_auto,
166 unsigned int range_full,
167 unsigned int v4l2_colorspace)
171 CGscaler *gsc = GetGscaler(handle);
173 ALOGE("%s::handle == NULL() fail", __func__);
177 if (gsc->gsc_id >= HW_SCAL0) {
179 ret = exynos_sc_csc_exclusive(gsc->scaler,
180 range_full, v4l2_colorspace);
184 gsc->eq_auto = eq_auto;
185 gsc->range_full = range_full;
186 gsc->v4l2_colorspace = v4l2_colorspace;
193 int exynos_gsc_set_src_format(
197 unsigned int crop_left,
198 unsigned int crop_top,
199 unsigned int crop_width,
200 unsigned int crop_height,
201 unsigned int v4l2_colorformat,
202 unsigned int cacheable,
203 unsigned int mode_drm)
207 CGscaler *gsc = GetGscaler(handle);
209 ALOGE("%s::handle == NULL() fail", __func__);
212 gsc->src_info.width = width;
213 gsc->src_info.height = height;
214 gsc->src_info.crop_left = crop_left;
215 gsc->src_info.crop_top = crop_top;
216 gsc->src_info.crop_width = crop_width;
217 gsc->src_info.crop_height = crop_height;
218 gsc->src_info.v4l2_colorformat = v4l2_colorformat;
219 gsc->src_info.cacheable = cacheable;
220 gsc->src_info.mode_drm = mode_drm;
221 gsc->src_info.dirty = true;
228 int exynos_gsc_set_dst_format(
232 unsigned int crop_left,
233 unsigned int crop_top,
234 unsigned int crop_width,
235 unsigned int crop_height,
236 unsigned int v4l2_colorformat,
237 unsigned int cacheable,
238 unsigned int mode_drm)
242 CGscaler *gsc = GetGscaler(handle);
244 ALOGE("%s::handle == NULL() fail", __func__);
248 gsc->dst_info.width = width;
249 gsc->dst_info.height = height;
250 gsc->dst_info.crop_left = crop_left;
251 gsc->dst_info.crop_top = crop_top;
252 gsc->dst_info.crop_width = crop_width;
253 gsc->dst_info.crop_height = crop_height;
254 gsc->dst_info.v4l2_colorformat = v4l2_colorformat;
255 gsc->dst_info.dirty = true;
256 gsc->dst_info.cacheable = cacheable;
257 gsc->dst_info.mode_drm = mode_drm;
264 int exynos_gsc_set_rotation(
270 CGscaler *gsc = GetGscaler(handle);
272 ALOGE("%s::handle == NULL() fail", __func__);
276 int new_rotation = rotation % 360;
278 if (new_rotation % 90 != 0) {
279 ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__,
285 new_rotation = -new_rotation;
287 gsc->dst_info.rotation = new_rotation;
288 gsc->dst_info.flip_horizontal = flip_horizontal;
289 gsc->dst_info.flip_vertical = flip_vertical;
294 int exynos_gsc_set_src_addr(
302 CGscaler* gsc = GetGscaler(handle);
304 ALOGE("%s::handle == NULL() fail", __func__);
308 gsc->src_info.buf.addr[0] = addr[0];
309 gsc->src_info.buf.addr[1] = addr[1];
310 gsc->src_info.buf.addr[2] = addr[2];
311 gsc->src_info.acquireFenceFd = acquireFenceFd;
312 gsc->src_info.buf.mem_type = (enum v4l2_memory)mem_type;
319 int exynos_gsc_set_dst_addr(
327 CGscaler* gsc = GetGscaler(handle);
329 ALOGE("%s::handle == NULL() fail", __func__);
333 gsc->dst_info.buf.addr[0] = addr[0];
334 gsc->dst_info.buf.addr[1] = addr[1];
335 gsc->dst_info.buf.addr[2] = addr[2];
336 gsc->dst_info.acquireFenceFd = acquireFenceFd;
337 gsc->dst_info.buf.mem_type = (enum v4l2_memory)mem_type;
344 int exynos_gsc_convert(void *handle)
349 CGscaler* gsc = GetGscaler(handle);
351 ALOGE("%s::handle == NULL() fail", __func__);
355 if (gsc->m_gsc_m2m_run_core(handle) < 0) {
356 ALOGE("%s::exynos_gsc_run_core fail", __func__);
360 if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
361 ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
365 if (gsc->src_info.releaseFenceFd >= 0) {
366 close(gsc->src_info.releaseFenceFd);
367 gsc->src_info.releaseFenceFd = -1;
370 if (gsc->dst_info.releaseFenceFd >= 0) {
371 close(gsc->dst_info.releaseFenceFd);
372 gsc->dst_info.releaseFenceFd = -1;
375 if (gsc->m_gsc_m2m_stop(handle) < 0) {
376 ALOGE("%s::m_gsc_m2m_stop", __func__);
388 int exynos_gsc_subdev_s_crop(void *handle,
389 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
391 struct v4l2_subdev_crop sd_crop;
392 CGscaler *gsc = GetGscaler(handle);
394 ALOGE("%s::handle == NULL() fail", __func__);
398 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE;
399 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
400 sd_crop.rect.left = dst_img->x;
401 sd_crop.rect.top = dst_img->y;
402 sd_crop.rect.width = dst_img->w;
403 sd_crop.rect.height = dst_img->h;
405 return exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop);
408 int exynos_gsc_config_exclusive(void *handle,
409 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
414 CGscaler* gsc = GetGscaler(handle);
416 ALOGE("%s::handle == NULL() fail", __func__);
419 if (gsc->gsc_id >= HW_SCAL0) {
420 ret = exynos_sc_config_exclusive(gsc->scaler,
421 (exynos_sc_img *)src_img, (exynos_sc_img *)dst_img);
428 ret = gsc->m_gsc_m2m_config(handle, src_img, dst_img);
430 case GSC_OUTPUT_MODE:
431 ret = gsc->m_gsc_out_config(handle, src_img, dst_img);
433 case GSC_CAPTURE_MODE:
434 ret = gsc->m_gsc_cap_config(handle, src_img, dst_img);
445 int exynos_gsc_run_exclusive(void *handle,
446 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
451 CGscaler* gsc = GetGscaler(handle);
453 ALOGE("%s::handle == NULL() fail", __func__);
457 if (gsc->gsc_id >= HW_SCAL0) {
458 ret = exynos_sc_run_exclusive(gsc->scaler,
459 (exynos_sc_img *)src_img, (exynos_sc_img *)dst_img);
466 ret = gsc->m_gsc_m2m_run(handle, src_img, dst_img);
468 case GSC_OUTPUT_MODE:
469 ret = gsc->m_gsc_out_run(handle, src_img);
471 case GSC_CAPTURE_MODE:
472 ret = gsc->m_gsc_cap_run(handle, dst_img);
483 void *exynos_gsc_create_blend_exclusive(int dev_num, int mode, int out_mode,
488 unsigned int total_sleep_time = 0;
493 if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
494 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
498 if ((dev_num >= NUM_OF_GSC_HW) && (dev_num < HW_SCAL_MAX)) {
499 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
501 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
505 gsc->scaler = exynos_sc_create_blend_exclusive(dev_num - HW_SCAL0, allow_drm);
509 ALOGE("%s::exynos_sc_create_blend_exclusive failed", __func__);
514 return reinterpret_cast<void *>(gsc);
522 int exynos_gsc_config_blend_exclusive(void *handle,
523 exynos_mpp_img *src_img, exynos_mpp_img *dst_img,
524 struct SrcBlendInfo *srcblendinfo)
529 CGscaler* gsc = GetGscaler(handle);
531 ALOGE("%s::handle == NULL() fail", __func__);
534 if (gsc->gsc_id >= HW_SCAL0) {
535 ret = exynos_sc_config_blend_exclusive(gsc->scaler,
536 (exynos_sc_img *)src_img,
537 (exynos_sc_img *)dst_img,
546 int exynos_gsc_wait_frame_done_exclusive(void *handle)
551 CGscaler* gsc = GetGscaler(handle);
553 ALOGE("%s::handle == NULL() fail", __func__);
557 if (gsc->gsc_id >= HW_SCAL0) {
558 ret = exynos_sc_wait_frame_done_exclusive(gsc->scaler);
563 if (gsc->mode == GSC_M2M_MODE)
564 ret = gsc->m_gsc_m2m_wait_frame_done(handle);
571 int exynos_gsc_stop_exclusive(void *handle)
576 CGscaler* gsc = GetGscaler(handle);
578 ALOGE("%s::handle == NULL() fail", __func__);
582 if (gsc->gsc_id >= HW_SCAL0) {
583 ret = exynos_sc_stop_exclusive(gsc->scaler);
590 ret = gsc->m_gsc_m2m_stop(handle);
592 case GSC_OUTPUT_MODE:
593 ret = gsc->m_gsc_out_stop(handle);
595 case GSC_CAPTURE_MODE:
596 ret = gsc->m_gsc_cap_stop(handle);
607 int exynos_gsc_free_and_close(void *handle)
611 struct v4l2_requestbuffers reqbuf;
612 struct v4l2_buffer buf;
613 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
615 CGscaler* gsc = GetGscaler(handle);
617 ALOGE("%s::handle == NULL() fail", __func__);
622 if (gsc->gsc_id >= HW_SCAL0) {
623 ret = exynos_sc_free_and_close(gsc->scaler);
628 memset(&reqbuf, 0, sizeof(struct v4l2_requestbuffers));
629 if (gsc->mode == GSC_OUTPUT_MODE)
630 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
632 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
634 reqbuf.memory = V4L2_MEMORY_DMABUF;
637 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
638 ALOGE("%s::request buffers failed", __func__);
642 exynos_gsc_destroy(gsc);