fimg5x: Fix broken Mutex code
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libgscaler / libgscaler_obj.cpp
CommitLineData
5763fb39
T
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 * Copyright@ Samsung Electronics Co. LTD
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17
18/*!
19 * \file libgscaler_obj.cpp
20 * \brief source file for Gscaler HAL
21 * \author Sungchun Kang (sungchun.kang@samsung.com)
22 * \date 2013/06/01
23 *
24 * <b>Revision History: </b>
25 * - 2013.06.01 : Sungchun Kang (sungchun.kang@samsung.com) \n
26 * Create
27 */
28
29#include <cerrno>
30#include "libgscaler_obj.h"
31#include "content_protect.h"
32
33int CGscaler::m_gsc_output_create(void *handle, int dev_num, int out_mode)
34{
35 Exynos_gsc_In();
36
37 struct media_device *media0;
38 struct media_entity *gsc_sd_entity;
39 struct media_entity *gsc_vd_entity;
40 struct media_entity *sink_sd_entity;
41 char node[32];
42 char devname[32];
43 unsigned int cap;
44 int i;
45 int fd = 0;
46 CGscaler* gsc = GetGscaler(handle);
47 if (gsc == NULL) {
48 ALOGE("%s::handle == NULL() fail", __func__);
49 return -1;
50 }
51
52 if ((out_mode != GSC_OUT_FIMD) &&
53 (out_mode != GSC_OUT_TV))
54 return -1;
55
56 gsc->out_mode = out_mode;
57 /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
58 if ((out_mode == GSC_OUT_FIMD) &&
59#ifndef USES_ONLY_GSC0_GSC1
60 (dev_num > 2))
61#else
62 (dev_num > 1))
63#endif
64 return -1;
65
66 /* media0 */
67 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 0);
68 media0 = exynos_media_open(node);
69 if (media0 == NULL) {
70 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
71 return false;
72 }
73 gsc->mdev.media0 = media0;
74
75 /* Get the sink subdev entity by name and make the node of sink subdev*/
76 if (out_mode == GSC_OUT_FIMD)
77 snprintf(devname, sizeof(devname), PFX_FIMD_ENTITY, dev_num);
78 else
79 snprintf(devname, sizeof(devname), PFX_MXR_ENTITY, 0);
80
81 sink_sd_entity = exynos_media_get_entity_by_name(media0, devname,
82 strlen(devname));
83 if (!sink_sd_entity) {
84 ALOGE("%s:: failed to get the sink sd entity", __func__);
85 goto gsc_output_err;
86 }
87 gsc->mdev.sink_sd_entity = sink_sd_entity;
88
89 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
90 if (sink_sd_entity->fd < 0) {
91 ALOGE("%s:: failed to open sink subdev node", __func__);
92 goto gsc_output_err;
93 }
94
95 /* get GSC video dev & sub dev entity by name*/
96#if defined(USES_DT)
97 switch (dev_num) {
98 case 0:
99 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
100 break;
101 case 1:
102 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
103 break;
104 case 2:
105 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
106 break;
107 }
108#else
109 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
110#endif
111 gsc_vd_entity = exynos_media_get_entity_by_name(media0, devname,
112 strlen(devname));
113 if (!gsc_vd_entity) {
114 ALOGE("%s:: failed to get the gsc vd entity", __func__);
115 goto gsc_output_err;
116 }
117 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
118
119 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
120 gsc_sd_entity = exynos_media_get_entity_by_name(media0, devname,
121 strlen(devname));
122 if (!gsc_sd_entity) {
123 ALOGE("%s:: failed to get the gsc sd entity", __func__);
124 goto gsc_output_err;
125 }
126 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
127
128 /* gsc sub-dev open */
129 snprintf(devname, sizeof(devname), PFX_GSC_SUBDEV_ENTITY, dev_num);
130 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
131 if (gsc_sd_entity->fd < 0) {
132 ALOGE("%s: gsc sub-dev open fail", __func__);
133 goto gsc_output_err;
134 }
135
136 /* gsc video-dev open */
137#if defined(USES_DT)
138 switch (dev_num) {
139 case 0:
140 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY0);
141 break;
142 case 1:
143 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY1);
144 break;
145 case 2:
146 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY2);
147 break;
148 }
149#else
150 snprintf(devname, sizeof(devname), PFX_GSC_VIDEODEV_ENTITY, dev_num);
151#endif
152 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR | O_NONBLOCK);
153 if (gsc_vd_entity->fd < 0) {
154 ALOGE("%s: gsc video-dev open fail", __func__);
155 goto gsc_output_err;
156 }
157
158 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
159
160 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
161 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
162 goto gsc_output_err;
163 }
164
165 Exynos_gsc_Out();
166
167 return 0;
168
169gsc_output_err:
170 gsc->m_gsc_out_destroy(handle);
171
172 return -1;
173}
174
175int CGscaler::m_gsc_capture_create(void *handle, int dev_num, int out_mode)
176{
177 Exynos_gsc_In();
178
179 struct media_device *media1;
180 struct media_entity *gsc_sd_entity;
181 struct media_entity *gsc_vd_entity;
182 struct media_entity *sink_sd_entity;
183 struct media_link *links;
184 char node[32];
185 char devname[32];
186 unsigned int cap;
187 int i;
188 int fd = 0;
189 CGscaler* gsc = GetGscaler(handle);
190 if (gsc == NULL) {
191 ALOGE("%s::handle == NULL() fail", __func__);
192 return -1;
193 }
194
195 gsc->out_mode = out_mode;
196
197 if (dev_num != 2)
198 return -1;
199
200 /* media1 */
201 snprintf(node, sizeof(node), "%s%d", PFX_NODE_MEDIADEV, 1);
202 media1 = exynos_media_open(node);
203 if (media1 == NULL) {
204 ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
205 return false;
206 }
207 gsc->mdev.media1 = media1;
208
209 /* DECON-TV sub-device Open */
210 snprintf(devname, sizeof(devname), DEX_WB_SD_NAME);
211
212 sink_sd_entity = exynos_media_get_entity_by_name(media1, devname,
213 strlen(devname));
214 if (!sink_sd_entity) {
215 ALOGE("%s:: failed to get the sink sd entity", __func__);
216 goto gsc_cap_err;
217 }
218 gsc->mdev.sink_sd_entity = sink_sd_entity;
219
220 sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
221 if (sink_sd_entity->fd < 0) {
222 ALOGE("%s:: failed to open sink subdev node", __func__);
223 goto gsc_cap_err;
224 }
225
226 /* Gscaler2 capture video-device Open */
227 snprintf(devname, sizeof(devname), PFX_GSC_CAPTURE_ENTITY);
228 gsc_vd_entity = exynos_media_get_entity_by_name(media1, devname,
229 strlen(devname));
230 if (!gsc_vd_entity) {
231 ALOGE("%s:: failed to get the gsc vd entity", __func__);
232 goto gsc_cap_err;
233 }
234 gsc->mdev.gsc_vd_entity = gsc_vd_entity;
235
236 gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
237 if (gsc_vd_entity->fd < 0) {
238 ALOGE("%s: gsc video-dev open fail", __func__);
239 goto gsc_cap_err;
240 }
241
242 /* Gscaler2 capture sub-device Open */
243 snprintf(devname, sizeof(devname), GSC_WB_SD_NAME);
244 gsc_sd_entity = exynos_media_get_entity_by_name(media1, devname,
245 strlen(devname));
246 if (!gsc_sd_entity) {
247 ALOGE("%s:: failed to get the gsc sd entity", __func__);
248 goto gsc_cap_err;
249 }
250 gsc->mdev.gsc_sd_entity = gsc_sd_entity;
251
252 gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
253 if (gsc_sd_entity->fd < 0) {
254 ALOGE("%s: gsc sub-dev open fail", __func__);
255 goto gsc_cap_err;
256 }
257
258 if (exynos_media_setup_link(media1, sink_sd_entity->pads,
259 gsc_sd_entity->pads, MEDIA_LNK_FL_ENABLED) < 0) {
260 ALOGE("%s::exynos_media_setup_link failed", __func__);
261 goto gsc_cap_err;
262 }
263
264 cap = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
265
266 if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
267 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
268 goto gsc_cap_err;
269 }
270
271 Exynos_gsc_Out();
272
273 return 0;
274
275gsc_cap_err:
276 gsc->m_gsc_cap_destroy(handle);
277
278 return -1;
279}
280
281int CGscaler::m_gsc_out_stop(void *handle)
282{
283 Exynos_gsc_In();
284
285 struct v4l2_requestbuffers reqbuf;
286 CGscaler* gsc = GetGscaler(handle);
287 if (gsc == NULL) {
288 ALOGE("%s::handle == NULL() fail", __func__);
289 return -1;
290 }
291
292 if (gsc->src_info.stream_on == false) {
293 /* to handle special scenario.*/
294 gsc->src_info.qbuf_cnt = 0;
295 ALOGD("%s::GSC is already stopped", __func__);
296 goto SKIP_STREAMOFF;
297 }
298 gsc->src_info.qbuf_cnt = 0;
299 gsc->src_info.stream_on = false;
300
301 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
302 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
303 ALOGE("%s::stream off failed", __func__);
304 return -1;
305 }
306
307SKIP_STREAMOFF:
308 Exynos_gsc_Out();
309
310 return 0;
311}
312
313int CGscaler::m_gsc_cap_stop(void *handle)
314{
315 Exynos_gsc_In();
316
317 CGscaler* gsc = GetGscaler(handle);
318 if (gsc == NULL) {
319 ALOGE("%s::handle == NULL() fail", __func__);
320 return -1;
321 }
322
323 if (gsc->dst_info.stream_on == false) {
324 /* to handle special scenario.*/
325 gsc->dst_info.qbuf_cnt = 0;
326 ALOGD("%s::GSC is already stopped", __func__);
327 goto SKIP_STREAMOFF;
328 }
329 gsc->dst_info.qbuf_cnt = 0;
330 gsc->dst_info.stream_on = false;
331
332 if (exynos_v4l2_streamoff(gsc->mdev.gsc_vd_entity->fd,
333 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
334 ALOGE("%s::stream off failed", __func__);
335 return -1;
336 }
337
338SKIP_STREAMOFF:
339 Exynos_gsc_Out();
340
341 return 0;
342}
343
344bool CGscaler::m_gsc_out_destroy(void *handle)
345{
346 Exynos_gsc_In();
347
348 int i;
349 CGscaler* gsc = GetGscaler(handle);
350 if (gsc == NULL) {
351 ALOGE("%s::handle == NULL() fail", __func__);
352 return false;
353 }
354
355 if (gsc->src_info.stream_on == true) {
356 if (gsc->m_gsc_out_stop(gsc) < 0)
357 ALOGE("%s::m_gsc_out_stop() fail", __func__);
358
359 gsc->src_info.stream_on = false;
360 }
361
362 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
363 close(gsc->mdev.gsc_vd_entity->fd);
364 gsc->mdev.gsc_vd_entity->fd = -1;
365 }
366
367 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
368 close(gsc->mdev.gsc_sd_entity->fd);
369 gsc->mdev.gsc_sd_entity->fd = -1;
370 }
371
372 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
373 close(gsc->mdev.sink_sd_entity->fd);
374 gsc->mdev.sink_sd_entity->fd = -1;
375 }
376
377 if (gsc->mdev.media0)
378 exynos_media_close(gsc->mdev.media0);
379
380 gsc->mdev.media0 = NULL;
381 gsc->mdev.gsc_sd_entity = NULL;
382 gsc->mdev.gsc_vd_entity = NULL;
383 gsc->mdev.sink_sd_entity = NULL;
384
385 Exynos_gsc_Out();
386 return true;
387}
388
389bool CGscaler::m_gsc_cap_destroy(void *handle)
390{
391 Exynos_gsc_In();
392
393 CGscaler* gsc = GetGscaler(handle);
394 if (gsc == NULL) {
395 ALOGE("%s::handle == NULL() fail", __func__);
396 return false;
397 }
398
399 if (gsc->dst_info.stream_on == true) {
400 if (gsc->m_gsc_cap_stop(gsc) < 0)
401 ALOGE("%s::m_gsc_cap_stop() fail", __func__);
402
403 gsc->dst_info.stream_on = false;
404 }
405
406 if (!gsc->mdev.media1 || !gsc->mdev.gsc_sd_entity ||
407 !gsc->mdev.gsc_vd_entity || !gsc->mdev.sink_sd_entity) {
408 ALOGE("%s::gsc->mdev information is null", __func__);
409 return false;
410 }
411
412 if (exynos_media_setup_link(gsc->mdev.media1,
413 gsc->mdev.sink_sd_entity->pads,
414 gsc->mdev.gsc_sd_entity->pads, 0) < 0) {
415 ALOGE("%s::exynos_media_setup_unlin failed", __func__);
416 }
417
418 if (gsc->mdev.gsc_vd_entity && gsc->mdev.gsc_vd_entity->fd > 0) {
419 close(gsc->mdev.gsc_vd_entity->fd);
420 gsc->mdev.gsc_vd_entity->fd = -1;
421 }
422
423 if (gsc->mdev.gsc_sd_entity && gsc->mdev.gsc_sd_entity->fd > 0) {
424 close(gsc->mdev.gsc_sd_entity->fd);
425 gsc->mdev.gsc_sd_entity->fd = -1;
426 }
427
428 if (gsc->mdev.sink_sd_entity && gsc->mdev.sink_sd_entity->fd > 0) {
429 close(gsc->mdev.sink_sd_entity->fd);
430 gsc->mdev.sink_sd_entity->fd = -1;
431 }
432
433 if (gsc->mdev.media1)
434 exynos_media_close(gsc->mdev.media1);
435
436 gsc->mdev.media1 = NULL;
437 gsc->mdev.gsc_sd_entity = NULL;
438 gsc->mdev.gsc_vd_entity = NULL;
439 gsc->mdev.sink_sd_entity = NULL;
440
441 Exynos_gsc_Out();
442 return true;
443}
444
445int CGscaler::m_gsc_m2m_create(int dev)
446{
447 Exynos_gsc_In();
448
449 int fd = 0;
450 int video_node_num;
451 unsigned int cap;
452 char node[32];
453
454 switch(dev) {
455 case 0:
456 video_node_num = NODE_NUM_GSC_0;
457 break;
458 case 1:
459 video_node_num = NODE_NUM_GSC_1;
460 break;
461#ifndef USES_ONLY_GSC0_GSC1
462 case 2:
463 video_node_num = NODE_NUM_GSC_2;
464 break;
465 case 3:
466 video_node_num = NODE_NUM_GSC_3;
467 break;
468#endif
469 default:
470 ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
471 return -1;
472 break;
473 }
474
475 snprintf(node, sizeof(node), "%s%d", PFX_NODE_GSC, video_node_num);
476 fd = exynos_v4l2_open(node, O_RDWR);
477 if (fd < 0) {
478 ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
479 return -1;
480 }
481
482 cap = V4L2_CAP_STREAMING |
483 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
484 V4L2_CAP_VIDEO_CAPTURE_MPLANE;
485
486 if (exynos_v4l2_querycap(fd, cap) == false) {
487 ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
488 close(fd);
489 fd = 0;
490 return -1;
491 }
492
493 Exynos_gsc_Out();
494
495 return fd;
496}
497
498bool CGscaler::m_gsc_find_and_create(void *handle)
499{
500 Exynos_gsc_In();
501
502 int i = 0;
503 bool flag_find_new_gsc = false;
504 unsigned int total_sleep_time = 0;
505 CGscaler* gsc = GetGscaler(handle);
506 if (gsc == NULL) {
507 ALOGE("%s::handle == NULL() fail", __func__);
508 return false;
509 }
510
511 do {
512 for (i = 0; i < NUM_OF_GSC_HW; i++) {
513#ifndef USES_ONLY_GSC0_GSC1
514 if (i == 0 || i == 3)
515#else
516 if (i == 0)
517#endif
518 continue;
519
520 gsc->gsc_id = i;
521 gsc->gsc_fd = gsc->m_gsc_m2m_create(i);
522 if (gsc->gsc_fd < 0) {
523 gsc->gsc_fd = 0;
524 continue;
525 }
526
527 flag_find_new_gsc = true;
528 break;
529 }
530
531 if (flag_find_new_gsc == false) {
532 usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
533 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
534 ALOGV("%s::waiting for the gscaler availability", __func__);
535 }
536
537 } while(flag_find_new_gsc == false
538 && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
539
540 if (flag_find_new_gsc == false)
541 ALOGE("%s::we don't have any available gsc.. fail", __func__);
542
543 Exynos_gsc_Out();
544
545 return flag_find_new_gsc;
546}
547
548bool CGscaler::m_gsc_m2m_destroy(void *handle)
549{
550 Exynos_gsc_In();
551
552 CGscaler* gsc = GetGscaler(handle);
553 if (gsc == NULL) {
554 ALOGE("%s::handle == NULL() fail", __func__);
555 return false;
556 }
557
558 /*
559 * just in case, we call stop here because we cannot afford to leave
560 * secure side protection on if things failed.
561 */
562 gsc->m_gsc_m2m_stop(handle);
563
564 if (gsc->gsc_id >= HW_SCAL0) {
565 bool ret = exynos_sc_free_and_close(gsc->scaler);
566 Exynos_gsc_Out();
567 return ret;
568 }
569
570 if (0 < gsc->gsc_fd)
571 close(gsc->gsc_fd);
572 gsc->gsc_fd = 0;
573
574 Exynos_gsc_Out();
575
576 return true;
577}
578
579int CGscaler::m_gsc_m2m_stop(void *handle)
580{
581 Exynos_gsc_In();
582
583 struct v4l2_requestbuffers req_buf;
584 int ret = 0;
585 CGscaler* gsc = GetGscaler(handle);
586 if (gsc == NULL) {
587 ALOGE("%s::handle == NULL() fail", __func__);
588 return -1;
589 }
590
591 if (!gsc->src_info.stream_on && !gsc->dst_info.stream_on) {
592 /* wasn't streaming, return success */
593 return 0;
594 } else if (gsc->src_info.stream_on != gsc->dst_info.stream_on) {
595 ALOGE("%s: invalid state, queue stream state doesn't match \
596 (%d != %d)", __func__, gsc->src_info.stream_on,
597 gsc->dst_info.stream_on);
598 ret = -1;
599 }
600
601 /*
602 * we need to plow forward on errors below to make sure that if we had
603 * turned on content protection on secure side, we turn it off.
604 *
605 * also, if we only failed to turn on one of the streams, we'll turn
606 * the other one off correctly.
607 */
608 if (gsc->src_info.stream_on == true) {
609 if (exynos_v4l2_streamoff(gsc->gsc_fd,
610 gsc->src_info.buf.buf_type) < 0) {
611 ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
612 ret = -1;
613 }
614 gsc->src_info.stream_on = false;
615 }
616
617 if (gsc->dst_info.stream_on == true) {
618 if (exynos_v4l2_streamoff(gsc->gsc_fd,
619 gsc->dst_info.buf.buf_type) < 0) {
620 ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
621 ret = -1;
622 }
623 gsc->dst_info.stream_on = false;
624 }
625
626 /* if drm is enabled */
627 if (gsc->allow_drm && gsc->protection_enabled) {
628 unsigned int protect_id = 0;
629
630 if (gsc->gsc_id == 0)
631 protect_id = CP_PROTECT_GSC0;
632 else if (gsc->gsc_id == 1)
633 protect_id = CP_PROTECT_GSC1;
634 else if (gsc->gsc_id == 2)
635 protect_id = CP_PROTECT_GSC2;
636 else if (gsc->gsc_id == 3)
637 protect_id = CP_PROTECT_GSC3;
638
639 /* CP_Disable_Path_Protection(protect_id); */
640 gsc->protection_enabled = false;
641 }
642
643 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
644 V4L2_CID_CONTENT_PROTECTION, 0) < 0) {
645 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
646 __func__);
647 ret = -1;
648 }
649
650 /* src: clear_buf */
651 req_buf.count = 0;
652 req_buf.type = gsc->src_info.buf.buf_type;
653 req_buf.memory = gsc->src_info.buf.mem_type;
654 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
655 ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
656 ret = -1;
657 }
658
659 /* dst: clear_buf */
660 req_buf.count = 0;
661 req_buf.type = gsc->dst_info.buf.buf_type;
662 req_buf.memory = gsc->dst_info.buf.mem_type;;
663 if (exynos_v4l2_reqbufs(gsc->gsc_fd, &req_buf) < 0) {
664 ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
665 ret = -1;
666 }
667
668 Exynos_gsc_Out();
669
670 return ret;
671}
672
673int CGscaler::m_gsc_m2m_run_core(void *handle)
674{
675 Exynos_gsc_In();
676
677 unsigned int rotate, hflip, vflip;
678 bool is_dirty;
679 bool is_drm;
680 CGscaler* gsc = GetGscaler(handle);
681 if (gsc == NULL) {
682 ALOGE("%s::handle == NULL() fail", __func__);
683 return -1;
684 }
685
686 is_dirty = gsc->src_info.dirty || gsc->dst_info.dirty;
687 is_drm = gsc->src_info.mode_drm;
688
689 if (is_dirty && (gsc->src_info.mode_drm != gsc->dst_info.mode_drm)) {
690 ALOGE("%s: drm mode mismatch between src and dst, \
691 gsc%d (s=%d d=%d)", __func__, gsc->gsc_id,
692 gsc->src_info.mode_drm, gsc->dst_info.mode_drm);
693 return -1;
694 } else if (is_drm && !gsc->allow_drm) {
695 ALOGE("%s: drm mode is not supported on gsc%d", __func__,
696 gsc->gsc_id);
697 return -1;
698 }
699
700 CGscaler::rotateValueHAL2GSC(gsc->dst_img.rot, &rotate, &hflip, &vflip);
701
702 if (CGscaler::m_gsc_check_src_size(&gsc->src_info.width,
703 &gsc->src_info.height, &gsc->src_info.crop_left,
704 &gsc->src_info.crop_top, &gsc->src_info.crop_width,
705 &gsc->src_info.crop_height, gsc->src_info.v4l2_colorformat,
706 (rotate == 90 || rotate == 270)) == false) {
707 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
708 return -1;
709 }
710
711 if (CGscaler::m_gsc_check_dst_size(&gsc->dst_info.width,
712 &gsc->dst_info.height, &gsc->dst_info.crop_left,
713 &gsc->dst_info.crop_top, &gsc->dst_info.crop_width,
714 &gsc->dst_info.crop_height, gsc->dst_info.v4l2_colorformat,
715 gsc->dst_info.rotation) == false) {
716 ALOGE("%s::m_gsc_check_dst_size() fail", __func__);
717 return -1;
718 }
719
720 /* dequeue buffers from previous work if necessary */
721 if (gsc->src_info.stream_on == true) {
722 if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
723 ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__);
724 return -1;
725 }
726 }
727
728 /*
729 * need to set the content protection flag before doing reqbufs
730 * in set_format
731 */
732 if (is_dirty && gsc->allow_drm && is_drm) {
733 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
734 V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) {
735 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
736 return -1;
737 }
738 }
739
740 /*
741 * from this point on, we have to ensure to call stop to clean up
742 * whatever state we have set.
743 */
744
745 if (gsc->src_info.dirty) {
746 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->src_info) == false) {
747 ALOGE("%s::m_gsc_set_format(src) fail", __func__);
748 goto done;
749 }
750 gsc->src_info.dirty = false;
751 }
752
753 if (gsc->dst_info.dirty) {
754 if (CGscaler::m_gsc_set_format(gsc->gsc_fd, &gsc->dst_info) == false) {
755 ALOGE("%s::m_gsc_set_format(dst) fail", __func__);
756 goto done;
757 }
758 gsc->dst_info.dirty = false;
759 }
760
761 /*
762 * set up csc equation property
763 */
764 if (is_dirty) {
765 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
766 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
767 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
768 return -1;
769 }
770
771 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
772 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
773 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
774 return -1;
775 }
776
777 if (exynos_v4l2_s_ctrl(gsc->gsc_fd,
778 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
779 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
780 return -1;
781 }
782 }
783
784 /* if we are enabling drm, make sure to enable hw protection.
785 * Need to do this before queuing buffers so that the mmu is reserved
786 * and power domain is kept on.
787 */
788 if (is_dirty && gsc->allow_drm && is_drm) {
789 unsigned int protect_id = 0;
790
791 if (gsc->gsc_id == 0) {
792 protect_id = CP_PROTECT_GSC0;
793 } else if (gsc->gsc_id == 1) {
794 protect_id = CP_PROTECT_GSC1;
795 } else if (gsc->gsc_id == 2) {
796 protect_id = CP_PROTECT_GSC2;
797 } else if (gsc->gsc_id == 3) {
798 protect_id = CP_PROTECT_GSC3;
799 } else {
800 ALOGE("%s::invalid gscaler id %d for content protection",
801 __func__, gsc->gsc_id);
802 goto done;
803 }
804
805 /* if (CP_Enable_Path_Protection(protect_id) != 0) {
806 ALOGE("%s::CP_Enable_Path_Protection failed", __func__);
807 goto done;
808 } */
809 gsc->protection_enabled = true;
810 }
811
812 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->src_info) == false) {
813 ALOGE("%s::m_gsc_set_addr(src) fail", __func__);
814 goto done;
815 }
816
817 if (gsc->m_gsc_set_addr(gsc->gsc_fd, &gsc->dst_info) == false) {
818 ALOGE("%s::m_gsc_set_addr(dst) fail", __func__);
819 goto done;
820 }
821
822 if (gsc->src_info.stream_on == false) {
823 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->src_info.buf.buf_type) < 0) {
824 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
825 goto done;
826 }
827 gsc->src_info.stream_on = true;
828 }
829
830 if (gsc->dst_info.stream_on == false) {
831 if (exynos_v4l2_streamon(gsc->gsc_fd, gsc->dst_info.buf.buf_type) < 0) {
832 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
833 goto done;
834 }
835 gsc->dst_info.stream_on = true;
836 }
837
838 Exynos_gsc_Out();
839
840 return 0;
841
842done:
843 gsc->m_gsc_m2m_stop(handle);
844 return -1;
845}
846
847bool CGscaler::m_gsc_check_src_size(
848 unsigned int *w, unsigned int *h,
849 unsigned int *crop_x, unsigned int *crop_y,
850 unsigned int *crop_w, unsigned int *crop_h,
851 int v4l2_colorformat, bool rotation)
852{
853 unsigned int minWidth, minHeight, shift = 0;
854 if (v4l2_colorformat == V4L2_PIX_FMT_RGB32 || v4l2_colorformat == V4L2_PIX_FMT_RGB565)
855 shift = 1;
856 if (rotation) {
857 minWidth = GSC_MIN_SRC_H_SIZE >> shift;
858 minHeight = GSC_MIN_SRC_W_SIZE >> shift;
859 } else {
860 minWidth = GSC_MIN_SRC_W_SIZE >> shift;
861 minHeight = GSC_MIN_SRC_H_SIZE >> shift;
862 }
863
864 if (*w < minWidth || *h < minHeight) {
865 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
866 __func__, GSC_MIN_SRC_W_SIZE, *w, GSC_MIN_SRC_H_SIZE, *h);
867 return false;
868 }
869
870 if (*crop_w < minWidth || *crop_h < minHeight) {
871 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
872 __func__, GSC_MIN_SRC_W_SIZE,* crop_w, GSC_MIN_SRC_H_SIZE, *crop_h);
873 return false;
874 }
875
876 return true;
877}
878
879bool CGscaler::m_gsc_check_dst_size(
880 unsigned int *w, unsigned int *h,
881 unsigned int *crop_x, unsigned int *crop_y,
882 unsigned int *crop_w, unsigned int *crop_h,
883 int v4l2_colorformat,
884 int rotation)
885{
886 if (*w < GSC_MIN_DST_W_SIZE || *h < GSC_MIN_DST_H_SIZE) {
887 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
888 __func__, GSC_MIN_DST_W_SIZE, *w, GSC_MIN_DST_H_SIZE, *h);
889 return false;
890 }
891
892 if (*crop_w < GSC_MIN_DST_W_SIZE || *crop_h < GSC_MIN_DST_H_SIZE) {
893 ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
894 __func__, GSC_MIN_DST_W_SIZE,* crop_w, GSC_MIN_DST_H_SIZE, *crop_h);
895 return false;
896 }
897
898 return true;
899}
900
901
902int CGscaler::m_gsc_multiple_of_n(int number, int N)
903{
904 int result = number;
905 switch (N) {
906 case 1:
907 case 2:
908 case 4:
909 case 8:
910 case 16:
911 case 32:
912 case 64:
913 case 128:
914 case 256:
915 result = (number - (number & (N-1)));
916 break;
917 default:
918 result = number - (number % N);
919 break;
920 }
921 return result;
922}
923
924int CGscaler::m_gsc_m2m_wait_frame_done(void *handle)
925{
926 Exynos_gsc_In();
927
928 CGscaler* gsc = GetGscaler(handle);
929 if (gsc == NULL) {
930 ALOGE("%s::handle == NULL() fail", __func__);
931 return -1;
932 }
933
934 if ((gsc->src_info.stream_on == false) ||
935 (gsc->dst_info.stream_on == false)) {
936 ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
937 return -1;
938 }
939
940 if (gsc->src_info.buf.buffer_queued) {
941 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->src_info.buf.buffer) < 0) {
942 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
943 return -1;
944 }
945 gsc->src_info.buf.buffer_queued = false;
946 }
947
948 if (gsc->dst_info.buf.buffer_queued) {
949 if (exynos_v4l2_dqbuf(gsc->gsc_fd, &gsc->dst_info.buf.buffer) < 0) {
950 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
951 return -1;
952 }
953 gsc->dst_info.buf.buffer_queued = false;
954 }
955
956 Exynos_gsc_Out();
957
958 return 0;
959}
960
961bool CGscaler::m_gsc_set_format(int fd, GscInfo *info)
962{
963 Exynos_gsc_In();
964
965 struct v4l2_requestbuffers req_buf;
966 int plane_count;
967
968 plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
969 if (plane_count < 0) {
970 ALOGE("%s::not supported v4l2_colorformat", __func__);
971 return false;
972 }
973
974 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
975 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
976 return false;
977 }
978
979 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
980 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
981 return false;
982 }
983
984 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
985 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
986 return false;
987 }
988
989 info->format.type = info->buf.buf_type;
990 info->format.fmt.pix_mp.width = info->width;
991 info->format.fmt.pix_mp.height = info->height;
992 info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
993 info->format.fmt.pix_mp.field = V4L2_FIELD_ANY;
994 info->format.fmt.pix_mp.num_planes = plane_count;
995
996 if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
997 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
998 return false;
999 }
1000
1001 info->crop.type = info->buf.buf_type;
1002 info->crop.c.left = info->crop_left;
1003 info->crop.c.top = info->crop_top;
1004 info->crop.c.width = info->crop_width;
1005 info->crop.c.height = info->crop_height;
1006
1007 if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
1008 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
1009 return false;
1010 }
1011
1012 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
1013 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
1014 return false;
1015 }
1016
1017 req_buf.count = 1;
1018 req_buf.type = info->buf.buf_type;
1019 req_buf.memory = info->buf.mem_type;
1020 if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
1021 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
1022 return false;
1023 }
1024
1025 Exynos_gsc_Out();
1026
1027 return true;
1028}
1029
1030unsigned int CGscaler::m_gsc_get_plane_count(int v4l_pixel_format)
1031{
1032 int plane_count = 0;
1033
1034 switch (v4l_pixel_format) {
1035 case V4L2_PIX_FMT_RGB32:
1036 case V4L2_PIX_FMT_BGR32:
1037 case V4L2_PIX_FMT_RGB24:
1038 case V4L2_PIX_FMT_RGB565:
1039 case V4L2_PIX_FMT_RGB555X:
1040 case V4L2_PIX_FMT_RGB444:
1041 case V4L2_PIX_FMT_YUYV:
1042 case V4L2_PIX_FMT_UYVY:
1043 case V4L2_PIX_FMT_NV16:
1044 case V4L2_PIX_FMT_NV61:
1045 case V4L2_PIX_FMT_YVU420:
1046 case V4L2_PIX_FMT_YUV420:
1047 case V4L2_PIX_FMT_NV12:
1048 case V4L2_PIX_FMT_NV21:
1049 case V4L2_PIX_FMT_YUV422P:
1050 plane_count = 1;
1051 break;
1052 case V4L2_PIX_FMT_NV12M:
1053 case V4L2_PIX_FMT_NV12MT_16X16:
1054 case V4L2_PIX_FMT_NV21M:
1055 plane_count = 2;
1056 break;
1057 case V4L2_PIX_FMT_YVU420M:
1058 case V4L2_PIX_FMT_YUV420M:
1059 plane_count = 3;
1060 break;
1061 default:
1062 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1063 __func__, v4l_pixel_format);
1064 plane_count = -1;
1065 break;
1066 }
1067
1068 return plane_count;
1069}
1070
1071bool CGscaler::m_gsc_set_addr(int fd, GscInfo *info)
1072{
1073 unsigned int i;
1074 unsigned int plane_size[NUM_OF_GSC_PLANES];
1075
1076 CGscaler::m_gsc_get_plane_size(plane_size, info->width,
1077 info->height, info->v4l2_colorformat);
1078
1079 info->buf.buffer.index = 0;
1080 info->buf.buffer.flags = V4L2_BUF_FLAG_USE_SYNC;
1081 info->buf.buffer.type = info->buf.buf_type;
1082 info->buf.buffer.memory = info->buf.mem_type;
1083 info->buf.buffer.m.planes = info->buf.planes;
1084 info->buf.buffer.length = info->format.fmt.pix_mp.num_planes;
1085 info->buf.buffer.reserved = info->acquireFenceFd;
1086
1087 for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
1088 if (info->buf.buffer.memory == V4L2_MEMORY_DMABUF)
1089 info->buf.buffer.m.planes[i].m.fd = (long)info->buf.addr[i];
1090 else
1091 info->buf.buffer.m.planes[i].m.userptr =
1092 (unsigned long)info->buf.addr[i];
1093 info->buf.buffer.m.planes[i].length = plane_size[i];
1094 info->buf.buffer.m.planes[i].bytesused = 0;
1095 }
1096
1097 if (exynos_v4l2_qbuf(fd, &info->buf.buffer) < 0) {
1098 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
1099 return false;
1100 }
1101 info->buf.buffer_queued = true;
1102
1103 info->releaseFenceFd = info->buf.buffer.reserved;
1104
1105 return true;
1106}
1107
1108unsigned int CGscaler::m_gsc_get_plane_size(
1109 unsigned int *plane_size,
1110 unsigned int width,
1111 unsigned int height,
1112 int v4l_pixel_format)
1113{
1114 switch (v4l_pixel_format) {
1115 /* 1 plane */
1116 case V4L2_PIX_FMT_RGB32:
1117 case V4L2_PIX_FMT_BGR32:
1118 plane_size[0] = width * height * 4;
1119 plane_size[1] = 0;
1120 plane_size[2] = 0;
1121 break;
1122 case V4L2_PIX_FMT_RGB24:
1123 plane_size[0] = width * height * 3;
1124 plane_size[1] = 0;
1125 plane_size[2] = 0;
1126 break;
1127 case V4L2_PIX_FMT_RGB565:
1128 case V4L2_PIX_FMT_RGB555X:
1129 case V4L2_PIX_FMT_RGB444:
1130 case V4L2_PIX_FMT_YUYV:
1131 case V4L2_PIX_FMT_UYVY:
1132 plane_size[0] = width * height * 2;
1133 plane_size[1] = 0;
1134 plane_size[2] = 0;
1135 break;
1136 /* 2 planes */
1137 case V4L2_PIX_FMT_NV12M:
1138 case V4L2_PIX_FMT_NV21M:
1139 plane_size[0] = width * height;
1140 plane_size[1] = width * (height / 2);
1141 plane_size[2] = 0;
1142 break;
1143 case V4L2_PIX_FMT_NV12:
1144 case V4L2_PIX_FMT_NV21:
1145 plane_size[0] = width * height * 3 / 2;
1146 plane_size[1] = 0;
1147 plane_size[2] = 0;
1148 break;
1149 case V4L2_PIX_FMT_NV16:
1150 case V4L2_PIX_FMT_NV61:
1151 case V4L2_PIX_FMT_YUV422P:
1152 plane_size[0] = width * height * 2;
1153 plane_size[1] = 0;
1154 plane_size[2] = 0;
1155 break;
1156 case V4L2_PIX_FMT_NV12MT_16X16:
1157 plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
1158 plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
1159 plane_size[2] = 0;
1160 break;
1161 /* 3 planes */
1162 case V4L2_PIX_FMT_YUV420M:
1163 plane_size[0] = width * height;
1164 plane_size[1] = (width / 2) * (height / 2);
1165 plane_size[2] = (width / 2) * (height / 2);
1166 break;
1167 case V4L2_PIX_FMT_YVU420:
1168 plane_size[0] = ALIGN(width, 16) * height + ALIGN(width / 2, 16) * height;
1169 plane_size[1] = 0;
1170 plane_size[2] = 0;
1171 break;
1172 case V4L2_PIX_FMT_YUV420:
1173 plane_size[0] = width * height * 3 / 2;
1174 plane_size[1] = 0;
1175 plane_size[2] = 0;
1176 break;
1177 case V4L2_PIX_FMT_YVU420M:
1178 plane_size[0] = ALIGN(width, 16) * height;
1179 plane_size[1] = ALIGN(width / 2, 16) * (height / 2);
1180 plane_size[2] = plane_size[1];
1181 break;
1182 default:
1183 ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
1184 __func__, v4l_pixel_format);
1185 return -1;
1186 }
1187
1188 return 0;
1189}
1190
1191int CGscaler::m_gsc_m2m_config(void *handle,
1192 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1193{
1194 Exynos_gsc_In();
1195
1196 int32_t src_color_space;
1197 int32_t dst_color_space;
1198 int ret;
1199 unsigned int rotate;
1200 unsigned int hflip;
1201 unsigned int vflip;
1202 CGscaler* gsc = GetGscaler(handle);
1203 if (gsc == NULL) {
1204 ALOGE("%s::handle == NULL() fail", __func__);
1205 return -1;
1206 }
1207
1208 if ((src_img->drmMode && !gsc->allow_drm) ||
1209 (src_img->drmMode != dst_img->drmMode)) {
1210 ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)",
1211 __func__, gsc->gsc_id, src_img->drmMode, dst_img->drmMode);
1212 return -1;
1213 }
1214
1215 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1216 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1217 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1218 exynos_gsc_set_rotation(gsc, rotate, hflip, vflip);
1219
1220 ret = exynos_gsc_set_src_format(gsc, src_img->fw, src_img->fh,
1221 src_img->x, src_img->y, src_img->w, src_img->h,
1222 src_color_space, src_img->cacheable, src_img->drmMode);
1223 if (ret < 0) {
1224 ALOGE("%s: fail: exynos_gsc_set_src_format \
1225 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1226 __func__, src_img->fw, src_img->fh, src_img->x, src_img->y,
1227 src_img->w, src_img->h, src_color_space, src_img->rot);
1228 return -1;
1229 }
1230
1231 ret = exynos_gsc_set_dst_format(gsc, dst_img->fw, dst_img->fh,
1232 dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1233 dst_color_space, dst_img->cacheable, dst_img->drmMode);
1234 if (ret < 0) {
1235 ALOGE("%s: fail: exynos_gsc_set_dst_format \
1236 [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1237 __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y,
1238 dst_img->w, dst_img->h, src_color_space, dst_img->rot);
1239 return -1;
1240 }
1241
1242 Exynos_gsc_Out();
1243
1244 return 0;
1245}
1246
1247int CGscaler::m_gsc_out_config(void *handle,
1248 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1249{
1250 Exynos_gsc_In();
1251
1252 struct v4l2_format fmt;
1253 struct v4l2_crop crop;
1254 struct v4l2_requestbuffers reqbuf;
1255 struct v4l2_subdev_format sd_fmt;
1256 struct v4l2_subdev_crop sd_crop;
1257 int i;
1258 unsigned int rotate;
1259 unsigned int hflip;
1260 unsigned int vflip;
1261 unsigned int plane_size[NUM_OF_GSC_PLANES];
1262 bool rgb;
1263
1264 struct v4l2_rect dst_rect;
1265 int32_t src_color_space;
1266 int32_t dst_color_space;
1267 int32_t src_planes;
1268
1269 CGscaler* gsc = GetGscaler(handle);
1270 if (gsc == NULL) {
1271 ALOGE("%s::handle == NULL() fail", __func__);
1272 return -1;
1273 }
1274
1275 if (gsc->src_info.stream_on != false) {
1276 ALOGE("Error: Src is already streamed on !!!!");
1277 return -1;
1278 }
1279
1280 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1281 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1282 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1283 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1284 src_planes = m_gsc_get_plane_count(src_color_space);
1285 src_planes = (src_planes == -1) ? 1 : src_planes;
1286 rgb = get_yuv_planes(dst_color_space) == -1;
1287 CGscaler::rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1288
1289 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1290 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1291 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1292 (rotate == 90 || rotate == 270)) == false) {
1293 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1294 return -1;
1295 }
1296
1297 /*set: src v4l2_buffer*/
1298 gsc->src_info.buf.buf_idx = 0;
1299 gsc->src_info.qbuf_cnt = 0;
1300 /* set format: src pad of GSC sub-dev*/
1301 sd_fmt.pad = GSCALER_SUBDEV_PAD_SOURCE;
1302 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1303 if (gsc->out_mode == GSC_OUT_FIMD) {
1304 sd_fmt.format.width = gsc->dst_img.fw;
1305 sd_fmt.format.height = gsc->dst_img.fh;
1306 } else {
1307 sd_fmt.format.width = gsc->dst_img.w;
1308 sd_fmt.format.height = gsc->dst_img.h;
1309 }
1310 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1311 V4L2_MBUS_FMT_YUV8_1X24;
1312 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1313 ALOGE("%s::GSC subdev set format failed", __func__);
1314 return -1;
1315 }
1316
1317 /* set crop: src crop of GSC sub-dev*/
1318 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE;
1319 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1320 if (gsc->out_mode == GSC_OUT_FIMD) {
1321 sd_crop.rect.left = gsc->dst_img.x;
1322 sd_crop.rect.top = gsc->dst_img.y;
1323 sd_crop.rect.width = gsc->dst_img.w;
1324 sd_crop.rect.height = gsc->dst_img.h;
1325 } else {
1326 sd_crop.rect.left = 0;
1327 sd_crop.rect.top = 0;
1328 sd_crop.rect.width = gsc->dst_img.w;
1329 sd_crop.rect.height = gsc->dst_img.h;
1330 }
1331
1332 /* sink pad is connected to GSC out */
1333 /* set format: sink sub-dev */
1334 if (gsc->out_mode == GSC_OUT_FIMD) {
1335 sd_fmt.pad = FIMD_SUBDEV_PAD_SINK;
1336 sd_fmt.format.width = gsc->dst_img.w;
1337 sd_fmt.format.height = gsc->dst_img.h;
1338 } else {
1339 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SINK;
1340 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1341 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1342 }
1343
1344 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1345 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1346 V4L2_MBUS_FMT_YUV8_1X24;
1347 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1348 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1349 sd_fmt.pad);
1350 return -1;
1351 }
1352
1353 /* set crop: sink sub-dev */
1354 if (gsc->out_mode == GSC_OUT_FIMD)
1355 sd_crop.pad = FIMD_SUBDEV_PAD_SINK;
1356 else
1357 sd_crop.pad = MIXER_V_SUBDEV_PAD_SINK;
1358
1359 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1360 if (gsc->out_mode == GSC_OUT_FIMD) {
1361 sd_crop.rect.left = gsc->dst_img.x;
1362 sd_crop.rect.top = gsc->dst_img.y;
1363 sd_crop.rect.width = gsc->dst_img.w;
1364 sd_crop.rect.height = gsc->dst_img.h;
1365 } else {
1366 sd_crop.rect.left = 0;
1367 sd_crop.rect.top = 0;
1368 sd_crop.rect.width = gsc->dst_img.w;
1369 sd_crop.rect.height = gsc->dst_img.h;
1370 }
1371
1372 if (gsc->out_mode != GSC_OUT_FIMD) {
1373 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1374 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1375 sd_fmt.format.width = gsc->dst_img.w + gsc->dst_img.x*2;
1376 sd_fmt.format.height = gsc->dst_img.h + gsc->dst_img.y*2;
1377 sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
1378 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1379 ALOGE("%s::sink:set format failed (PAD=%d)", __func__,
1380 sd_fmt.pad);
1381 return -1;
1382 }
1383
1384 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE;
1385 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1386 sd_crop.rect.left = gsc->dst_img.x;
1387 sd_crop.rect.top = gsc->dst_img.y;
1388 sd_crop.rect.width = gsc->dst_img.w;
1389 sd_crop.rect.height = gsc->dst_img.h;
1390 if (exynos_subdev_s_crop(gsc->mdev.sink_sd_entity->fd, &sd_crop) < 0) {
1391 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__,
1392 sd_crop.pad);
1393 return -1;
1394 }
1395 }
1396
1397 /*set GSC ctrls */
1398 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1399 rotate) < 0) {
1400 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1401 __func__, rotate);
1402 return -1;
1403 }
1404
1405 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1406 vflip) < 0) {
1407 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1408 __func__, vflip);
1409 return -1;
1410 }
1411
1412 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1413 hflip) < 0) {
1414 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1415 __func__, hflip);
1416 return -1;
1417 }
1418
1419 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1420 V4L2_CID_CACHEABLE, 1) < 0) {
1421 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1422 __func__);
1423 return -1;
1424 }
1425
1426 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1427 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1428 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1429 __func__);
1430 return -1;
1431 }
1432
1433 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1434 V4L2_CID_CSC_EQ_MODE, gsc->eq_auto) < 0) {
1435 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ_MODE) fail", __func__);
1436 return -1;
1437 }
1438
1439 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1440 V4L2_CID_CSC_EQ, gsc->v4l2_colorspace) < 0) {
1441 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_EQ) fail", __func__);
1442 return -1;
1443 }
1444
1445 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1446 V4L2_CID_CSC_RANGE, gsc->range_full) < 0) {
1447 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
1448 return -1;
1449 }
1450
1451 /* set src format :GSC video dev*/
1452 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1453 fmt.fmt.pix_mp.width = gsc->src_img.fw;
1454 fmt.fmt.pix_mp.height = gsc->src_img.fh;
1455 fmt.fmt.pix_mp.pixelformat = src_color_space;
1456 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1457 fmt.fmt.pix_mp.num_planes = src_planes;
1458
1459 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1460 ALOGE("%s::videodev set format failed", __func__);
1461 return -1;
1462 }
1463
1464 /* set src crop info :GSC video dev*/
1465 crop.type = fmt.type;
1466 crop.c.left = gsc->src_img.x;
1467 crop.c.top = gsc->src_img.y;
1468 crop.c.width = gsc->src_img.w;
1469 crop.c.height = gsc->src_img.h;
1470
1471 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1472 ALOGE("%s::videodev set crop failed", __func__);
1473 return -1;
1474 }
1475
1476 reqbuf.type = fmt.type;
1477 reqbuf.memory = V4L2_MEMORY_DMABUF;
1478 reqbuf.count = MAX_BUFFERS_GSCALER_OUT;
1479
1480 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1481 ALOGE("%s::request buffers failed", __func__);
1482 return -1;
1483 }
1484
1485 Exynos_gsc_Out();
1486
1487 return 0;
1488}
1489
1490int CGscaler::m_gsc_cap_config(void *handle,
1491 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1492{
1493 Exynos_gsc_In();
1494
1495 struct v4l2_format fmt;
1496 struct v4l2_crop crop;
1497 struct v4l2_requestbuffers reqbuf;
1498 struct v4l2_subdev_format sd_fmt;
1499 struct v4l2_subdev_crop sd_crop;
1500 int i;
1501 unsigned int rotate;
1502 unsigned int hflip;
1503 unsigned int vflip;
1504 unsigned int plane_size[NUM_OF_GSC_PLANES];
1505 bool rgb;
1506
1507 struct v4l2_rect dst_rect;
1508 int32_t src_color_space;
1509 int32_t dst_color_space;
1510 int32_t dst_planes;
1511
1512 CGscaler* gsc = GetGscaler(handle);
1513 if (gsc == NULL) {
1514 ALOGE("%s::handle == NULL() fail", __func__);
1515 return -1;
1516 }
1517
1518 memcpy(&gsc->src_img, src_img, sizeof(exynos_mpp_img));
1519 memcpy(&gsc->dst_img, dst_img, sizeof(exynos_mpp_img));
1520 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1521 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1522 dst_planes = m_gsc_get_plane_count(dst_color_space);
1523 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1524 rgb = get_yuv_planes(src_color_space) == -1;
1525 CGscaler::rotateValueHAL2GSC(src_img->rot, &rotate, &hflip, &vflip);
1526
1527 if (CGscaler::m_gsc_check_src_size(&gsc->src_img.fw,
1528 &gsc->src_img.fh, &gsc->src_img.x, &gsc->src_img.y,
1529 &gsc->src_img.w, &gsc->src_img.h, src_color_space,
1530 (rotate == 90 || rotate == 270)) == false) {
1531 ALOGE("%s::m_gsc_check_src_size() fail", __func__);
1532 return -1;
1533 }
1534
1535 /*set GSC ctrls */
1536 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_ROTATE,
1537 rotate) < 0) {
1538 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed",
1539 __func__, rotate);
1540 return -1;
1541 }
1542 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_HFLIP,
1543 vflip) < 0) {
1544 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed",
1545 __func__, vflip);
1546 return -1;
1547 }
1548 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd, V4L2_CID_VFLIP,
1549 hflip) < 0) {
1550 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed",
1551 __func__, hflip);
1552 return -1;
1553 }
1554 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1555 V4L2_CID_CACHEABLE, 1) < 0) {
1556 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed",
1557 __func__);
1558 return -1;
1559 }
1560 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1561 V4L2_CID_CONTENT_PROTECTION, gsc->src_img.drmMode) < 0) {
1562 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
1563 __func__);
1564 return -1;
1565 }
1566 if (exynos_v4l2_s_ctrl(gsc->mdev.gsc_vd_entity->fd,
1567 V4L2_CID_CSC_RANGE, gsc->range_full)) {
1568 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail",
1569 __func__, gsc->range_full);
1570 return -1;
1571 }
1572 /* set format: source pad of Decon-TV sub-dev*/
1573 sd_fmt.pad = DECON_TV_WB_PAD;
1574 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1575 sd_fmt.format.width = gsc->src_img.w;
1576 sd_fmt.format.height = gsc->src_img.h;
1577 sd_fmt.format.code = WB_PATH_FORMAT;
1578 if (exynos_subdev_s_fmt(gsc->mdev.sink_sd_entity->fd, &sd_fmt) < 0) {
1579 ALOGE("%s::Decon-TV subdev set format failed", __func__);
1580 return -1;
1581 }
1582
1583 if (!gsc->dst_info.stream_on) {
1584 /* set src format: GSC video dev*/
1585 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1586 fmt.fmt.pix_mp.width = gsc->dst_img.fw;
1587 fmt.fmt.pix_mp.height = gsc->dst_img.fh;
1588 fmt.fmt.pix_mp.pixelformat = dst_color_space;
1589 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1590 fmt.fmt.pix_mp.num_planes = dst_planes;
1591
1592 if (exynos_v4l2_s_fmt(gsc->mdev.gsc_vd_entity->fd, &fmt) < 0) {
1593 ALOGE("%s::videodev set format failed", __func__);
1594 return -1;
1595 }
1596 gsc->dst_info.buf.buf_idx = 0;
1597 gsc->dst_info.qbuf_cnt = 0;
1598 }
1599
1600 /* set format: sink pad of GSC sub-dev*/
1601 sd_fmt.pad = GSCALER_SUBDEV_PAD_SINK;
1602 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1603 sd_fmt.format.width = gsc->src_img.w;
1604 sd_fmt.format.height = gsc->src_img.h;
1605 sd_fmt.format.code = WB_PATH_FORMAT;
1606 if (exynos_subdev_s_fmt(gsc->mdev.gsc_sd_entity->fd, &sd_fmt) < 0) {
1607 ALOGE("%s::GSC subdev set format failed", __func__);
1608 return -1;
1609 }
1610
1611 /* set src crop info :GSC video dev*/
1612 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1613 crop.c.left = gsc->dst_img.x;
1614 crop.c.top = gsc->dst_img.y;
1615 crop.c.width = gsc->dst_img.w;
1616 crop.c.height = gsc->dst_img.h;
1617 if (exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop) < 0) {
1618 ALOGE("%s::videodev set crop failed", __func__);
1619 return -1;
1620 }
1621
1622 /* set crop: src crop of GSC sub-dev*/
1623 sd_crop.pad = GSCALER_SUBDEV_PAD_SINK;
1624 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1625 sd_crop.rect.left = 0;
1626 sd_crop.rect.top = 0;
1627 sd_crop.rect.width = gsc->src_img.w;
1628 sd_crop.rect.height = gsc->src_img.h;
1629
1630 if (exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop) < 0) {
1631 ALOGE("%s::GSC subdev set crop failed(PAD=%d)", __func__,
1632 sd_crop.pad);
1633 return -1;
1634 }
1635 reqbuf.type = fmt.type;
1636 reqbuf.memory = V4L2_MEMORY_DMABUF;
1637 reqbuf.count = MAX_BUFFERS_GSCALER_CAP;
1638
1639 if (!gsc->dst_info.stream_on) {
1640 if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
1641 ALOGE("%s::request buffers failed", __func__);
1642 return -1;
1643 }
1644 }
1645
1646 Exynos_gsc_Out();
1647
1648 return 0;
1649}
1650
1651
1652void CGscaler::rotateValueHAL2GSC(unsigned int transform,
1653 unsigned int *rotate, unsigned int *hflip, unsigned int *vflip)
1654{
1655 int rotate_flag = transform & 0x7;
1656 *rotate = 0;
1657 *hflip = 0;
1658 *vflip = 0;
1659
1660 switch (rotate_flag) {
1661 case HAL_TRANSFORM_ROT_90:
1662 *rotate = 90;
1663 break;
1664 case HAL_TRANSFORM_ROT_180:
1665 *rotate = 180;
1666 break;
1667 case HAL_TRANSFORM_ROT_270:
1668 *rotate = 270;
1669 break;
1670 case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
1671 *rotate = 90;
1672 *vflip = 1; /* set vflip to compensate the rot & flip order. */
1673 break;
1674 case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
1675 *rotate = 90;
1676 *hflip = 1; /* set hflip to compensate the rot & flip order. */
1677 break;
1678 case HAL_TRANSFORM_FLIP_H:
1679 *hflip = 1;
1680 break;
1681 case HAL_TRANSFORM_FLIP_V:
1682 *vflip = 1;
1683 break;
1684 default:
1685 break;
1686 }
1687}
1688
1689int CGscaler::m_gsc_m2m_run(void *handle,
1690 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
1691{
1692 Exynos_gsc_In();
1693
1694 CGscaler* gsc = GetGscaler(handle);
1695 if (gsc == NULL) {
1696 ALOGE("%s::handle == NULL() fail", __func__);
1697 return -1;
1698 }
1699 void *addr[3] = {NULL, NULL, NULL};
1700 int ret = 0;
1701
1702 addr[0] = (void *)src_img->yaddr;
1703 addr[1] = (void *)src_img->uaddr;
1704 addr[2] = (void *)src_img->vaddr;
1705 ret = exynos_gsc_set_src_addr(handle, addr, src_img->mem_type,
1706 src_img->acquireFenceFd);
1707 if (ret < 0) {
1708 ALOGE("%s::fail: exynos_gsc_set_src_addr[%p %p %p]", __func__,
1709 addr[0], addr[1], addr[2]);
1710 return -1;
1711 }
1712
1713 addr[0] = (void *)dst_img->yaddr;
1714 addr[1] = (void *)dst_img->uaddr;
1715 addr[2] = (void *)dst_img->vaddr;
1716 ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->mem_type,
1717 dst_img->acquireFenceFd);
1718 if (ret < 0) {
1719 ALOGE("%s::fail: exynos_gsc_set_dst_addr[%p %p %p]", __func__,
1720 addr[0], addr[1], addr[2]);
1721 return -1;
1722 }
1723
1724 ret = gsc->m_gsc_m2m_run_core(handle);
1725 if (ret < 0) {
1726 ALOGE("%s::fail: m_gsc_m2m_run_core", __func__);
1727 return -1;
1728 }
1729
1730 if (src_img->acquireFenceFd >= 0) {
1731 close(src_img->acquireFenceFd);
1732 src_img->acquireFenceFd = -1;
1733 }
1734
1735 if (dst_img->acquireFenceFd >= 0) {
1736 close(dst_img->acquireFenceFd);
1737 dst_img->acquireFenceFd = -1;
1738 }
1739
1740 src_img->releaseFenceFd = gsc->src_info.releaseFenceFd;
1741 dst_img->releaseFenceFd = gsc->dst_info.releaseFenceFd;
1742
1743 Exynos_gsc_Out();
1744
1745 return 0;
1746}
1747
1748int CGscaler::m_gsc_out_run(void *handle, exynos_mpp_img *src_img)
1749{
1750 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1751 struct v4l2_buffer buf;
1752 int32_t src_color_space;
1753 int32_t src_planes;
1754 unsigned int i;
1755 unsigned int plane_size[NUM_OF_GSC_PLANES];
1756 int ret = 0;
1757 unsigned int dq_retry_cnt = 0;
1758
1759 CGscaler* gsc = GetGscaler(handle);
1760 if (gsc == NULL) {
1761 ALOGE("%s::handle == NULL() fail", __func__);
1762 return -1;
1763 }
1764
1765 /* All buffers have been queued, dequeue one */
1766 if (gsc->src_info.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) {
1767 memset(&buf, 0, sizeof(struct v4l2_buffer));
1768 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1769 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1770
1771 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1772 buf.memory = V4L2_MEMORY_DMABUF;
1773 buf.m.planes = planes;
1774
1775 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1776 src_planes = m_gsc_get_plane_count(src_color_space);
1777 src_planes = (src_planes == -1) ? 1 : src_planes;
1778 buf.length = src_planes;
1779
1780
1781 do {
1782 ret = exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf);
1783 if (ret == -EAGAIN) {
1784 ALOGE("%s::Retry DQbuf(index=%d)", __func__, buf.index);
1785 usleep(10000);
1786 dq_retry_cnt++;
1787 continue;
1788 }
1789 break;
1790 } while (dq_retry_cnt <= 10);
1791
1792 if (ret < 0) {
1793 ALOGE("%s::dq buffer failed (index=%d)", __func__, buf.index);
1794 return -1;
1795 }
1796 gsc->src_info.qbuf_cnt--;
1797 }
1798
1799 memset(&buf, 0, sizeof(struct v4l2_buffer));
1800 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1801 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1802
1803 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->src_img.format);
1804 src_planes = m_gsc_get_plane_count(src_color_space);
1805 src_planes = (src_planes == -1) ? 1 : src_planes;
1806
1807 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1808 buf.memory = V4L2_MEMORY_DMABUF;
1809 buf.flags = 0;
1810 buf.length = src_planes;
1811 buf.index = gsc->src_info.buf.buf_idx;
1812 buf.m.planes = planes;
1813 buf.reserved = -1;
1814
1815 gsc->src_info.buf.addr[0] = (void*)src_img->yaddr;
1816 gsc->src_info.buf.addr[1] = (void*)src_img->uaddr;
1817 gsc->src_info.buf.addr[2] = (void*)src_img->vaddr;
1818
1819 if (CGscaler::tmp_get_plane_size(src_color_space, plane_size,
1820 gsc->src_img.fw, gsc->src_img.fh, src_planes) != true) {
1821 ALOGE("%s:get_plane_size:fail", __func__);
1822 return -1;
1823 }
1824
1825 for (i = 0; i < buf.length; i++) {
1826 buf.m.planes[i].m.fd = (long)gsc->src_info.buf.addr[i];
1827 buf.m.planes[i].length = plane_size[i];
1828 buf.m.planes[i].bytesused = plane_size[i];
1829 }
1830
1831 /* Queue the buf */
1832 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1833 ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)",
1834 __func__, gsc->src_info.buf.buf_idx,
1835 MAX_BUFFERS_GSCALER_OUT);
1836 return -1;
1837 }
1838 gsc->src_info.buf.buf_idx++;
1839 gsc->src_info.buf.buf_idx =
1840 gsc->src_info.buf.buf_idx % MAX_BUFFERS_GSCALER_OUT;
1841 gsc->src_info.qbuf_cnt++;
1842
1843 if (gsc->src_info.stream_on == false) {
1844 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1845 (v4l2_buf_type)buf.type) < 0) {
1846 ALOGE("%s::stream on failed", __func__);
1847 return -1;
1848 }
1849 gsc->src_info.stream_on = true;
1850 }
1851
1852 return 0;
1853}
1854
1855int CGscaler::m_gsc_cap_run(void *handle, exynos_mpp_img *dst_img)
1856{
1857 struct v4l2_plane planes[NUM_OF_GSC_PLANES];
1858 struct v4l2_buffer buf;
1859 int32_t dst_color_space;
1860 int32_t dst_planes;
1861 unsigned int i;
1862 unsigned int plane_size[NUM_OF_GSC_PLANES];
1863 CGscaler* gsc = GetGscaler(handle);
1864 if (gsc == NULL) {
1865 ALOGE("%s::handle == NULL() fail", __func__);
1866 return -1;
1867 }
1868
1869 /* All buffers have been queued, dequeue one */
1870 if (gsc->dst_info.qbuf_cnt == MAX_BUFFERS_GSCALER_CAP) {
1871 memset(&buf, 0, sizeof(struct v4l2_buffer));
1872 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1873 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1874
1875 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1876 buf.memory = V4L2_MEMORY_DMABUF;
1877 buf.m.planes = planes;
1878
1879 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1880 dst_planes = m_gsc_get_plane_count(dst_color_space);
1881 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1882 buf.length = dst_planes;
1883
1884
1885 if (exynos_v4l2_dqbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1886 ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)",
1887 __func__, gsc->src_info.buf.buf_idx,
1888 MAX_BUFFERS_GSCALER_CAP);
1889 return -1;
1890 }
1891 gsc->dst_info.qbuf_cnt--;
1892 }
1893
1894 memset(&buf, 0, sizeof(struct v4l2_buffer));
1895 for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1896 memset(&planes[i], 0, sizeof(struct v4l2_plane));
1897
1898 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc->dst_img.format);
1899 dst_planes = m_gsc_get_plane_count(dst_color_space);
1900 dst_planes = (dst_planes == -1) ? 1 : dst_planes;
1901
1902 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1903 buf.memory = V4L2_MEMORY_DMABUF;
1904 buf.flags = V4L2_BUF_FLAG_USE_SYNC;
1905 buf.length = dst_planes;
1906 buf.index = gsc->dst_info.buf.buf_idx;
1907 buf.m.planes = planes;
1908 buf.reserved = dst_img->acquireFenceFd;
1909
1910 gsc->dst_info.buf.addr[0] = (void*)dst_img->yaddr;
1911 gsc->dst_info.buf.addr[1] = (void*)dst_img->uaddr;
1912 gsc->dst_info.buf.addr[2] = (void*)dst_img->vaddr;
1913
1914 if (CGscaler::tmp_get_plane_size(dst_color_space, plane_size,
1915 gsc->dst_img.fw, gsc->dst_img.fh, dst_planes) != true) {
1916 ALOGE("%s:get_plane_size:fail", __func__);
1917 return -1;
1918 }
1919
1920 for (i = 0; i < buf.length; i++) {
1921 buf.m.planes[i].m.fd = (int)(long)gsc->dst_info.buf.addr[i];
1922 buf.m.planes[i].length = plane_size[i];
1923 buf.m.planes[i].bytesused = plane_size[i];
1924 }
1925
1926 /* Queue the buf */
1927 if (exynos_v4l2_qbuf(gsc->mdev.gsc_vd_entity->fd, &buf) < 0) {
1928 ALOGE("%s::queue buffer failed (index=%d)(mDstBufNum=%d)",
1929 __func__, gsc->dst_info.buf.buf_idx,
1930 MAX_BUFFERS_GSCALER_CAP);
1931 return -1;
1932 }
1933
1934 gsc->dst_info.buf.buf_idx++;
1935 gsc->dst_info.buf.buf_idx =
1936 gsc->dst_info.buf.buf_idx % MAX_BUFFERS_GSCALER_CAP;
1937 gsc->dst_info.qbuf_cnt++;
1938
1939 if (gsc->dst_info.stream_on == false) {
1940 if (exynos_v4l2_streamon(gsc->mdev.gsc_vd_entity->fd,
1941 (v4l2_buf_type)buf.type) < 0) {
1942 ALOGE("%s::stream on failed", __func__);
1943 return -1;
1944 }
1945 gsc->dst_info.stream_on = true;
1946 }
1947
1948 dst_img->releaseFenceFd = buf.reserved;
1949 return 0;
1950}
1951
1952bool CGscaler::tmp_get_plane_size(int V4L2_PIX,
1953 unsigned int * size, unsigned int width, unsigned int height, int src_planes)
1954{
1955 unsigned int frame_ratio = 1;
1956 int src_bpp = get_yuv_bpp(V4L2_PIX);
1957 unsigned int frame_size = width * height;
1958
1959 src_planes = (src_planes == -1) ? 1 : src_planes;
1960 frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
1961
1962 switch (src_planes) {
1963 case 1:
1964 switch (V4L2_PIX) {
1965 case V4L2_PIX_FMT_BGR32:
1966 case V4L2_PIX_FMT_RGB32:
1967 size[0] = frame_size << 2;
1968 break;
1969 case V4L2_PIX_FMT_RGB565:
1970 case V4L2_PIX_FMT_NV16:
1971 case V4L2_PIX_FMT_NV61:
1972 case V4L2_PIX_FMT_YUYV:
1973 case V4L2_PIX_FMT_UYVY:
1974 case V4L2_PIX_FMT_VYUY:
1975 case V4L2_PIX_FMT_YVYU:
1976 size[0] = frame_size << 1;
1977 break;
1978 case V4L2_PIX_FMT_YUV420:
1979 case V4L2_PIX_FMT_NV12:
1980 case V4L2_PIX_FMT_NV21:
1981 case V4L2_PIX_FMT_NV21M:
1982 size[0] = (frame_size * 3) >> 1;
1983 break;
1984 case V4L2_PIX_FMT_YVU420:
1985 size[0] = frame_size + (ALIGN((width >> 1), 16) * ((height >> 1) * 2));
1986 break;
1987 default:
1988 ALOGE("%s::invalid color type (%x)", __func__, V4L2_PIX);
1989 return false;
1990 break;
1991 }
1992 size[1] = 0;
1993 size[2] = 0;
1994 break;
1995 case 2:
1996 size[0] = frame_size;
1997 size[1] = frame_size / frame_ratio;
1998 size[2] = 0;
1999 break;
2000 case 3:
2001 size[0] = frame_size;
2002 size[1] = frame_size / frame_ratio;
2003 size[2] = frame_size / frame_ratio;
2004 break;
2005 default:
2006 ALOGE("%s::invalid color foarmt", __func__);
2007 return false;
2008 break;
2009 }
2010
2011 return true;
2012}
2013
2014int CGscaler::ConfigMpp(void *handle, exynos_mpp_img *src,
2015 exynos_mpp_img *dst)
2016{
2017 return exynos_gsc_config_exclusive(handle, src, dst);
2018}
2019
2020int CGscaler::ConfigBlendMpp(void *handle, exynos_mpp_img *src,
2021 exynos_mpp_img *dst,
2022 SrcBlendInfo *srcblendinfo)
2023{
2024 return exynos_gsc_config_blend_exclusive(handle, src, dst, srcblendinfo);
2025}
2026
2027int CGscaler::RunMpp(void *handle, exynos_mpp_img *src,
2028 exynos_mpp_img *dst)
2029{
2030 return exynos_gsc_run_exclusive(handle, src, dst);
2031}
2032
2033int CGscaler::StopMpp(void *handle)
2034{
2035 return exynos_gsc_stop_exclusive(handle);
2036}
2037
2038void CGscaler::DestroyMpp(void *handle)
2039{
2040 return exynos_gsc_destroy(handle);
2041}
2042
2043int CGscaler::SetCSCProperty(void *handle, unsigned int eqAuto,
2044 unsigned int fullRange, unsigned int colorspace)
2045{
2046 return exynos_gsc_set_csc_property(handle, eqAuto, fullRange,
2047 colorspace);
2048}
2049
2050int CGscaler::FreeMpp(void *handle)
2051{
2052 return exynos_gsc_free_and_close(handle);
2053}
2054
2055int CGscaler::SetInputCrop(void *handle,
2056 exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
2057{
2058 struct v4l2_crop crop;
2059 int ret = 0;
2060 CGscaler *gsc = GetGscaler(handle);
2061 if (gsc == NULL) {
2062 ALOGE("%s::handle == NULL() fail", __func__);
2063 return -1;
2064 }
2065
2066 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2067 crop.c.left = src_img->x;
2068 crop.c.top = src_img->y;
2069 crop.c.width = src_img->w;
2070 crop.c.height = src_img->h;
2071
2072 return exynos_v4l2_s_crop(gsc->mdev.gsc_vd_entity->fd, &crop);
2073}