blob: 1a3deca163ed3c585c99dec9b786247e5ab93954 [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
41#define NUM_PLANES (1)
42#define NUM_BUFFERS (1)
43
44SecJpegEncoderHal::SecJpegEncoderHal()
45{
46 t_iJpegFd = -1;
47 t_bFlagCreate = false;
48}
49
50SecJpegEncoderHal::~SecJpegEncoderHal()
51{
52 if (t_bFlagCreate == true) {
53 this->destroy();
54 }
55}
56
57int SecJpegEncoderHal::create(void)
58{
59 if (t_bFlagCreate == true) {
60 return ERROR_JPEG_DEVICE_ALREADY_CREATE;
61 }
62
63 int iRet = ERROR_NONE;
64
65 t_iJpegFd = open(JPEG_ENC_NODE, O_RDWR, 0);
66
67 if (t_iJpegFd < 0) {
68 t_iJpegFd = -1;
69 JPEG_ERROR_LOG("[%s]: JPEG_ENC_NODE open failed", __func__);
70 return ERROR_CANNOT_OPEN_JPEG_DEVICE;
71 }
72
73 if (t_iJpegFd <= 0) {
74 t_iJpegFd = -1;
75 JPEG_ERROR_LOG("ERR(%s):JPEG device was closed\n", __func__);
76 return ERROR_JPEG_DEVICE_ALREADY_CLOSED;
77 }
78
79 iRet = t_v4l2Querycap(t_iJpegFd);
80 if (iRet < 0) {
81 JPEG_ERROR_LOG("[%s]: QUERYCAP failed", __func__);
82 close(t_iJpegFd);
83 return ERROR_CANNOT_OPEN_JPEG_DEVICE;
84 }
85
86 memset(&t_stJpegConfig, 0, sizeof(struct CONFIG));
87 memset(&t_stJpegInbuf, 0, sizeof(struct BUFFER));
88 memset(&t_stJpegOutbuf, 0, sizeof(struct BUFFER));
89
90 t_stJpegConfig.mode = MODE_ENCODE;
91
92 t_bFlagCreate = true;
93 t_bFlagCreateInBuf = false;
94 t_bFlagCreateOutBuf = false;
95 t_bFlagExcute = false;
96
97 t_iPlaneNum = 0;
98
99 return ERROR_NONE;
100}
101
102int SecJpegEncoderHal::destroy(void)
103{
104 if (t_bFlagCreate == false) {
105 return ERROR_JPEG_DEVICE_ALREADY_DESTROY;
106 }
107
108 if (t_iJpegFd > 0) {
109 struct BUF_INFO stBufInfo;
110 int iRet = ERROR_NONE;
111
112 if (t_bFlagExcute) {
113 iRet = t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
114 }
115
116 if (t_bFlagExcute) {
117 stBufInfo.numOfPlanes = t_iPlaneNum;
118 stBufInfo.memory = V4L2_MEMORY_MMAP;
119
120 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
121 iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo);
122
123 stBufInfo.numOfPlanes = NUM_PLANES;
124 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
125 iRet = t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo);
126 }
127
128 iRet = close(t_iJpegFd);
129 }
130
131 t_iJpegFd = -1;
132 t_bFlagCreate = false;
133 return ERROR_NONE;
134}
135
136int SecJpegEncoderHal::setSize(int iW, int iH)
137{
138 if (t_bFlagCreate == false) {
139 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
140 }
141
142 if (iW < 0 || MAX_JPG_WIDTH < iW) {
143 return ERROR_INVALID_IMAGE_SIZE;
144 }
145
146 if (iH < 0 || MAX_JPG_HEIGHT < iH) {
147 return ERROR_INVALID_IMAGE_SIZE;
148 }
149
150 t_stJpegConfig.width = iW;
151 t_stJpegConfig.height = iH;
152
153 return ERROR_NONE;
154}
155
156int SecJpegEncoderHal::setJpegConfig(void *pConfig)
157{
158 if (t_bFlagCreate == false) {
159 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
160 }
161
162 if (pConfig == NULL) {
163 return ERROR_JPEG_CONFIG_POINTER_NULL;
164 }
165
166 memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG));
167
168 if (t_stJpegConfig.pix.enc_fmt.in_fmt == V4L2_PIX_FMT_NV12) {
169 t_iPlaneNum = 2;
170 } else {
171 t_iPlaneNum = 1;
172 }
173
174 return ERROR_NONE;
175}
176
177void *SecJpegEncoderHal::getJpegConfig(void)
178{
179 if (t_bFlagCreate == false) {
180 return NULL;
181 }
182
183 return &t_stJpegConfig;
184}
185
186char **SecJpegEncoderHal::getInBuf(int *piInputSize)
187{
188 if (t_bFlagCreate == false) {
189 return NULL;
190 }
191
192 if (t_bFlagCreateInBuf == false) {
193
194 *piInputSize = 0;
195 return NULL;
196 }
197
198 for (int i=0;i<t_iPlaneNum;i++) {
199 piInputSize[i] = t_stJpegInbuf.size[i];
200 }
201
202 return t_stJpegInbuf.addr;
203}
204
205char *SecJpegEncoderHal::getOutBuf(int *piOutputSize)
206{
207 if (t_bFlagCreate == false) {
208 return NULL;
209 }
210
211 if (t_bFlagCreateOutBuf == false) {
212
213 *piOutputSize = 0;
214 return NULL;
215 }
216
217 *piOutputSize = t_stJpegOutbuf.size[0];
218
219 return (char *)(t_stJpegOutbuf.addr[0]);
220}
221
222int SecJpegEncoderHal::setInBuf(char **pcBuf, int *iSize)
223{
224 if (t_bFlagCreate == false) {
225 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
226 }
227
228 if (pcBuf == NULL) {
229 return ERROR_BUFFR_IS_NULL;
230 }
231
232 if (iSize<=0) {
233 return ERROR_BUFFER_TOO_SMALL;
234 }
235
236 for(int i=0;i<t_iPlaneNum;i++) {
237 t_stJpegInbuf.addr[i] = pcBuf[i];
238 t_stJpegInbuf.size[i] = iSize[i];
239 }
240
241 t_stJpegInbuf.numOfPlanes = t_iPlaneNum;
242
243 t_bFlagCreateInBuf = true;
244
245 return ERROR_NONE;
246}
247
248int SecJpegEncoderHal::setOutBuf(char *pcBuf, int iSize)
249{
250 if (t_bFlagCreate == false) {
251 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
252 }
253
254 if (pcBuf == NULL) {
255 return ERROR_BUFFR_IS_NULL;
256 }
257
258 if (iSize<=0) {
259 return ERROR_BUFFER_TOO_SMALL;
260 }
261
262 t_stJpegOutbuf.addr[0] = pcBuf;
263 t_stJpegOutbuf.size[0] = iSize;
264 t_stJpegOutbuf.numOfPlanes = NUM_PLANES;
265
266 t_bFlagCreateOutBuf = true;
267
268 return ERROR_NONE;
269}
270
271int SecJpegEncoderHal::setCache(int iValue)
272{
273 if (t_bFlagCreate == false) {
274 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
275 }
276
277 if (t_v4l2SetCtrl(t_iJpegFd, V4L2_CID_CACHEABLE, iValue)<0) {
278 JPEG_ERROR_LOG("%s::cache setting failed\n", __func__);
279 return ERROR_CANNOT_CHANGE_CACHE_SETTING;
280 }
281
282 return ERROR_NONE;
283}
284
285int SecJpegEncoderHal::getSize(int *piW, int *piH)
286{
287 if (t_bFlagCreate == false) {
288 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
289 }
290
291 if (t_stJpegConfig.width == 0 && t_stJpegConfig.height == 0) {
292 return ERROR_SIZE_NOT_SET_YET;
293 }
294
295 *piW = t_stJpegConfig.width;
296 *piH = t_stJpegConfig.height;
297
298 return ERROR_NONE;
299}
300
301int SecJpegEncoderHal::setColorFormat(int iV4l2ColorFormat)
302{
303 if (t_bFlagCreate == false) {
304 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
305 }
306
307 switch(iV4l2ColorFormat) {
308 case V4L2_PIX_FMT_YUYV:
309 case V4L2_PIX_FMT_RGB565X:
310 case V4L2_PIX_FMT_BGR32:
311 case V4L2_PIX_FMT_RGB32:
312 t_stJpegConfig.pix.enc_fmt.in_fmt = iV4l2ColorFormat;
313 break;
314 default:
315 t_iPlaneNum = 0;
316 return ERROR_INVALID_COLOR_FORMAT;
317 break;
318 }
319
320 if (iV4l2ColorFormat == V4L2_PIX_FMT_NV12) {
321 t_iPlaneNum = 2;
322 } else {
323 t_iPlaneNum = 1;
324 }
325
326 return ERROR_NONE;
327}
328
329int SecJpegEncoderHal::setJpegFormat(int iV4l2JpegFormat)
330{
331 if (t_bFlagCreate == false) {
332 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
333 }
334
335 switch(iV4l2JpegFormat) {
336 case V4L2_PIX_FMT_JPEG_444:
337 case V4L2_PIX_FMT_JPEG_422:
338 case V4L2_PIX_FMT_JPEG_420:
339 case V4L2_PIX_FMT_JPEG_GRAY:
340 t_stJpegConfig.pix.enc_fmt.out_fmt = iV4l2JpegFormat;
341 break;
342 default:
343 return ERROR_INVALID_JPEG_FORMAT;
344 break;
345 }
346
347 return ERROR_NONE;
348}
349
350int SecJpegEncoderHal::updateConfig(void)
351{
352 if (t_bFlagCreate == false) {
353 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
354 }
355
356 int iRet = ERROR_NONE;
357
358 iRet = t_v4l2SetJpegcomp(t_iJpegFd, t_stJpegConfig.enc_qual);
359 if (iRet < 0) {
360 JPEG_ERROR_LOG("[%s,%d]: S_JPEGCOMP failed", __func__,iRet);
361 return ERROR_INVALID_JPEG_CONFIG;
362 }
363
364 t_stJpegConfig.numOfPlanes = t_iPlaneNum;
365
366 t_stJpegConfig.mode = MODE_ENCODE;
367
368 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &t_stJpegConfig);
369 if (iRet < 0) {
370 JPEG_ERROR_LOG("[%s,%d]: jpeg input S_FMT failed", __func__,iRet);
371 return ERROR_INVALID_JPEG_CONFIG;
372 }
373
374 struct BUF_INFO stBufInfo;
375
376 stBufInfo.numOfPlanes = t_iPlaneNum;
377 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
378 stBufInfo.memory = V4L2_MEMORY_USERPTR;
379
380 iRet = t_v4l2Reqbufs(t_iJpegFd, NUM_BUFFERS, &stBufInfo);
381 if (iRet < 0) {
382 JPEG_ERROR_LOG("[%s:%d]: Input REQBUFS failed", __func__, iRet);
383 return ERROR_EXCUTE_FAIL;
384 }
385
386 t_stJpegConfig.numOfPlanes = NUM_PLANES;
387 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &t_stJpegConfig);
388 if (iRet < 0) {
389 JPEG_ERROR_LOG("[%s,%d]: jpeg output S_FMT failed", __func__,iRet);
390 return ERROR_INVALID_JPEG_CONFIG;
391 }
392
393 stBufInfo.numOfPlanes = NUM_PLANES;
394 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
395
396 iRet = t_v4l2Reqbufs(t_iJpegFd, NUM_BUFFERS, &stBufInfo);
397 if (iRet < 0) {
398 JPEG_ERROR_LOG("[%s:%d]: Output REQBUFS failed", __func__, iRet);
399 return ERROR_REQBUF_FAIL;
400 }
401
402 return ERROR_NONE;
403}
404
405int SecJpegEncoderHal::setQuality(int iV4l2Quality)
406{
407 if (t_bFlagCreate == false) {
408 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
409 }
410
411 if (iV4l2Quality >= 90)
412 t_stJpegConfig.enc_qual = QUALITY_LEVEL_1;
413 else if (iV4l2Quality >= 80)
414 t_stJpegConfig.enc_qual = QUALITY_LEVEL_2;
415 else if (iV4l2Quality >= 70)
416 t_stJpegConfig.enc_qual = QUALITY_LEVEL_3;
417 else
418 t_stJpegConfig.enc_qual = QUALITY_LEVEL_4;
419
420 return ERROR_NONE;
421}
422
423int SecJpegEncoderHal::getJpegSize(void)
424{
425 if (t_bFlagCreate == false) {
426 return 0;
427 }
428
429 int iSize = t_v4l2GetCtrl(t_iJpegFd, V4L2_CID_CAM_JPEG_ENCODEDSIZE);
430
431 if (iSize < 0) {
432 JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__);
433 return 0;
434 }
435
436 return iSize;
437}
438
439int SecJpegEncoderHal::encode(void)
440{
441 if (t_bFlagCreate == false) {
442 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
443 }
444
445 struct BUF_INFO stBufInfo;
446 int iRet = ERROR_NONE;
447
448 t_bFlagExcute = true;
449
450 stBufInfo.numOfPlanes = t_iPlaneNum;
451 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
452
453 stBufInfo.memory = V4L2_MEMORY_USERPTR;
454
455 iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegInbuf);
456 if (iRet < 0) {
457 JPEG_ERROR_LOG("[%s:%d]: Input QBUF failed", __func__, iRet);
458 return ERROR_EXCUTE_FAIL;
459 }
460
461 stBufInfo.numOfPlanes = NUM_PLANES;
462 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
463
464 iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegOutbuf);
465 if (iRet < 0) {
466 JPEG_ERROR_LOG("[%s:%d]: Output QBUF failed", __func__, iRet);
467 return ERROR_EXCUTE_FAIL;
468 }
469
470 stBufInfo.numOfPlanes = t_iPlaneNum;
471 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
472 if (iRet < 0) {
473 JPEG_ERROR_LOG("[%s:%d]: input stream on failed", __func__, iRet);
474 return ERROR_EXCUTE_FAIL;
475 }
476 stBufInfo.numOfPlanes = NUM_PLANES;
477 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
478 if (iRet < 0) {
479 JPEG_ERROR_LOG("[%s:%d]: output stream on failed", __func__, iRet);
480 return ERROR_EXCUTE_FAIL;
481 }
482
483 stBufInfo.numOfPlanes = t_iPlaneNum;
484 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP);
485 if (iRet < 0) {
486 JPEG_ERROR_LOG("[%s:%d]: Intput DQBUF failed", __func__, iRet);
487 return ERROR_EXCUTE_FAIL;
488 }
489 stBufInfo.numOfPlanes = NUM_PLANES;
490 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
491 if (iRet < 0) {
492 JPEG_ERROR_LOG("[%s:%d]: Output DQBUF failed", __func__, iRet);
493 return ERROR_EXCUTE_FAIL;
494 }
495 return ERROR_NONE;
496}
497