blob: 12b9dfcbdb03d5890b2937270ab23f83031b85db [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
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020039#define JPEG_ERROR_ALOG(fmt,...)
codeworkx62f02ba2012-05-20 12:00:36 +020040
41#define NUM_PLANES (1)
42#define NUM_BUFFERS (1)
43
44SecJpegDecoderHal::SecJpegDecoderHal()
45{
46 t_iJpegFd = -1;
47 t_bFlagCreate = false;
48}
49
50SecJpegDecoderHal::~SecJpegDecoderHal()
51{
52 if (t_bFlagCreate == true) {
53 this->destroy();
54 }
55}
56
57int SecJpegDecoderHal::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_DEC_NODE, O_RDWR, 0);
66
67 if (t_iJpegFd < 0) {
68 t_iJpegFd = -1;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020069 JPEG_ERROR_ALOG("[%s]: JPEG_DEC_NODE open failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +020070 return ERROR_CANNOT_OPEN_JPEG_DEVICE;
71 }
72
73 if (t_iJpegFd <= 0) {
74 t_iJpegFd = -1;
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020075 JPEG_ERROR_ALOG("ERR(%s):JPEG device was closed\n", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +020076 return ERROR_JPEG_DEVICE_ALREADY_CLOSED;
77 }
78
79 iRet = t_v4l2Querycap(t_iJpegFd);
80 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +020081 JPEG_ERROR_ALOG("[%s]: QUERYCAP failed", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +020082 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_DECODE;
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 SecJpegDecoderHal::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 = NUM_PLANES;
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 = t_iPlaneNum;
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 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200130 JPEG_ERROR_ALOG("[%s:%d]: JPEG_DEC_NODE close failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200131 }
132 }
133
134 t_iJpegFd = -1;
135 t_bFlagCreate = false;
136 return ERROR_NONE;
137}
138
139int SecJpegDecoderHal::setSize(int iW, int iH)
140{
141 if (t_bFlagCreate == false) {
142 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
143 }
144
145 if (iW < 0 || MAX_JPG_WIDTH < iW) {
146 return ERROR_INVALID_IMAGE_SIZE;
147 }
148
149 if (iH < 0 || MAX_JPG_HEIGHT < iH) {
150 return ERROR_INVALID_IMAGE_SIZE;
151 }
152
153 t_stJpegConfig.width = iW;
154 t_stJpegConfig.height = iH;
155
156 return ERROR_NONE;
157}
158
159int SecJpegDecoderHal::setJpegConfig(void *pConfig)
160{
161 if (t_bFlagCreate == false) {
162 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
163 }
164
165 if (pConfig == NULL) {
166 return ERROR_JPEG_CONFIG_POINTER_NULL;
167 }
168
169 memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG));
170
171 if (t_stJpegConfig.pix.dec_fmt.out_fmt == V4L2_PIX_FMT_NV12) {
172 t_iPlaneNum = 2;
173 } else {
174 t_iPlaneNum = 1;
175 }
176
177 return ERROR_NONE;
178}
179
180void *SecJpegDecoderHal::getJpegConfig(void)
181{
182 if (t_bFlagCreate == false) {
183 return NULL;
184 }
185
186 return &t_stJpegConfig;
187}
188
189char *SecJpegDecoderHal::getInBuf(int *piInputSize)
190{
191 if (t_bFlagCreate == false) {
192 return NULL;
193 }
194
195 if (t_bFlagCreateInBuf == false) {
196
197 *piInputSize = 0;
198 return NULL;
199 }
200
201 *piInputSize = t_stJpegInbuf.size[0];
202
203 return (char *)(t_stJpegInbuf.addr[0]);
204}
205
206char **SecJpegDecoderHal::getOutBuf(int *piOutputSize)
207{
208 if (t_bFlagCreate == false) {
209 return NULL;
210 }
211
212 if (t_bFlagCreateOutBuf == false) {
213
214 *piOutputSize = 0;
215 return NULL;
216 }
217
218 for (int i=0;i<t_iPlaneNum;i++) {
219 piOutputSize[i] = t_stJpegOutbuf.size[i];
220 }
221
222 return t_stJpegOutbuf.addr;
223}
224
225int SecJpegDecoderHal::setInBuf(char *pcBuf, int iSize)
226{
227 if (t_bFlagCreate == false) {
228 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
229 }
230
231 if (pcBuf == NULL) {
232 return ERROR_BUFFR_IS_NULL;
233 }
234
235 if (iSize<=0) {
236 return ERROR_BUFFER_TOO_SMALL;
237 }
238
239 t_stJpegInbuf.addr[0] = pcBuf;
240 t_stJpegInbuf.size[0] = iSize;
241 t_stJpegInbuf.numOfPlanes = NUM_PLANES;
242
243 t_bFlagCreateInBuf = true;
244
245 return ERROR_NONE;
246}
247
248int SecJpegDecoderHal::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 for(int i=0;i<t_iPlaneNum;i++) {
263 t_stJpegOutbuf.addr[i] = pcBuf[i];
264 t_stJpegOutbuf.size[i] = iSize[i];
265 }
266
267 t_stJpegOutbuf.numOfPlanes = t_iPlaneNum;
268
269 t_bFlagCreateOutBuf = true;
270
271 return ERROR_NONE;
272}
273
274int SecJpegDecoderHal::setCache(int iValue)
275{
276 if (t_bFlagCreate == false) {
277 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
278 }
279
280 if (t_v4l2SetCtrl(t_iJpegFd, V4L2_CID_CACHEABLE, iValue)<0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200281 JPEG_ERROR_ALOG("%s::cache setting failed\n", __func__);
codeworkx62f02ba2012-05-20 12:00:36 +0200282 return ERROR_CANNOT_CHANGE_CACHE_SETTING;
283 }
284
285 return ERROR_NONE;
286}
287
288int SecJpegDecoderHal::getSize(int *piW, int *piH)
289{
290 if (t_bFlagCreate == false) {
291 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
292 }
293
294 int iRet = t_v4l2GetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &t_stJpegConfig);
295 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200296 JPEG_ERROR_ALOG("[%s,%d]: get image size failed", __func__,iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200297 return ERROR_GET_SIZE_FAIL;
298 }
299
300 *piW = t_stJpegConfig.width;
301 *piH = t_stJpegConfig.height;
302
303 return ERROR_NONE;
304}
305
306int SecJpegDecoderHal::setColorFormat(int iV4l2ColorFormat)
307{
308 if (t_bFlagCreate == false) {
309 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
310 }
311
312 switch(iV4l2ColorFormat) {
313 case V4L2_PIX_FMT_YUYV:
314 case V4L2_PIX_FMT_RGB565X:
315 case V4L2_PIX_FMT_BGR32:
316 case V4L2_PIX_FMT_RGB32:
317 t_stJpegConfig.pix.dec_fmt.out_fmt = iV4l2ColorFormat;
318 break;
319 default:
320 t_iPlaneNum = 0;
321 return ERROR_INVALID_COLOR_FORMAT;
322 break;
323 }
324
325 if (iV4l2ColorFormat == V4L2_PIX_FMT_NV12) {
326 t_iPlaneNum = 2;
327 } else {
328 t_iPlaneNum = 1;
329 }
330
331 return ERROR_NONE;
332}
333
334int SecJpegDecoderHal::setJpegFormat(int iV4l2JpegFormat)
335{
336 if (t_bFlagCreate == false) {
337 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
338 }
339
340 switch(iV4l2JpegFormat) {
341 case V4L2_PIX_FMT_JPEG_444:
342 case V4L2_PIX_FMT_JPEG_422:
343 case V4L2_PIX_FMT_JPEG_420:
344 case V4L2_PIX_FMT_JPEG_GRAY:
345 t_stJpegConfig.pix.dec_fmt.in_fmt = iV4l2JpegFormat;
346 break;
347 default:
348 return ERROR_INVALID_JPEG_FORMAT;
349 break;
350 }
351
352 return ERROR_NONE;
353}
354
355int SecJpegDecoderHal::updateConfig(void)
356{
357 if (t_bFlagCreate == false) {
358 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
359 }
360
361 int iRet = ERROR_NONE;
362
363 t_stJpegConfig.numOfPlanes = NUM_PLANES;
364
365 t_stJpegConfig.mode = MODE_DECODE;
366
367 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &t_stJpegConfig);
368 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200369 JPEG_ERROR_ALOG("[%s,%d]: jpeg input S_FMT failed", __func__,iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200370 return ERROR_INVALID_JPEG_CONFIG;
371 }
372
373 struct BUF_INFO stBufInfo;
374
375 stBufInfo.numOfPlanes = NUM_PLANES;
376 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
377 stBufInfo.memory = V4L2_MEMORY_USERPTR;
378
379 iRet = t_v4l2Reqbufs(t_iJpegFd, NUM_BUFFERS, &stBufInfo);
380 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200381 JPEG_ERROR_ALOG("[%s:%d]: Input REQBUFS failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200382 return ERROR_EXCUTE_FAIL;
383 }
384
385 t_stJpegConfig.numOfPlanes = t_iPlaneNum;
386 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &t_stJpegConfig);
387 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200388 JPEG_ERROR_ALOG("[%s,%d]: jpeg output S_FMT failed", __func__,iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200389 return ERROR_INVALID_JPEG_CONFIG;
390 }
391
392 stBufInfo.numOfPlanes = t_iPlaneNum;
393 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
394
395 iRet = t_v4l2Reqbufs(t_iJpegFd, NUM_BUFFERS, &stBufInfo);
396 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200397 JPEG_ERROR_ALOG("[%s:%d]: Output REQBUFS failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200398 return ERROR_REQBUF_FAIL;
399 }
400
401 return ERROR_NONE;
402}
403
404int SecJpegDecoderHal::setScaledSize(int iW, int iH)
405{
406 if (t_bFlagCreate == false) {
407 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
408 }
409
410 if (iW < 0 || MAX_JPG_WIDTH < iW) {
411 return ERROR_INVALID_IMAGE_SIZE;
412 }
413
414 if (iH < 0 || MAX_JPG_HEIGHT < iH) {
415 return ERROR_INVALID_IMAGE_SIZE;
416 }
417
418 t_stJpegConfig.scaled_width = iW;
419 t_stJpegConfig.scaled_height = iH;
420
421 return ERROR_NONE;
422}
423
424int SecJpegDecoderHal::setJpegSize(int iJpegSize)
425{
426 if (t_bFlagCreate == false) {
427 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
428 }
429
430 if (iJpegSize<=0) {
431 return ERROR_JPEG_SIZE_TOO_SMALL;
432 }
433
434 t_stJpegConfig.sizeJpeg = iJpegSize;
435
436 return ERROR_NONE;
437}
438
439int SecJpegDecoderHal::decode(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 = NUM_PLANES;
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) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200457 JPEG_ERROR_ALOG("[%s:%d]: Input QBUF failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200458 return ERROR_EXCUTE_FAIL;
459 }
460
461 stBufInfo.numOfPlanes = t_iPlaneNum;
462 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
463
464 iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegOutbuf);
465 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200466 JPEG_ERROR_ALOG("[%s:%d]: Output QBUF failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200467 return ERROR_EXCUTE_FAIL;
468 }
469
470 stBufInfo.numOfPlanes = NUM_PLANES;
471 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
472 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200473 JPEG_ERROR_ALOG("[%s:%d]: input stream on failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200474 return ERROR_EXCUTE_FAIL;
475 }
476 stBufInfo.numOfPlanes = t_iPlaneNum;
477 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
478 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200479 JPEG_ERROR_ALOG("[%s:%d]: output stream on failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200480 return ERROR_EXCUTE_FAIL;
481 }
482
483 stBufInfo.numOfPlanes = NUM_PLANES;
484 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP);
485 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200486 JPEG_ERROR_ALOG("[%s:%d]: Intput DQBUF failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200487 return ERROR_EXCUTE_FAIL;
488 }
489 stBufInfo.numOfPlanes = t_iPlaneNum;
490 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
491 if (iRet < 0) {
Daniel Hillenbrand0fdadca2012-07-22 15:45:33 +0200492 JPEG_ERROR_ALOG("[%s:%d]: Output DQBUF failed", __func__, iRet);
codeworkx62f02ba2012-05-20 12:00:36 +0200493 return ERROR_EXCUTE_FAIL;
494 }
495
496 return ERROR_NONE;
497}
498