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(
57 if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
58 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
62 if ((dev_num >= NUM_OF_GSC_HW) && (dev_num < HW_SCAL_MAX)) {
63 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
65 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
69 gsc->scaler = exynos_sc_create_exclusive(dev_num - HW_SCAL0,
73 ALOGE("%s::exynos_sc_create fail", __func__);
77 return reinterpret_cast<void *>(gsc);
80 if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
81 ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
85 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
87 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
91 if (mode == GSC_M2M_MODE) {
92 gsc->gsc_fd = gsc->m_gsc_m2m_create(dev_num);
93 if (gsc->gsc_fd < 0) {
94 ALOGE("%s::m_gsc_m2m_create(%i) fail", __func__, dev_num);
97 } else if (mode == GSC_OUTPUT_MODE) {
98 ret = gsc->m_gsc_output_create(gsc, dev_num, out_mode);
100 ALOGE("%s::m_gsc_output_create(%i) fail", __func__, dev_num);
103 } else if (mode == GSC_CAPTURE_MODE) {
104 ret = gsc->m_gsc_capture_create(gsc, dev_num, out_mode);
106 ALOGE("%s::m_gsc_capture_create(%i) fail", __func__, dev_num);
110 ALOGE("%s::Unsupported Mode(%i) fail", __func__, dev_num);
116 return reinterpret_cast<void *>(gsc);
120 gsc->m_gsc_m2m_destroy(gsc);
122 case GSC_OUTPUT_MODE:
123 gsc->m_gsc_out_destroy(gsc);
125 case GSC_CAPTURE_MODE:
126 gsc->m_gsc_cap_destroy(gsc);
137 void exynos_gsc_destroy(void *handle)
141 CGscaler* gsc = GetGscaler(handle);
143 ALOGE("%s::handle == NULL() fail", __func__);
147 if (gsc->mode == GSC_OUTPUT_MODE)
148 gsc->m_gsc_out_destroy(gsc);
149 else if (gsc->mode ==GSC_CAPTURE_MODE)
150 gsc->m_gsc_cap_destroy(gsc);
152 gsc->m_gsc_m2m_destroy(gsc);
159 int exynos_gsc_set_csc_property(
161 unsigned int eq_auto,
162 unsigned int range_full,
163 unsigned int v4l2_colorspace)
167 CGscaler *gsc = GetGscaler(handle);
169 ALOGE("%s::handle == NULL() fail", __func__);
173 if (gsc->gsc_id >= HW_SCAL0) {
175 ret = exynos_sc_csc_exclusive(gsc->scaler,
176 range_full, v4l2_colorspace);
180 gsc->eq_auto = eq_auto;
181 gsc->range_full = range_full;
182 gsc->v4l2_colorspace = v4l2_colorspace;
189 int exynos_gsc_set_src_format(
193 unsigned int crop_left,
194 unsigned int crop_top,
195 unsigned int crop_width,
196 unsigned int crop_height,
197 unsigned int v4l2_colorformat,
198 unsigned int cacheable,
199 unsigned int mode_drm)
203 CGscaler *gsc = GetGscaler(handle);
205 ALOGE("%s::handle == NULL() fail", __func__);
208 gsc->src_info.width = width;
209 gsc->src_info.height = height;
210 gsc->src_info.crop_left = crop_left;
211 gsc->src_info.crop_top = crop_top;
212 gsc->src_info.crop_width = crop_width;
213 gsc->src_info.crop_height = crop_height;
214 gsc->src_info.v4l2_colorformat = v4l2_colorformat;
215 gsc->src_info.cacheable = cacheable;
216 gsc->src_info.mode_drm = mode_drm;
217 gsc->src_info.dirty = true;
224 int exynos_gsc_set_dst_format(
228 unsigned int crop_left,
229 unsigned int crop_top,
230 unsigned int crop_width,
231 unsigned int crop_height,
232 unsigned int v4l2_colorformat,
233 unsigned int cacheable,
234 unsigned int mode_drm)
238 CGscaler *gsc = GetGscaler(handle);
240 ALOGE("%s::handle == NULL() fail", __func__);
244 gsc->dst_info.width = width;
245 gsc->dst_info.height = height;
246 gsc->dst_info.crop_left = crop_left;
247 gsc->dst_info.crop_top = crop_top;
248 gsc->dst_info.crop_width = crop_width;
249 gsc->dst_info.crop_height = crop_height;
250 gsc->dst_info.v4l2_colorformat = v4l2_colorformat;
251 gsc->dst_info.dirty = true;
252 gsc->dst_info.cacheable = cacheable;
253 gsc->dst_info.mode_drm = mode_drm;
260 int exynos_gsc_set_rotation(
266 CGscaler *gsc = GetGscaler(handle);
268 ALOGE("%s::handle == NULL() fail", __func__);
272 int new_rotation = rotation % 360;
274 if (new_rotation % 90 != 0) {
275 ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__,
281 new_rotation = -new_rotation;
283 gsc->dst_info.rotation = new_rotation;
284 gsc->dst_info.flip_horizontal = flip_horizontal;
285 gsc->dst_info.flip_vertical = flip_vertical;
290 int exynos_gsc_set_src_addr(
298 CGscaler* gsc = GetGscaler(handle);
300 ALOGE("%s::handle == NULL() fail", __func__);
304 gsc->src_info.buf.addr[0] = addr[0];
305 gsc->src_info.buf.addr[1] = addr[1];
306 gsc->src_info.buf.addr[2] = addr[2];
307 gsc->src_info.acquireFenceFd = acquireFenceFd;
308 gsc->src_info.buf.mem_type = (enum v4l2_memory)mem_type;
315 int exynos_gsc_set_dst_addr(
323 CGscaler* gsc = GetGscaler(handle);
325 ALOGE("%s::handle == NULL() fail", __func__);
329 gsc->dst_info.buf.addr[0] = addr[0];
330 gsc->dst_info.buf.addr[1] = addr[1];
331 gsc->dst_info.buf.addr[2] = addr[2];
332 gsc->dst_info.acquireFenceFd = acquireFenceFd;
333 gsc->dst_info.buf.mem_type = (enum v4l2_memory)mem_type;
340 int exynos_gsc_convert(void *handle)
345 CGscaler* gsc = GetGscaler(handle);
347 ALOGE("%s::handle == NULL() fail", __func__);
351 if (gsc->m_gsc_m2m_run_core(handle) < 0) {
352 ALOGE("%s::exynos_gsc_run_core fail", __func__);
356 if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
357 ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
361 if (gsc->src_info.releaseFenceFd >= 0) {
362 close(gsc->src_info.releaseFenceFd);
363 gsc->src_info.releaseFenceFd = -1;
366 if (gsc->dst_info.releaseFenceFd >= 0) {
367 close(gsc->dst_info.releaseFenceFd);
368 gsc->dst_info.releaseFenceFd = -1;
371 if (gsc->m_gsc_m2m_stop(handle) < 0) {
372 ALOGE("%s::m_gsc_m2m_stop", __func__);
384 int exynos_gsc_subdev_s_crop(void *handle,
385 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
387 struct v4l2_subdev_crop sd_crop;
388 CGscaler *gsc = GetGscaler(handle);
390 ALOGE("%s::handle == NULL() fail", __func__);
394 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE;
395 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
396 sd_crop.rect.left = dst_img->x;
397 sd_crop.rect.top = dst_img->y;
398 sd_crop.rect.width = dst_img->w;
399 sd_crop.rect.height = dst_img->h;
401 return exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop);
404 int exynos_gsc_config_exclusive(void *handle,
405 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
410 CGscaler* gsc = GetGscaler(handle);
412 ALOGE("%s::handle == NULL() fail", __func__);
415 if (gsc->gsc_id >= HW_SCAL0) {
416 ret = exynos_sc_config_exclusive(gsc->scaler,
417 (exynos_sc_img *)src_img, (exynos_sc_img *)dst_img);
424 ret = gsc->m_gsc_m2m_config(handle, src_img, dst_img);
426 case GSC_OUTPUT_MODE:
427 ret = gsc->m_gsc_out_config(handle, src_img, dst_img);
429 case GSC_CAPTURE_MODE:
430 ret = gsc->m_gsc_cap_config(handle, src_img, dst_img);
441 int exynos_gsc_run_exclusive(void *handle,
442 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
447 CGscaler* gsc = GetGscaler(handle);
449 ALOGE("%s::handle == NULL() fail", __func__);
453 if (gsc->gsc_id >= HW_SCAL0) {
454 ret = exynos_sc_run_exclusive(gsc->scaler,
455 (exynos_sc_img *)src_img, (exynos_sc_img *)dst_img);
462 ret = gsc->m_gsc_m2m_run(handle, src_img, dst_img);
464 case GSC_OUTPUT_MODE:
465 ret = gsc->m_gsc_out_run(handle, src_img);
467 case GSC_CAPTURE_MODE:
468 ret = gsc->m_gsc_cap_run(handle, dst_img);
479 void *exynos_gsc_create_blend_exclusive(int dev_num, int mode, int out_mode,
484 if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
485 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
489 if ((dev_num >= NUM_OF_GSC_HW) && (dev_num < HW_SCAL_MAX)) {
490 CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
492 ALOGE("%s:: failed to allocate Gscaler handle", __func__);
496 gsc->scaler = exynos_sc_create_blend_exclusive(dev_num - HW_SCAL0, allow_drm);
500 ALOGE("%s::exynos_sc_create_blend_exclusive failed", __func__);
505 return reinterpret_cast<void *>(gsc);
513 int exynos_gsc_config_blend_exclusive(void *handle,
514 exynos_mpp_img *src_img, exynos_mpp_img *dst_img,
515 struct SrcBlendInfo *srcblendinfo)
520 CGscaler* gsc = GetGscaler(handle);
522 ALOGE("%s::handle == NULL() fail", __func__);
525 if (gsc->gsc_id >= HW_SCAL0) {
526 ret = exynos_sc_config_blend_exclusive(gsc->scaler,
527 (exynos_sc_img *)src_img,
528 (exynos_sc_img *)dst_img,
537 int exynos_gsc_wait_frame_done_exclusive(void *handle)
542 CGscaler* gsc = GetGscaler(handle);
544 ALOGE("%s::handle == NULL() fail", __func__);
548 if (gsc->gsc_id >= HW_SCAL0) {
549 ret = exynos_sc_wait_frame_done_exclusive(gsc->scaler);
554 if (gsc->mode == GSC_M2M_MODE)
555 ret = gsc->m_gsc_m2m_wait_frame_done(handle);
562 int exynos_gsc_stop_exclusive(void *handle)
567 CGscaler* gsc = GetGscaler(handle);
569 ALOGE("%s::handle == NULL() fail", __func__);
573 if (gsc->gsc_id >= HW_SCAL0) {
574 ret = exynos_sc_stop_exclusive(gsc->scaler);
581 ret = gsc->m_gsc_m2m_stop(handle);
583 case GSC_OUTPUT_MODE:
584 ret = gsc->m_gsc_out_stop(handle);
586 case GSC_CAPTURE_MODE:
587 ret = gsc->m_gsc_cap_stop(handle);
598 int exynos_gsc_free_and_close(void *handle)
602 struct v4l2_requestbuffers reqbuf;
604 CGscaler* gsc = GetGscaler(handle);
606 ALOGE("%s::handle == NULL() fail", __func__);
611 if (gsc->gsc_id >= HW_SCAL0) {
612 ret = exynos_sc_free_and_close(gsc->scaler);
617 memset(&reqbuf, 0, sizeof(struct v4l2_requestbuffers));
618 if (gsc->mode == GSC_OUTPUT_MODE)
619 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
621 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
623 reqbuf.memory = V4L2_MEMORY_DMABUF;
626 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
627 ALOGE("%s::request buffers failed", __func__);
631 exynos_gsc_destroy(gsc);