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 #include <linux/videodev2.h>
19
20 #include <ExynosJpegApi.h>
21
22 #include "hwjpeg-internal.h"
23
setJpegConfig(void * pConfig)24 int ExynosJpegEncoder::setJpegConfig(void* pConfig)
25 {
26 ExynosJpegEncoder *that = reinterpret_cast<ExynosJpegEncoder *>(pConfig);
27
28 if (!setColorFormat(that->m_v4l2Format))
29 return -1;
30
31 if (!setJpegFormat(that->m_jpegFormat))
32 return -1;
33
34 if (!setSize(that->m_nWidth, that->m_nHeight))
35 return -1;
36
37 m_iInBufType = that->m_iInBufType;
38 m_iOutBufType = that->m_iOutBufType;
39
40 return 0;
41 }
42
getInBuf(int * piBuf,int * piInputSize,int iSize)43 int ExynosJpegEncoder::getInBuf(int *piBuf, int *piInputSize, int iSize)
44 {
45 if (iSize < 1) {
46 ALOGE("Invalid array size %d for getInBuf()", iSize);
47 return -1;
48 }
49
50 size_t len_buffers[iSize];
51 if (!m_hwjpeg.GetImageBuffers(piBuf, len_buffers, static_cast<unsigned int>(iSize)))
52 return -1;
53
54 for (int i = 0; i < iSize; i++)
55 piInputSize[i] = static_cast<int>(len_buffers[i]);
56
57 return 0;
58 }
59
getOutBuf(int * piBuf,int * piOutputSize)60 int ExynosJpegEncoder::getOutBuf(int *piBuf, int *piOutputSize)
61 {
62 size_t len;
63 if (!m_hwjpeg.GetJpegBuffer(piBuf, &len))
64 return -1;
65
66 *piOutputSize = static_cast<int>(len);
67 return 0;
68 }
69
setInBuf(int * piBuf,int * iSize)70 int ExynosJpegEncoder::setInBuf(int *piBuf, int *iSize)
71 {
72 size_t buflen[3];
73 unsigned int bufnum = 3;
74
75 if (!EnsureFormatIsApplied())
76 return -1;
77
78 if (!m_hwjpeg.GetImageBufferSizes(buflen, &bufnum))
79 return -1;
80
81 for (unsigned int i = 0; i < bufnum; i++)
82 buflen[i] = static_cast<size_t>(iSize[i]);
83
84 if (!m_hwjpeg.SetImageBuffer(piBuf, buflen, bufnum))
85 return -1;
86
87 m_iInBufType = JPEG_BUF_TYPE_DMA_BUF;
88
89 return 0;
90 }
91
setOutBuf(int iBuf,int iSize,int offset)92 int ExynosJpegEncoder::setOutBuf(int iBuf, int iSize, int offset)
93 {
94 if (!m_hwjpeg.SetJpegBuffer(iBuf, static_cast<size_t>(iSize), offset))
95 return -1;
96
97 m_iOutBufType = JPEG_BUF_TYPE_DMA_BUF;
98
99 return 0;
100 }
101
getInBuf(char ** pcBuf,int * piInputSize,int iSize)102 int ExynosJpegEncoder::getInBuf(char **pcBuf, int *piInputSize, int iSize)
103 {
104 if (iSize < 1) {
105 ALOGE("Invalid array size %d for getInBuf()", iSize);
106 return -1;
107 }
108
109 size_t len_buffers[iSize];
110 if (!m_hwjpeg.GetImageBuffers(pcBuf, len_buffers, static_cast<unsigned int>(iSize)))
111 return -1;
112
113 for (int i = 0; i < iSize; i++)
114 piInputSize[i] = static_cast<int>(len_buffers[i]);
115
116 return 0;
117 }
118
getOutBuf(char ** pcBuf,int * piOutputSize)119 int ExynosJpegEncoder::getOutBuf(char **pcBuf, int *piOutputSize)
120 {
121 size_t len;
122 if (!m_hwjpeg.GetJpegBuffer(pcBuf, &len))
123 return -1;
124
125 *piOutputSize = static_cast<int>(len);
126 return 0;
127 }
128
setInBuf(char ** pcBuf,int * iSize)129 int ExynosJpegEncoder::setInBuf(char **pcBuf, int *iSize)
130 {
131 size_t buflen[3];
132 unsigned int bufnum = 3;
133
134 if (!EnsureFormatIsApplied())
135 return -1;
136
137 if (!m_hwjpeg.GetImageBufferSizes(buflen, &bufnum))
138 return -1;
139
140 for (unsigned int i = 0; i < bufnum; i++)
141 buflen[i] = static_cast<size_t>(iSize[i]);
142
143 if (!m_hwjpeg.SetImageBuffer(pcBuf, buflen, bufnum))
144 return -1;
145
146 m_iInBufType = JPEG_BUF_TYPE_USER_PTR;
147 return 0;
148 }
149
setOutBuf(char * pcBuf,int iSize)150 int ExynosJpegEncoder::setOutBuf(char *pcBuf, int iSize)
151 {
152 if (!m_hwjpeg.SetJpegBuffer(pcBuf, static_cast<size_t>(iSize)))
153 return -1;
154
155 m_iOutBufType = JPEG_BUF_TYPE_USER_PTR;
156
157 return 0;
158 }
159
setJpegFormat(int iV4l2JpegFormat)160 int ExynosJpegEncoder::setJpegFormat(int iV4l2JpegFormat)
161 {
162 if (m_jpegFormat == iV4l2JpegFormat)
163 return 0;
164
165 unsigned int hfactor, vfactor;
166 switch (iV4l2JpegFormat) {
167 case V4L2_PIX_FMT_JPEG_444:
168 hfactor = 1;
169 vfactor = 1;
170 break;
171 case V4L2_PIX_FMT_JPEG_422:
172 hfactor = 2;
173 vfactor = 1;
174 break;
175 case V4L2_PIX_FMT_JPEG_420:
176 hfactor = 2;
177 vfactor = 2;
178 break;
179 case V4L2_PIX_FMT_JPEG_GRAY:
180 hfactor = 0;
181 vfactor = 0;
182 break;
183 case V4L2_PIX_FMT_JPEG_422V:
184 hfactor = 1;
185 vfactor = 2;
186 break;
187 case V4L2_PIX_FMT_JPEG_411:
188 hfactor = 4;
189 vfactor = 1;
190 break;
191 default:
192 ALOGE("Unknown JPEG format `%08Xh", iV4l2JpegFormat);
193 return -1;
194 }
195
196 if (!m_hwjpeg.SetChromaSampFactor(hfactor, vfactor))
197 return -1;
198
199 m_jpegFormat = iV4l2JpegFormat;
200
201 return 0;
202 }
203
setColorBufSize(int * piBufSize,int iSize)204 int ExynosJpegEncoder::setColorBufSize(int *piBufSize, int iSize)
205 {
206 size_t len[3];
207 unsigned int num = static_cast<unsigned int>(iSize);
208
209 if (!m_hwjpeg.GetImageBufferSizes(len, &num))
210 return -1;
211
212 for (unsigned int i = 0; i < num; i++)
213 piBufSize[i] = static_cast<int>(len[i]);
214
215 return 0;
216 }
217
__EnsureFormatIsApplied()218 bool ExynosJpegEncoder::__EnsureFormatIsApplied() {
219 if (TestStateEither(STATE_SIZE_CHANGED | STATE_PIXFMT_CHANGED) &&
220 !m_hwjpeg.SetImageFormat(m_v4l2Format, m_nWidth, m_nHeight))
221 return false;
222
223 ClearState(STATE_SIZE_CHANGED | STATE_PIXFMT_CHANGED);
224 return true;
225 }
226
setQuality(const unsigned char q_table[])227 int ExynosJpegEncoder::setQuality(const unsigned char q_table[]) {
228 return m_hwjpeg.SetQuality(q_table) ? 0 : -1;
229 }
230