1 /*
2  * Copyright Samsung Electronics Co.,LTD.
3  * Copyright (C) 2015 The Android Open Source Project
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 #ifndef __HARDWARE_EXYNOS_EXYNOS_JPEG_API_H__
19 #define __HARDWARE_EXYNOS_EXYNOS_JPEG_API_H__
20 
21 // Exynos HAL defines another version of videodev2 apart from the original one
22 // This prevents conflict from the Exynos HAL from the original videodev2.h
23 /*
24 #ifndef v4l2_fourcc
25 #include <linux/videodev2.h>
26 #endif
27 */
28 
29 #include <exynos-hwjpeg.h>
30 
31 #ifndef JPEG_CACHE_ON
32 #define JPEG_CACHE_ON 1
33 #endif
34 
35 #define JPEG_BUF_TYPE_USER_PTR 1
36 #define JPEG_BUF_TYPE_DMA_BUF  2
37 
38 // CUSTOM V4L2 4CC FORMATS FOR LEGACY JPEG LIBRARY AND DRIVERS
39 #ifndef V4L2_PIX_FMT_JPEG_444
40 #define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4')
41 #endif
42 #ifndef V4L2_PIX_FMT_JPEG_422
43 #define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2')
44 #endif
45 #ifndef V4L2_PIX_FMT_JPEG_420
46 #define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0')
47 #endif
48 #ifndef V4L2_PIX_FMT_JPEG_GRAY
49 #define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G')
50 #endif
51 #ifndef V4L2_PIX_FMT_JPEG_422V
52 #define V4L2_PIX_FMT_JPEG_422V v4l2_fourcc('J', 'P', 'G', '5')
53 #endif
54 #ifndef V4L2_PIX_FMT_JPEG_411
55 #define V4L2_PIX_FMT_JPEG_411 v4l2_fourcc('J', 'P', 'G', '1')
56 #endif
57 
58 class ExynosJpegEncoder {
59     /*
60      * ExynosJpedgEncoder class is actually a derived class of
61      * CHWJpegV4L2Compressor. But it is not derived from CHWJpegV4L2Compressor
62      * because it has a lot of virtual functions which require extra memory for
63      * vtables. Moreover, ExynosJpegEncoder class implements no virtual function
64      * of CHWJpegV4L2Compressor.
65      */
66     CHWJpegV4L2Compressor m_hwjpeg;
67 
68     char m_iInBufType;
69     char m_iOutBufType;
70 
71     unsigned int m_uiState;
72 
73     int m_nQFactor;
74     int m_nWidth;
75     int m_nHeight;
76     int m_v4l2Format;
77     int m_jpegFormat;
78     int m_nStreamSize;
79 
80     bool __EnsureFormatIsApplied();
81 protected:
82     enum {
83         STATE_SIZE_CHANGED      = 1 << 0,
84         STATE_PIXFMT_CHANGED    = 1 << 1,
85         STATE_BASE_MAX          = 1 << 16,
86     };
87 
GetDeviceCapabilities()88     unsigned int GetDeviceCapabilities() { return m_hwjpeg.GetDeviceCapabilities(); }
GetCompressor()89     CHWJpegCompressor &GetCompressor() { return m_hwjpeg; }
GetHWDelay()90     unsigned int GetHWDelay() { return m_hwjpeg.GetHWDelay(); }
91 
SetState(unsigned int state)92     void SetState(unsigned int state) { m_uiState |= state; }
ClearState(unsigned int state)93     void ClearState(unsigned int state) { m_uiState &= ~state; }
TestState(unsigned int state)94     bool TestState(unsigned int state) { return (m_uiState & state) == state; }
TestStateEither(unsigned int state)95     bool TestStateEither(unsigned int state) { return (m_uiState & state) != 0; }
96 
EnsureFormatIsApplied()97     virtual bool EnsureFormatIsApplied() { return __EnsureFormatIsApplied(); }
98 public:
ExynosJpegEncoder()99     ExynosJpegEncoder(): m_hwjpeg(),
100           m_iInBufType(JPEG_BUF_TYPE_USER_PTR), m_iOutBufType(JPEG_BUF_TYPE_USER_PTR), m_uiState(0),
101           m_nQFactor(0), m_nWidth(0), m_nHeight(0), m_v4l2Format(0), m_jpegFormat(0), m_nStreamSize(0)
102     {
103         /* To detect setInBuf() call without format setting */
104         SetState(STATE_SIZE_CHANGED | STATE_PIXFMT_CHANGED);
105     }
~ExynosJpegEncoder()106     virtual ~ExynosJpegEncoder() { destroy(); }
107 
108     // Return 0 on success, -1 on error
flagCreate()109     int flagCreate() { return m_hwjpeg.Okay() ? 0 : -1; }
create(void)110     virtual int create(void) { return flagCreate(); }
destroy(void)111     virtual int destroy(void) { return 0; }
updateConfig(void)112     int updateConfig(void) { return 0; }
setCache(int __unused val)113     int setCache(int __unused val) { return 0; }
114 
getJpegConfig()115     void *getJpegConfig() { return reinterpret_cast<void *>(this); }
116     int setJpegConfig(void* pConfig);
117 
checkInBufType(void)118     int checkInBufType(void) { return m_iInBufType; }
checkOutBufType(void)119     int checkOutBufType(void) { return m_iOutBufType; }
120 
121     int getInBuf(int *piBuf, int *piInputSize, int iSize);
122     int getOutBuf(int *piBuf, int *piOutputSize);
123     int getInBuf(char **pcBuf, int *piInputSize, int iSize);
124     int getOutBuf(char **pcBuf, int *piOutputSize);
125 
126     int setInBuf(int *piBuf, int *iSize);
127     int setOutBuf(int iBuf, int iSize, int offset = 0);
128     int setInBuf(char **pcBuf, int *iSize);
129     int setOutBuf(char *pcBuf, int iSize);
130 
getSize(int * piWidth,int * piHeight)131     int getSize(int *piWidth, int *piHeight) {
132         *piWidth = m_nWidth;
133         *piHeight = m_nHeight;
134         return 0;
135     }
136 
setSize(int iW,int iH)137     int setSize(int iW, int iH) {
138         if ((m_nWidth != iW) || (m_nHeight != iH)) {
139             m_nWidth = iW;
140             m_nHeight = iH;
141             SetState(STATE_SIZE_CHANGED);
142         }
143         return 0;
144     }
145 
146     int setJpegFormat(int iV4l2JpegFormat);
getColorFormat(void)147     int getColorFormat(void) { return m_v4l2Format; }
setColorFormat(int iV4l2ColorFormat)148     int setColorFormat(int iV4l2ColorFormat) {
149         if (iV4l2ColorFormat != m_v4l2Format) {
150             m_v4l2Format = iV4l2ColorFormat;
151             SetState(STATE_PIXFMT_CHANGED);
152         }
153         return 0;
154     }
155 
setQuality(int iQuality)156     int setQuality(int iQuality) {
157         if (m_nQFactor != iQuality) {
158             if (!m_hwjpeg.SetQuality(static_cast<unsigned int>(iQuality)))
159                 return -1;
160             m_nQFactor = iQuality;
161         }
162         return 0;
163     }
164 
165     int setQuality(const unsigned char q_table[]);
166 
167     int setColorBufSize(int *piBufSize, int iSize);
getJpegSize(void)168     int getJpegSize(void) { return m_nStreamSize; }
169 
encode(void)170     int encode(void) {
171         if (!__EnsureFormatIsApplied())
172             return false;
173 
174         m_nStreamSize = static_cast<int>(m_hwjpeg.Compress());
175         return (m_nStreamSize < 0) ? -1 : 0;
176     }
177 
178 };
179 
180 #endif //__HARDWARE_EXYNOS_EXYNOS_JPEG_API_H__
181