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