Removed build warnings
[platform/adaptation/ap_samsung/libexynos-common.git] / libgscaler / libgscaler.cpp
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.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 "libgscaler_obj.h"
30
31 void *exynos_gsc_create(void)
32 {
33     CGscaler *gsc = new CGscaler(GSC_M2M_MODE);
34     if (!gsc) {
35         ALOGE("%s:: failed to allocate Gscaler handle", __func__);
36         return NULL;
37     }
38     if (gsc->m_gsc_find_and_create(gsc) == false) {
39         ALOGE("%s::m_exynos_gsc_find_and_create() fail", __func__);
40         delete gsc;
41         return NULL;
42     }
43
44     return reinterpret_cast<void *>(gsc);
45 }
46
47 void *exynos_gsc_create_exclusive(
48     int dev_num,
49     int mode,
50     int out_mode,
51     int allow_drm)
52 {
53     int ret = 0;
54
55     Exynos_gsc_In();
56
57     if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
58         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
59         return NULL;
60     }
61
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);
64         if (!gsc) {
65             ALOGE("%s:: failed to allocate Gscaler handle", __func__);
66             return NULL;
67         }
68
69         gsc->scaler = exynos_sc_create_exclusive(dev_num - HW_SCAL0,
70             allow_drm);
71         if (!gsc->scaler) {
72             delete(gsc);
73             ALOGE("%s::exynos_sc_create fail", __func__);
74             return NULL;
75         }
76         Exynos_gsc_Out();
77         return reinterpret_cast<void *>(gsc);
78     }
79
80     if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
81         ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
82         return NULL;
83     }
84
85     CGscaler *gsc = new CGscaler(mode, out_mode, dev_num, allow_drm);
86     if (!gsc) {
87         ALOGE("%s:: failed to allocate Gscaler handle", __func__);
88         return NULL;
89     }
90
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);
95             goto err;
96         }
97     } else if (mode == GSC_OUTPUT_MODE) {
98         ret = gsc->m_gsc_output_create(gsc, dev_num, out_mode);
99         if (ret < 0) {
100             ALOGE("%s::m_gsc_output_create(%i) fail", __func__, dev_num);
101             goto err;
102         }
103     } else if (mode == GSC_CAPTURE_MODE) {
104         ret = gsc->m_gsc_capture_create(gsc, dev_num, out_mode);
105         if (ret < 0) {
106             ALOGE("%s::m_gsc_capture_create(%i) fail", __func__, dev_num);
107             goto err;
108         }
109     } else {
110             ALOGE("%s::Unsupported Mode(%i) fail", __func__, dev_num);
111             goto err;
112     }
113
114     Exynos_gsc_Out();
115
116     return reinterpret_cast<void *>(gsc);
117 err:
118     switch (mode) {
119     case GSC_M2M_MODE:
120         gsc->m_gsc_m2m_destroy(gsc);
121         break;
122     case GSC_OUTPUT_MODE:
123         gsc->m_gsc_out_destroy(gsc);
124         break;
125     case GSC_CAPTURE_MODE:
126         gsc->m_gsc_cap_destroy(gsc);
127         break;
128     }
129
130     delete(gsc);
131
132     Exynos_gsc_Out();
133
134     return NULL;
135 }
136
137 void exynos_gsc_destroy(void *handle)
138 {
139     Exynos_gsc_In();
140
141     CGscaler* gsc = GetGscaler(handle);
142     if (gsc == NULL) {
143         ALOGE("%s::handle == NULL() fail", __func__);
144         return;
145     }
146
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);
151     else
152         gsc->m_gsc_m2m_destroy(gsc);
153
154     delete(gsc);
155
156     Exynos_gsc_Out();
157 }
158
159 int exynos_gsc_set_csc_property(
160     void        *handle,
161     unsigned int eq_auto,
162     unsigned int range_full,
163     unsigned int v4l2_colorspace)
164 {
165     Exynos_gsc_In();
166
167     CGscaler *gsc = GetGscaler(handle);
168     if (gsc == NULL) {
169         ALOGE("%s::handle == NULL() fail", __func__);
170         return -1;
171     }
172
173     if (gsc->gsc_id >= HW_SCAL0) {
174         int ret;
175         ret = exynos_sc_csc_exclusive(gsc->scaler,
176                             range_full, v4l2_colorspace);
177         Exynos_gsc_Out();
178         return ret;
179     }
180     gsc->eq_auto = eq_auto;
181     gsc->range_full = range_full;
182     gsc->v4l2_colorspace = v4l2_colorspace;
183
184     Exynos_gsc_Out();
185
186     return 0;
187 }
188
189 int exynos_gsc_set_src_format(
190     void        *handle,
191     unsigned int width,
192     unsigned int height,
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)
200 {
201     Exynos_gsc_In();
202
203     CGscaler *gsc = GetGscaler(handle);
204     if (gsc == NULL) {
205         ALOGE("%s::handle == NULL() fail", __func__);
206         return -1;
207     }
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;
218
219     Exynos_gsc_Out();
220
221     return 0;
222 }
223
224 int exynos_gsc_set_dst_format(
225     void        *handle,
226     unsigned int width,
227     unsigned int height,
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)
235 {
236     Exynos_gsc_In();
237
238     CGscaler *gsc = GetGscaler(handle);
239     if (gsc == NULL) {
240         ALOGE("%s::handle == NULL() fail", __func__);
241         return -1;
242     }
243
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;
254
255     Exynos_gsc_Out();
256
257     return 0;
258 }
259
260 int exynos_gsc_set_rotation(
261     void *handle,
262     int   rotation,
263     int   flip_horizontal,
264     int   flip_vertical)
265 {
266     CGscaler *gsc = GetGscaler(handle);
267     if (gsc == NULL) {
268         ALOGE("%s::handle == NULL() fail", __func__);
269         return -1;
270     }
271
272     int new_rotation = rotation % 360;
273
274     if (new_rotation % 90 != 0) {
275         ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__,
276             rotation);
277         return -1;
278     }
279
280     if(new_rotation < 0)
281         new_rotation = -new_rotation;
282
283     gsc->dst_info.rotation        = new_rotation;
284     gsc->dst_info.flip_horizontal = flip_horizontal;
285     gsc->dst_info.flip_vertical   = flip_vertical;
286
287     return 0;
288 }
289
290 int exynos_gsc_set_src_addr(
291     void *handle,
292     void *addr[3],
293     int mem_type,
294     int acquireFenceFd)
295 {
296     Exynos_gsc_In();
297
298     CGscaler* gsc = GetGscaler(handle);
299     if (gsc == NULL) {
300         ALOGE("%s::handle == NULL() fail", __func__);
301         return -1;
302     }
303
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;
309
310     Exynos_gsc_Out();
311
312     return 0;
313 }
314
315 int exynos_gsc_set_dst_addr(
316     void *handle,
317     void *addr[3],
318     int mem_type,
319     int acquireFenceFd)
320 {
321     Exynos_gsc_In();
322
323     CGscaler* gsc = GetGscaler(handle);
324     if (gsc == NULL) {
325         ALOGE("%s::handle == NULL() fail", __func__);
326         return -1;
327     }
328
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;
334
335     Exynos_gsc_Out();
336
337     return 0;
338 }
339
340 int exynos_gsc_convert(void *handle)
341 {
342     Exynos_gsc_In();
343
344     int ret    = -1;
345     CGscaler* gsc = GetGscaler(handle);
346     if (gsc == NULL) {
347         ALOGE("%s::handle == NULL() fail", __func__);
348         return ret;
349     }
350
351     if (gsc->m_gsc_m2m_run_core(handle) < 0) {
352         ALOGE("%s::exynos_gsc_run_core fail", __func__);
353         goto done;
354     }
355
356     if (gsc->m_gsc_m2m_wait_frame_done(handle) < 0) {
357         ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
358         goto done;
359     }
360
361     if (gsc->src_info.releaseFenceFd >= 0) {
362         close(gsc->src_info.releaseFenceFd);
363         gsc->src_info.releaseFenceFd = -1;
364     }
365
366     if (gsc->dst_info.releaseFenceFd >= 0) {
367         close(gsc->dst_info.releaseFenceFd);
368         gsc->dst_info.releaseFenceFd = -1;
369     }
370
371     if (gsc->m_gsc_m2m_stop(handle) < 0) {
372         ALOGE("%s::m_gsc_m2m_stop", __func__);
373         goto done;
374     }
375
376     ret = 0;
377
378 done:
379     Exynos_gsc_Out();
380
381     return ret;
382 }
383
384 int exynos_gsc_subdev_s_crop(void *handle,
385         exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
386 {
387     struct v4l2_subdev_crop sd_crop;
388     CGscaler *gsc = GetGscaler(handle);
389     if (gsc == NULL) {
390         ALOGE("%s::handle == NULL() fail", __func__);
391         return -1;
392     }
393
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;
400
401     return exynos_subdev_s_crop(gsc->mdev.gsc_sd_entity->fd, &sd_crop);
402 }
403
404 int exynos_gsc_config_exclusive(void *handle,
405     exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
406 {
407     Exynos_gsc_In();
408
409     int ret = 0;
410     CGscaler* gsc = GetGscaler(handle);
411     if (gsc == NULL) {
412         ALOGE("%s::handle == NULL() fail", __func__);
413         return -1;
414     }
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);
418         Exynos_gsc_Out();
419         return ret;
420     }
421
422     switch (gsc->mode) {
423     case GSC_M2M_MODE:
424         ret = gsc->m_gsc_m2m_config(handle, src_img, dst_img);
425         break;
426     case GSC_OUTPUT_MODE:
427         ret = gsc->m_gsc_out_config(handle, src_img, dst_img);
428         break;
429     case GSC_CAPTURE_MODE:
430         ret = gsc->m_gsc_cap_config(handle, src_img, dst_img);
431         break;
432     default:
433         break;
434     }
435
436     Exynos_gsc_Out();
437
438     return ret;
439 }
440
441 int exynos_gsc_run_exclusive(void *handle,
442     exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
443 {
444     Exynos_gsc_In();
445
446     int ret = 0;
447     CGscaler* gsc = GetGscaler(handle);
448     if (gsc == NULL) {
449         ALOGE("%s::handle == NULL() fail", __func__);
450         return -1;
451     }
452
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);
456         Exynos_gsc_Out();
457         return ret;
458     }
459
460     switch (gsc->mode) {
461     case GSC_M2M_MODE:
462         ret = gsc->m_gsc_m2m_run(handle, src_img, dst_img);
463         break;
464     case GSC_OUTPUT_MODE:
465         ret = gsc->m_gsc_out_run(handle, src_img);
466         break;
467     case GSC_CAPTURE_MODE:
468         ret = gsc->m_gsc_cap_run(handle, dst_img);
469         break;
470     default:
471         break;
472     }
473
474     Exynos_gsc_Out();
475
476     return ret;
477 }
478
479 void *exynos_gsc_create_blend_exclusive(int dev_num, int mode, int out_mode,
480                                                                 int allow_drm)
481 {
482     Exynos_gsc_In();
483
484     if ((dev_num < 0) || (dev_num >= HW_SCAL_MAX)) {
485         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
486         return NULL;
487     }
488
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);
491         if (!gsc) {
492             ALOGE("%s:: failed to allocate Gscaler handle", __func__);
493             return NULL;
494         }
495
496         gsc->scaler = exynos_sc_create_blend_exclusive(dev_num - HW_SCAL0, allow_drm);
497         if (!gsc->scaler) {
498             Exynos_gsc_Out();
499             delete(gsc);
500             ALOGE("%s::exynos_sc_create_blend_exclusive failed", __func__);
501             return NULL;
502         }
503         Exynos_gsc_Out();
504
505         return reinterpret_cast<void *>(gsc);
506     }
507
508     Exynos_gsc_Out();
509
510     return NULL;
511 }
512
513 int exynos_gsc_config_blend_exclusive(void *handle,
514     exynos_mpp_img *src_img, exynos_mpp_img *dst_img,
515     struct SrcBlendInfo  *srcblendinfo)
516 {
517     Exynos_gsc_In();
518
519     int ret = 0;
520     CGscaler* gsc = GetGscaler(handle);
521     if (gsc == NULL) {
522         ALOGE("%s::handle == NULL() fail", __func__);
523         return -1;
524     }
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,
529                                                srcblendinfo);
530         Exynos_gsc_Out();
531         return ret;
532     }
533         Exynos_gsc_Out();
534         return ret;
535 }
536
537 int exynos_gsc_wait_frame_done_exclusive(void *handle)
538 {
539     Exynos_gsc_In();
540
541     int ret = 0;
542     CGscaler* gsc = GetGscaler(handle);
543     if (gsc == NULL) {
544         ALOGE("%s::handle == NULL() fail", __func__);
545         return -1;
546     }
547
548     if (gsc->gsc_id >= HW_SCAL0) {
549         ret = exynos_sc_wait_frame_done_exclusive(gsc->scaler);
550         Exynos_gsc_Out();
551         return ret;
552     }
553
554     if (gsc->mode == GSC_M2M_MODE)
555         ret = gsc->m_gsc_m2m_wait_frame_done(handle);
556
557     Exynos_gsc_Out();
558
559     return ret;
560 }
561
562 int exynos_gsc_stop_exclusive(void *handle)
563 {
564     Exynos_gsc_In();
565
566     int ret = 0;
567     CGscaler* gsc = GetGscaler(handle);
568     if (gsc == NULL) {
569         ALOGE("%s::handle == NULL() fail", __func__);
570         return -1;
571     }
572
573     if (gsc->gsc_id >= HW_SCAL0) {
574         ret = exynos_sc_stop_exclusive(gsc->scaler);
575         Exynos_gsc_Out();
576         return ret;
577     }
578
579     switch (gsc->mode) {
580     case GSC_M2M_MODE:
581         ret = gsc->m_gsc_m2m_stop(handle);
582         break;
583     case GSC_OUTPUT_MODE:
584         ret = gsc->m_gsc_out_stop(handle);
585         break;
586     case  GSC_CAPTURE_MODE:
587         ret = gsc->m_gsc_cap_stop(handle);
588         break;
589     default:
590         break;
591     }
592
593     Exynos_gsc_Out();
594
595     return ret;
596 }
597
598 int exynos_gsc_free_and_close(void *handle)
599 {
600     Exynos_gsc_In();
601
602     struct v4l2_requestbuffers reqbuf;
603     int ret = 0;
604     CGscaler* gsc = GetGscaler(handle);
605     if (gsc == NULL) {
606         ALOGE("%s::handle == NULL() fail", __func__);
607         return -1;
608     }
609
610
611     if (gsc->gsc_id >= HW_SCAL0) {
612         ret = exynos_sc_free_and_close(gsc->scaler);
613         Exynos_gsc_Out();
614         return ret;
615     }
616
617     memset(&reqbuf, 0, sizeof(struct v4l2_requestbuffers));
618     if (gsc->mode == GSC_OUTPUT_MODE)
619             reqbuf.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
620     else
621             reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
622
623     reqbuf.memory = V4L2_MEMORY_DMABUF;
624     reqbuf.count  = 0;
625
626     if (exynos_v4l2_reqbufs(gsc->mdev.gsc_vd_entity->fd, &reqbuf) < 0) {
627         ALOGE("%s::request buffers failed", __func__);
628         return -1;
629     }
630
631     exynos_gsc_destroy(gsc);
632     Exynos_gsc_Out();
633
634     return 0;
635 }