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      exynos_scaler.c
20  * \brief     header file for Scaler HAL
21  * \author    Sunyoung Kang (sy0816.kang@samsung.com)
22  * \date      2013/02/01
23  *
24  * <b>Revision History: </b>
25  * - 2013.02.01 : Sunyoung Kang (sy0816.kang@samsung.com) \n
26  *   Create
27  *
28  * - 2013.04.26 : Cho KyongHo (pullip.cho@samsung.com \n
29  *   Library rewrite
30  *
31  */
32 
33 #ifndef _EXYNOS_SCALER_H_
34 #define _EXYNOS_SCALER_H_
35 
36 
37 #include <linux/videodev2.h>
38 #include <stdbool.h>
39 
40 #include "exynos_format.h"
41 
42 #define SC_DEV_NODE     "/dev/video"
43 #define SC_NODE(x)      (50 + x)
44 
45 #define SC_NUM_OF_PLANES    (3)
46 
47 #define V4L2_PIX_FMT_NV12_RGB32         v4l2_fourcc('N', 'V', '1', 'R')
48 #define V4L2_PIX_FMT_NV12N_RGB32        v4l2_fourcc('N', 'N', '1', 'R')
49 #define V4L2_PIX_FMT_NV12M_RGB32        v4l2_fourcc('N', 'V', 'R', 'G')
50 #define V4L2_PIX_FMT_NV12M_BGR32        v4l2_fourcc('N', 'V', 'B', 'G')
51 #define V4L2_PIX_FMT_NV12M_RGB565       v4l2_fourcc('N', 'V', 'R', '6')
52 #define V4L2_PIX_FMT_NV12M_RGB444       v4l2_fourcc('N', 'V', 'R', '4')
53 #define V4L2_PIX_FMT_NV12M_RGB555X      v4l2_fourcc('N', 'V', 'R', '5')
54 #define V4L2_PIX_FMT_NV12MT_16X16_RGB32 v4l2_fourcc('V', 'M', 'R', 'G')
55 #define V4L2_PIX_FMT_NV21M_RGB32        v4l2_fourcc('V', 'N', 'R', 'G')
56 #define V4L2_PIX_FMT_NV21M_BGR32        v4l2_fourcc('V', 'N', 'B', 'G')
57 #define V4L2_PIX_FMT_NV21_RGB32         v4l2_fourcc('V', 'N', '1', 'R')
58 #define V4L2_PIX_FMT_YVU420_RGB32       v4l2_fourcc('Y', 'V', 'R', 'G')
59 #define V4L2_PIX_FMT_NV12M_P010         v4l2_fourcc('P', 'M', '1', '2')
60 
61 // libgscaler's internal use only
62 typedef enum _HW_SCAL_ID {
63     HW_SCAL0 = 4,
64     HW_SCAL1,
65     HW_SCAL2,
66     HW_SCAL_MAX,
67 } HW_SCAL_ID;
68 
69 // argument of non-blocking api
70 typedef struct {
71     uint32_t x;
72     uint32_t y;
73     uint32_t w;
74     uint32_t h;
75     uint32_t fw;
76     uint32_t fh;
77     uint32_t format;
78     unsigned long yaddr;
79     unsigned long uaddr;
80     unsigned long vaddr;
81     uint32_t rot;
82     uint32_t cacheable;
83     uint32_t drmMode;
84     uint32_t narrowRgb;
85     int      acquireFenceFd;
86     int      releaseFenceFd;
87     int      mem_type;
88     uint32_t pre_multi;
89 } exynos_sc_img;
90 
91 enum colorspace {
92     COLORSPACE_SMPTE170M,
93     COLORSPACE_SMPTE240M,
94     COLORSPACE_REC709,
95     COLORSPACE_BT878,
96     COLORSPACE_470_SYSTEM_M,
97     COLORSPACE_470_SYSTEM_BG,
98     COLORSPACE_JPEG,
99     COLORSPACE_SRGB,
100 };
101 
102 struct CSC_Spec{
103 	uint32_t enable;    // set 'true' for user-defined
104 	enum colorspace space;
105 	uint32_t wide;
106 };
107 
108 enum SRC_BL_OP {
109 	/* [0, 0] */
110 	SRC_BL_OP_CLR = 1,
111 	/* [Sa, Sc] */
112 	SRC_BL_OP_SRC,
113 	/* [Da, Dc] */
114 	SRC_BL_OP_DST,
115 	/* [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
116 	SRC_BL_OP_SRC_OVER,
117 	/* [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
118 	SRC_BL_OP_DST_OVER,
119 	/* [Sa * Da, Sc * Da] */
120 	SRC_BL_OP_SRC_IN,
121 	/* [Sa * Da, Sa * Dc] */
122 	SRC_BL_OP_DST_IN,
123 	/* [Sa * (1 - Da), Sc * (1 - Da)] */
124 	SRC_BL_OP_SRC_OUT,
125 	/* [Da * (1 - Sa), Dc * (1 - Sa)] */
126 	SRC_BL_OP_DST_OUT,
127 	/* [Da, Sc * Da + (1 - Sa) * Dc] */
128 	SRC_BL_OP_SRC_ATOP,
129 	/* [Sa, Sc * (1 - Da) + Sa * Dc ] */
130 	SRC_BL_OP_DST_ATOP,
131 	/* [-(Sa * Da), Sc * (1 - Da) + (1 - Sa) * Dc] */
132 	SRC_BL_OP_XOR,
133 	/* [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
134 	SRC_BL_OP_DARKEN,
135 	/* [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
136 	SRC_BL_OP_LIGHTEN,
137 	/** [Sa * Da, Sc * Dc] */
138 	SRC_BL_OP_MULTIPLY,
139 	/* [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
140 	SRC_BL_OP_SCREEN,
141 	/* Saturate(S + D) */
142 	SRC_BL_OP_ADD
143 };
144 
145 struct SrcGlobalAlpha {
146 	uint32_t enable;
147 	unsigned int val;
148 };
149 
150 struct SrcBlendInfo {
151 	enum SRC_BL_OP blop;
152 	unsigned int srcblendfmt;
153 	unsigned int srcblendhpos;
154 	unsigned int srcblendvpos;
155 	unsigned int srcblendpremulti;
156 	unsigned int srcblendstride;
157 	unsigned int srcblendwidth;
158 	unsigned int srcblendheight;
159 	struct SrcGlobalAlpha globalalpha;
160 	struct CSC_Spec cscspec;
161 };
162 
163 #ifdef __cplusplus
164 extern "C" {
165 #endif
166 
167 /*!
168  * Create libscaler handle
169  *
170  * \ingroup exynos_scaler
171  *
172  * \param dev_num
173  *  scaler dev_num[in]
174  *
175  * \return
176  * libscaler handle
177  */
178 void *exynos_sc_create(int dev_num);
179 
180 /*!
181  * Destroy libscaler handle
182  *
183  * \ingroup exynos_scaler
184  *
185  * \param handle
186  *   libscaler handle[in]
187  */
188 int exynos_sc_destroy(void *handle);
189 
190 /*!
191  * Convert color space with presetup color format
192  *
193  * \ingroup exynos_scaler
194  *
195  * \param handle
196  *   libscaler handle[in]
197  *
198  * \return
199  *   error code
200  */
201 int exynos_sc_convert(void *handle);
202 
203 /*!
204  * Convert color space with presetup color format
205  *
206  * \ingroup exynos_scaler
207  *
208  * \param handle
209  *   libscaler handle
210  *
211  * \param csc_range
212  *   csc narrow/wide property
213  *
214  * \param v4l2_colorspace
215  *   csc equation property
216  *
217  * \param filter
218  *   denoise filter info
219  *
220  * \return
221  *   error code
222  */
223 int exynos_sc_set_csc_property(
224     void        *handle,
225     unsigned int csc_range,
226     unsigned int v4l2_colorspace,
227     unsigned int filter);
228 
229 /*!
230  * Set source format.
231  *
232  * \ingroup exynos_scaler
233  *
234  * \param handle
235  *   libscaler handle[in]
236  *
237  * \param width
238  *   image width[in]
239  *
240  * \param height
241  *   image height[in]
242  *
243  * \param crop_left
244  *   image left crop size[in]
245  *
246  * \param crop_top
247  *   image top crop size[in]
248  *
249  * \param crop_width
250  *   cropped image width[in]
251  *
252  * \param crop_height
253  *   cropped image height[in]
254  *
255  * \param v4l2_colorformat
256  *   color format[in]
257  *
258  * \param cacheable
259  *   ccacheable[in]
260  *
261  * \param mode_drm
262  *   mode_drm[in]
263  *
264  * \param premultiplied
265  *   pre-multiplied format[in]
266  *
267  * \return
268  *   error code
269  */
270 int exynos_sc_set_src_format(
271     void        *handle,
272     unsigned int width,
273     unsigned int height,
274     unsigned int crop_left,
275     unsigned int crop_top,
276     unsigned int crop_width,
277     unsigned int crop_height,
278     unsigned int v4l2_colorformat,
279     unsigned int cacheable,
280     unsigned int mode_drm,
281     unsigned int premultiplied);
282 
283 /*!
284  * Set destination format.
285  *
286  * \ingroup exynos_scaler
287  *
288  * \param handle
289  *   libscaler handle[in]
290  *
291  * \param width
292  *   image width[in]
293  *
294  * \param height
295  *   image height[in]
296  *
297  * \param crop_left
298  *   image left crop size[in]
299  *
300  * \param crop_top
301  *   image top crop size[in]
302  *
303  * \param crop_width
304  *   cropped image width[in]
305  *
306  * \param crop_height
307  *   cropped image height[in]
308  *
309  * \param v4l2_colorformat
310  *   color format[in]
311  *
312  * \param cacheable
313  *   ccacheable[in]
314  *
315  * \param mode_drm
316  *   mode_drm[in]
317  *
318  * \param premultiplied
319  *   pre-multiplied format[in]
320  *
321  * \return
322  *   error code
323  */
324 int exynos_sc_set_dst_format(
325     void        *handle,
326     unsigned int width,
327     unsigned int height,
328     unsigned int crop_left,
329     unsigned int crop_top,
330     unsigned int crop_width,
331     unsigned int crop_height,
332     unsigned int v4l2_colorformat,
333     unsigned int cacheable,
334     unsigned int mode_drm,
335     unsigned int premultiplied);
336 
337 /*!
338  * Set source buffer
339  *
340  * \ingroup exynos_scaler
341  *
342  * \param handle
343  *   libscaler handle[in]
344  *
345  * \param addr
346  *   buffer pointer array[in]
347  *
348  * \param mem_type
349  *   memory type[in]
350  *
351  * \param acquireFenceFd
352  *   acquire fence fd for the buffer or -1[in]
353  *
354  * \return
355  *   error code
356  */
357 
358 int exynos_sc_set_src_addr(
359     void *handle,
360     void *addr[SC_NUM_OF_PLANES],
361     int mem_type,
362     int acquireFenceFd);
363 
364 /*!
365  * Set destination buffer
366  *
367  * \param handle
368  *   libscaler handle[in]
369  *
370  * \param addr
371  *   buffer pointer array[in]
372  *
373  * \param mem_type
374  *   memory type[in]
375  *
376  * \param acquireFenceFd
377  *   acquire fence fd for the buffer or -1[in]
378  *
379  * \return
380  *   error code
381  */
382 int exynos_sc_set_dst_addr(
383     void *handle,
384     void *addr[SC_NUM_OF_PLANES],
385     int mem_type,
386     int acquireFenceFd);
387 
388 /*!
389  * Set rotation.
390  *
391  * \ingroup exynos_scaler
392  *
393  * \param handle
394  *   libscaler handle[in]
395  *
396  * \param rot
397  *   image rotation. It should be multiple of 90[in]
398  *
399  * \param flip_h
400  *   image flip_horizontal[in]
401  *
402  * \param flip_v
403  *   image flip_vertical[in]
404  *
405  * \return
406  *   error code
407  */
408 int exynos_sc_set_rotation(
409     void *handle,
410     int rot,
411     int flip_h,
412     int flip_v);
413 
414 /*!
415  * Set framerate (optional).
416  *
417  * \ingroup exynos_scaler
418  *
419  * \param handle
420  *   libscaler handle[in]
421  *
422  * \param framerate
423  *   frame rate[in]
424  */
425 void exynos_sc_set_framerate(
426         void *handle,
427         int framerate);
428 ////// non-blocking /////
429 
430 void *exynos_sc_create_exclusive(
431     int dev_num,
432     int allow_drm);
433 
434 int exynos_sc_csc_exclusive(void *handle,
435     unsigned int range_full,
436     unsigned int v4l2_colorspace);
437 
438 int exynos_sc_config_exclusive(
439     void *handle,
440     exynos_sc_img *src_img,
441     exynos_sc_img *dst_img);
442 
443 int exynos_sc_run_exclusive(
444     void *handle,
445     exynos_sc_img *src_img,
446     exynos_sc_img *dst_img);
447 
448 void *exynos_sc_create_blend_exclusive(
449         int dev_num,
450         int allow_drm);
451 
452 int exynos_sc_config_blend_exclusive(
453     void *handle,
454     exynos_sc_img *src_img,
455     exynos_sc_img *dst_img,
456     struct SrcBlendInfo  *srcblendinfo);
457 
458 int exynos_sc_wait_frame_done_exclusive
459 (void *handle);
460 
461 int exynos_sc_stop_exclusive
462 (void *handle);
463 
464 int exynos_sc_free_and_close
465 (void *handle);
466 
467 
468 /******************************************************************************
469  ******** API for Copy Pixels between RGB data ********************************
470  ******************************************************************************/
471 
472 /*!
473  * Description of an image for both of the source and the destination.
474  *
475  * \ingroup exynos_scaler
476  */
477 struct exynos_sc_pxinfo_img
478 {
479     void *addr;
480     unsigned int width;
481     unsigned int height;
482     unsigned int crop_left;
483     unsigned int crop_top;
484     unsigned int crop_width;
485     unsigned int crop_height;
486     unsigned int pxfmt;  // enum EXYNOS_SC_FMT_PXINFO
487 };
488 
489 /*!
490  * Description of a pixel copy
491  *
492  * \ingroup exynos_scaler
493  */
494 struct exynos_sc_pxinfo {
495     struct exynos_sc_pxinfo_img src;
496     struct exynos_sc_pxinfo_img dst;
497     unsigned short rotate; // 0 ~ 360
498     char hflip;  // non-zero value for hflip
499     char vflip;  // non-zero value for vflip
500 };
501 
502 /*!
503  * Pixel format definition for pixel copy
504  *
505  * \ingroup exynos_scaler
506  */
507 enum SC_FMT_PXINFO {
508     EXYNOS_SC_FMT_RGB32 = 0x10,
509     EXYNOS_SC_FMT_BGR32,
510     EXYNOS_SC_FMT_RGB565,
511     EXYNOS_SC_FMT_RGB555X,
512     EXYNOS_SC_FMT_RGB444,
513 };
514 
515 /*!
516  * Copy pixel data from RGB to RGB
517  *
518  * \ingroup exynos_scaler
519  *
520  * \param pxinfo
521  *   information for pixel data copy [in]
522  *
523  * \param dev_num
524  *   Scaler H/W instance number. Starts from 0 [in]
525  *
526  * \return
527  *   true on success in copying pixel data.
528  *   false on failure.
529  */
530 bool exynos_sc_copy_pixels(
531     struct exynos_sc_pxinfo *pxinfo,
532     int dev_num);
533 
534 int hal_pixfmt_to_v4l2(int hal_pixel_format);
535 
536 #ifdef __cplusplus
537 }
538 #endif
539 
540 #endif /* _EXYNOS_SCALER_H_ */
541