Commit | Line | Data |
---|---|---|
5763fb39 T |
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
92 | int ExynosJpegEncoder::setOutBuf(int iBuf, int iSize) | |
93 | { | |
94 | if (!m_hwjpeg.SetJpegBuffer(iBuf, static_cast<size_t>(iSize))) | |
95 | return -1; | |
96 | ||
97 | m_iOutBufType = JPEG_BUF_TYPE_DMA_BUF; | |
98 | ||
99 | return 0; | |
100 | } | |
101 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
227 | static unsigned char jpeg_zigzagorder[] = { | |
228 | 0, 1, 8, 16, 9, 2, 3, 10, | |
229 | 17, 24, 32, 25, 18, 11, 4, 5, | |
230 | 12, 19, 26, 33, 40, 48, 41, 34, | |
231 | 27, 20, 13, 6, 7, 14, 21, 28, | |
232 | 35, 42, 49, 56, 57, 50, 43, 36, | |
233 | 29, 22, 15, 23, 30, 37, 44, 51, | |
234 | 58, 59, 52, 45, 38, 31, 39, 46, | |
235 | 53, 60, 61, 54, 47, 55, 62, 63 | |
236 | }; | |
237 | ||
238 | int ExynosJpegEncoder::setQuality(const unsigned char q_table[]) { | |
239 | unsigned char qtbl[128]; | |
240 | ||
241 | for (unsigned int i = 0; i < ARRSIZE(jpeg_zigzagorder); i++) | |
242 | qtbl[i] = q_table[jpeg_zigzagorder[i]]; | |
243 | ||
244 | for (unsigned int i = 0; i < ARRSIZE(jpeg_zigzagorder); i++) | |
245 | qtbl[i + 64] = q_table[jpeg_zigzagorder[i] + 64]; | |
246 | ||
247 | if (!m_hwjpeg.SetQuality(qtbl)) | |
248 | return -1; | |
249 | ||
250 | return 0; | |
251 | } |