blob: b78212b1e140accc1ac4c3e71ad8e60bcfa92366 [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
2 * Copyright Samsung Electronics Co.,LTD.
3 * Copyright (C) 2011 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 <stdio.h>
19#include <stdlib.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <sys/ioctl.h>
23#include <fcntl.h>
24#include <ctype.h>
25#include <unistd.h>
26#include <sys/mman.h>
27#include <string.h>
28#include <errno.h>
29#include <signal.h>
30#include <math.h>
31#include <sys/poll.h>
32
33#include <cutils/log.h>
34
35#include <utils/Log.h>
36
37#include "SecJpegCodecHal.h"
38
39#define JPEG_ERROR_LOG(fmt,...)
40
41SecJpegCodecHal::SecJpegCodecHal()
42{
43}
44
45SecJpegCodecHal::~SecJpegCodecHal()
46{
47}
48
49int SecJpegCodecHal::t_v4l2Querycap(int iFd)
50{
51 struct v4l2_capability cap;
52 int iRet = ERROR_NONE;
53
54 iRet = ioctl(iFd, VIDIOC_QUERYCAP, &cap);
55 if (iRet < 0) {
56 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYCAP failed", __func__, iRet);
57 return iRet;
58 }
59
60 return iRet;
61}
62
63int SecJpegCodecHal::t_v4l2SetJpegcomp(int iFd, int iQuality)
64{
65 struct v4l2_jpegcompression arg;
66 int iRet = ERROR_NONE;
67
68 arg.quality = iQuality;
69
70 iRet = ioctl(iFd, VIDIOC_S_JPEGCOMP, &arg);
71 if (iRet < 0) {
72 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_JPEGCOMP failed", __func__, iRet);
73 return iRet;
74 }
75
76 return iRet;
77}
78
79int SecJpegCodecHal::t_v4l2SetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig)
80{
81 struct v4l2_format fmt;
82 int iRet = ERROR_NONE;
83
84 fmt.type = eType;
85 fmt.fmt.pix_mp.width = pstConfig->width;
86 fmt.fmt.pix_mp.height = pstConfig->height;
87 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
88 fmt.fmt.pix_mp.num_planes = pstConfig->numOfPlanes;
89
90 if (pstConfig->mode == MODE_ENCODE)
91 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG;
92
93 switch (fmt.type) {
94 case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through
95 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
96 break;
97 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
98 if (pstConfig->mode == MODE_ENCODE) {
99 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.in_fmt;
100 } else {
101 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.in_fmt;
102 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = pstConfig->sizeJpeg;
103 }
104 break;
105 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
106 if (pstConfig->mode == MODE_ENCODE) {
107 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.out_fmt;
108 } else {
109 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.out_fmt;
110 fmt.fmt.pix_mp.width = pstConfig->scaled_width;
111 fmt.fmt.pix_mp.height = pstConfig->scaled_height;
112 }
113 break;
114 default:
115 return -ERROR_INVALID_V4l2_BUF_TYPE;
116 break;
117 }
118
119 iRet = ioctl(iFd, VIDIOC_S_FMT, &fmt);
120 if (iRet < 0) {
121 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_FMT failed", __func__, iRet);
122 return iRet;
123 }
124
125 return iRet;
126}
127
128int SecJpegCodecHal::t_v4l2GetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig)
129{
130 struct v4l2_format fmt;
131 int iRet = ERROR_NONE;
132
133 fmt.type = eType;
134 iRet = ioctl(iFd, VIDIOC_G_FMT, &fmt);
135 if (iRet < 0) {
136 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_G_FMT failed", __func__, iRet);
137 return iRet;
138 }
139
140 switch (fmt.type) {
141 case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through
142 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
143 pstConfig->width = fmt.fmt.pix.width;
144 pstConfig->height = fmt.fmt.pix.height;
145 break;
146 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
147 pstConfig->width = fmt.fmt.pix_mp.width;
148 pstConfig->height = fmt.fmt.pix_mp.height;
149 if (pstConfig->mode == MODE_ENCODE)
150 pstConfig->pix.enc_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat;
151 else
152 pstConfig->pix.dec_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat;
153 break;
154 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
155 pstConfig->width = fmt.fmt.pix_mp.width;
156 pstConfig->height = fmt.fmt.pix_mp.height;
157 if (pstConfig->mode == MODE_ENCODE)
158 pstConfig->pix.enc_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat;
159 else
160 pstConfig->pix.dec_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat;
161 break;
162 default:
163 return -ERROR_INVALID_V4l2_BUF_TYPE;
164 }
165
166 return iRet;
167}
168
169int SecJpegCodecHal::t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo)
170{
171 struct v4l2_requestbuffers req;
172 int iRet = ERROR_NONE;
173
174 memset(&req, 0, sizeof(req));
175
176 req.type = pstBufInfo->buf_type;
177 req.memory = pstBufInfo->memory;
178
179 //if (pstBufInfo->memory == V4L2_MEMORY_MMAP)
180 req.count = iBufCount;
181
182 iRet = ioctl(iFd, VIDIOC_REQBUFS, &req);
183 if (iRet < 0) {
184 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_REQBUFS failed", __func__, iRet);
185 return iRet;
186 }
187
188 return iRet;
189}
190
191int SecJpegCodecHal::t_v4l2Querybuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf)
192{
193 struct v4l2_buffer v4l2_buf;
194 struct v4l2_plane plane[JPEG_MAX_PLANE_CNT];
195 int iRet = ERROR_NONE;
196 int i;
197
198 memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane));
199
200 v4l2_buf.index = 0;
201 v4l2_buf.type = pstBufInfo->buf_type;
202 v4l2_buf.memory = pstBufInfo->memory;
203 v4l2_buf.length = pstBufInfo->numOfPlanes;
204 v4l2_buf.m.planes = plane;
205
206 iRet = ioctl(iFd, VIDIOC_QUERYBUF, &v4l2_buf);
207 if (iRet < 0) {
208 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYBUF failed", __func__, iRet);
209 return iRet;
210 }
211
212 for (i= 0; i < v4l2_buf.length; i++) {
213 pstBuf->size[i] = v4l2_buf.m.planes[i].length;
214 pstBuf->addr[i] = (char *) mmap(0,
215 pstBuf->size[i],
216 PROT_READ | PROT_WRITE, MAP_SHARED, iFd,
217 v4l2_buf.m.planes[i].m.mem_offset);
218
219 if (pstBuf->addr[i] == MAP_FAILED) {
220 JPEG_ERROR_LOG("[%s]: mmap failed", __func__);
221 return -ERROR_MMAP_FAILED;
222 }
223 }
224
225 return iRet;
226}
227
228int SecJpegCodecHal::t_v4l2Qbuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf)
229{
230 struct v4l2_buffer v4l2_buf;
231 struct v4l2_plane plane[JPEG_MAX_PLANE_CNT];
232 int i;
233 int iRet = ERROR_NONE;
234
235 memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer));
236 memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane));
237
238 v4l2_buf.index = 0;
239 v4l2_buf.type = pstBufInfo->buf_type;
240 v4l2_buf.memory = pstBufInfo->memory;
241 v4l2_buf.length = pstBufInfo->numOfPlanes;
242 v4l2_buf.m.planes = plane;
243
244 if (pstBufInfo->memory == V4L2_MEMORY_USERPTR) {
245 for (i = 0; i < pstBufInfo->numOfPlanes; i++) {
246 v4l2_buf.m.planes[i].m.userptr = (unsigned long)pstBuf->addr[i];
247 v4l2_buf.m.planes[i].length = pstBuf->size[i];
248 }
249 }
250
251 iRet = ioctl(iFd, VIDIOC_QBUF, &v4l2_buf);
252 if (iRet < 0) {
253 JPEG_ERROR_LOG("[%s:%d] VIDIOC_QBUF failed", __func__, iRet);
254 pstBuf->numOfPlanes = 0;
255 return iRet;
256 }
257
258 return iRet;
259}
260
261int SecJpegCodecHal::t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory)
262{
263 struct v4l2_buffer buf;
264 int iRet = ERROR_NONE;
265
266 memset(&buf, 0, sizeof(struct v4l2_buffer));
267
268 buf.type = eType;
269 buf.memory = eMemory;
270
271 iRet = ioctl(iFd, VIDIOC_DQBUF, &buf);
272 if (iRet < 0) {
273 JPEG_ERROR_LOG("[%s:%d] VIDIOC_DQBUF failed", __func__, iRet);
274 return iRet;
275 }
276
277 return iRet;
278}
279
280int SecJpegCodecHal::t_v4l2StreamOn(int iFd, enum v4l2_buf_type eType)
281{
282 int iRet = ERROR_NONE;
283
284 iRet = ioctl(iFd, VIDIOC_STREAMON, &eType);
285 if (iRet < 0) {
286 JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMON failed", __func__, iRet);
287 return iRet;
288 }
289
290 return iRet;
291}
292
293int SecJpegCodecHal::t_v4l2StreamOff(int iFd, enum v4l2_buf_type eType)
294{
295 int iRet = ERROR_NONE;
296
297 iRet = ioctl(iFd, VIDIOC_STREAMOFF, &eType);
298 if (iRet < 0) {
299 JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMOFF failed", __func__, iRet);
300 return iRet;
301 }
302
303 return iRet;
304}
305
306int SecJpegCodecHal::t_v4l2SetCtrl(int iFd, int iCid, int iValue)
307{
308 struct v4l2_control vc;
309 int iRet = ERROR_NONE;
310
311 vc.id = iCid;
312 vc.value = iValue;
313
314 iRet = ioctl(iFd, VIDIOC_S_CTRL, &vc);
315 if (iRet < 0) {
316 JPEG_ERROR_LOG("[%s] VIDIOC_S_CTRL failed : cid(%d), value(%d)\n", __func__, iCid, iValue);
317 return iRet;
318 }
319
320 return iRet;
321}
322
323int SecJpegCodecHal::t_v4l2GetCtrl(int iFd, int iCid)
324{
325 struct v4l2_control ctrl;
326 int iRet = ERROR_NONE;
327
328 ctrl.id = iCid;
329
330 iRet = ioctl(iFd, VIDIOC_G_CTRL, &ctrl);
331 if (iRet < 0) {
332 JPEG_ERROR_LOG("[%s] VIDIOC_G_CTRL failed : cid(%d)\n", __func__, ctrl.id);
333 return iRet;
334 }
335
336 return ctrl.value;
337}
338