1 /*
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 "ExynosJpegApi.h"
38
39 #define JPEG_DEC_NODE "/dev/video11"
40 #define JPEG_ENC_NODE "/dev/video12"
41
42 #define MAX_JPG_WIDTH (8192)
43 #define MAX_JPG_HEIGHT (8192)
44
45 #define JPEG_ERROR_LOG(fmt,...)
46
ExynosJpegBase()47 ExynosJpegBase::ExynosJpegBase()
48 {
49 }
50
~ExynosJpegBase()51 ExynosJpegBase::~ExynosJpegBase()
52 {
53 }
54
t_v4l2Querycap(int iFd)55 int ExynosJpegBase::t_v4l2Querycap(int iFd)
56 {
57 struct v4l2_capability cap;
58 int iRet = ERROR_NONE;
59
60 iRet = ioctl(iFd, VIDIOC_QUERYCAP, &cap);
61 if (iRet < 0) {
62 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYCAP failed\n", __func__, iRet);
63 return iRet;
64 }
65
66 return iRet;
67 }
68
t_v4l2SetJpegcomp(int iFd,int iQuality)69 int ExynosJpegBase::t_v4l2SetJpegcomp(int iFd, int iQuality)
70 {
71 struct v4l2_jpegcompression arg;
72 int iRet = ERROR_NONE;
73
74 arg.quality = iQuality;
75
76 iRet = ioctl(iFd, VIDIOC_S_JPEGCOMP, &arg);
77 if (iRet < 0) {
78 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_JPEGCOMP failed\n", __func__, iRet);
79 return iRet;
80 }
81
82 return iRet;
83 }
84
t_v4l2SetFmt(int iFd,enum v4l2_buf_type eType,struct CONFIG * pstConfig)85 int ExynosJpegBase::t_v4l2SetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig)
86 {
87 struct v4l2_format fmt;
88 int iRet = ERROR_NONE;
89
90 fmt.type = eType;
91 fmt.fmt.pix_mp.width = pstConfig->width;
92 fmt.fmt.pix_mp.height = pstConfig->height;
93 fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
94 fmt.fmt.pix_mp.num_planes = pstConfig->numOfPlanes;
95
96 if (pstConfig->mode == MODE_ENCODE)
97 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG;
98
99 switch (fmt.type) {
100 case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through
101 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
102 break;
103 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
104 if (pstConfig->mode == MODE_ENCODE) {
105 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.in_fmt;
106 } else {
107 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.in_fmt;
108 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = pstConfig->sizeJpeg;
109 }
110 break;
111 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
112 if (pstConfig->mode == MODE_ENCODE) {
113 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.out_fmt;
114 } else {
115 fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.out_fmt;
116 fmt.fmt.pix_mp.width = pstConfig->scaled_width;
117 fmt.fmt.pix_mp.height = pstConfig->scaled_height;
118 }
119 break;
120 default:
121 return ERROR_INVALID_V4l2_BUF_TYPE;
122 break;
123 }
124
125 iRet = ioctl(iFd, VIDIOC_S_FMT, &fmt);
126 if (iRet < 0) {
127 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_FMT failed\n", __func__, iRet);
128 return iRet;
129 }
130
131 return iRet;
132 }
133
t_v4l2GetFmt(int iFd,enum v4l2_buf_type eType,struct CONFIG * pstConfig)134 int ExynosJpegBase::t_v4l2GetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig)
135 {
136 struct v4l2_format fmt;
137 int iRet = ERROR_NONE;
138
139 fmt.type = eType;
140 iRet = ioctl(iFd, VIDIOC_G_FMT, &fmt);
141 if (iRet < 0) {
142 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_G_FMT failed\n", __func__, iRet);
143 return iRet;
144 }
145
146 switch (fmt.type) {
147 case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through
148 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
149 pstConfig->width = fmt.fmt.pix.width;
150 pstConfig->height = fmt.fmt.pix.height;
151 break;
152 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
153 pstConfig->width = fmt.fmt.pix_mp.width;
154 pstConfig->height = fmt.fmt.pix_mp.height;
155 if (pstConfig->mode == MODE_ENCODE)
156 pstConfig->pix.enc_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat;
157 else
158 pstConfig->pix.dec_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat;
159 break;
160 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
161 pstConfig->width = fmt.fmt.pix_mp.width;
162 pstConfig->height = fmt.fmt.pix_mp.height;
163 if (pstConfig->mode == MODE_ENCODE)
164 pstConfig->pix.enc_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat;
165 else
166 pstConfig->pix.dec_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat;
167 break;
168 default:
169 return ERROR_INVALID_V4l2_BUF_TYPE;
170 }
171
172 return iRet;
173 }
174
t_v4l2Reqbufs(int iFd,int iBufCount,struct BUF_INFO * pstBufInfo)175 int ExynosJpegBase::t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo)
176 {
177 struct v4l2_requestbuffers req;
178 int iRet = ERROR_NONE;
179
180 memset(&req, 0, sizeof(v4l2_requestbuffers));
181
182 req.type = pstBufInfo->buf_type;
183 req.memory = pstBufInfo->memory;
184
185 //if (pstBufInfo->memory == V4L2_MEMORY_MMAP)
186 req.count = iBufCount;
187
188 iRet = ioctl(iFd, VIDIOC_REQBUFS, &req);
189 if (iRet < 0) {
190 JPEG_ERROR_LOG("[%s:%d]: VIDIOC_REQBUFS failed\n", __func__, iRet);
191 return iRet;
192 }
193
194 return iRet;
195 }
196
t_v4l2Qbuf(int iFd,struct BUF_INFO * pstBufInfo,struct BUFFER * pstBuf)197 int ExynosJpegBase::t_v4l2Qbuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf)
198 {
199 struct v4l2_buffer v4l2_buf;
200 struct v4l2_plane plane[JPEG_MAX_PLANE_CNT];
201 int i;
202 int iRet = ERROR_NONE;
203
204 memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer));
205 memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane));
206
207 v4l2_buf.index = 0;
208 v4l2_buf.type = pstBufInfo->buf_type;
209 v4l2_buf.memory = pstBufInfo->memory;
210 v4l2_buf.field = V4L2_FIELD_ANY;
211 v4l2_buf.length = pstBufInfo->numOfPlanes;
212 v4l2_buf.m.planes = plane;
213
214 if (pstBufInfo->memory == V4L2_MEMORY_DMABUF) {
215 for (i = 0; i < pstBufInfo->numOfPlanes; i++) {
216 v4l2_buf.m.planes[i].m.fd = (unsigned long)pstBuf->addr[i];
217 v4l2_buf.m.planes[i].length = pstBuf->size[i];
218 }
219 }
220
221 iRet = ioctl(iFd, VIDIOC_QBUF, &v4l2_buf);
222 if (iRet < 0) {
223 JPEG_ERROR_LOG("[%s:%d] VIDIOC_QBUF failed\n", __func__, iRet);
224 pstBuf->numOfPlanes = 0;
225 return iRet;
226 }
227
228 return iRet;
229 }
230
t_v4l2Dqbuf(int iFd,enum v4l2_buf_type eType,enum v4l2_memory eMemory,int iNumPlanes)231 int ExynosJpegBase::t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory, int iNumPlanes)
232 {
233 struct v4l2_buffer buf;
234 struct v4l2_plane planes[3];
235 int iRet = ERROR_NONE;
236
237 memset(&buf, 0, sizeof(struct v4l2_buffer));
238 memset(planes, 0, sizeof(struct v4l2_plane)*3);
239
240 buf.type = eType;
241 buf.memory = eMemory;
242 buf.length = iNumPlanes;
243 buf.m.planes = planes;
244
245 iRet = ioctl(iFd, VIDIOC_DQBUF, &buf);
246 if (iRet < 0) {
247 JPEG_ERROR_LOG("[%s:%d] VIDIOC_DQBUF failed\n", __func__, iRet);
248 return iRet;
249 }
250
251 #ifdef KERNEL_33_JPEG_API
252 if ((eType == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && \
253 (t_stJpegConfig.mode == MODE_ENCODE)) {
254 t_stJpegConfig.sizeJpeg = buf.m.planes[0].bytesused;
255 }
256 #endif
257
258 return iRet;
259 }
260
t_v4l2StreamOn(int iFd,enum v4l2_buf_type eType)261 int ExynosJpegBase::t_v4l2StreamOn(int iFd, enum v4l2_buf_type eType)
262 {
263 int iRet = ERROR_NONE;
264
265 iRet = ioctl(iFd, VIDIOC_STREAMON, &eType);
266 if (iRet < 0) {
267 JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMON failed\n", __func__, iRet);
268 return iRet;
269 }
270
271 return iRet;
272 }
273
t_v4l2StreamOff(int iFd,enum v4l2_buf_type eType)274 int ExynosJpegBase::t_v4l2StreamOff(int iFd, enum v4l2_buf_type eType)
275 {
276 int iRet = ERROR_NONE;
277
278 iRet = ioctl(iFd, VIDIOC_STREAMOFF, &eType);
279 if (iRet < 0) {
280 JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMOFF failed\n", __func__, iRet);
281 return iRet;
282 }
283
284 return iRet;
285 }
286
t_v4l2SetCtrl(int iFd,int iCid,int iValue)287 int ExynosJpegBase::t_v4l2SetCtrl(int iFd, int iCid, int iValue)
288 {
289 struct v4l2_control vc;
290 int iRet = ERROR_NONE;
291
292 vc.id = iCid;
293 vc.value = iValue;
294
295 iRet = ioctl(iFd, VIDIOC_S_CTRL, &vc);
296 if (iRet < 0) {
297 JPEG_ERROR_LOG("[%s] VIDIOC_S_CTRL failed : cid(%d), value(%d)\n", __func__, iCid, iValue);
298 return iRet;
299 }
300
301 return iRet;
302 }
303
t_v4l2GetCtrl(int iFd,int iCid)304 int ExynosJpegBase::t_v4l2GetCtrl(int iFd, int iCid)
305 {
306 struct v4l2_control ctrl;
307 int iRet = ERROR_NONE;
308
309 ctrl.id = iCid;
310
311 iRet = ioctl(iFd, VIDIOC_G_CTRL, &ctrl);
312 if (iRet < 0) {
313 JPEG_ERROR_LOG("[%s] VIDIOC_G_CTRL failed : cid(%d)\n", __func__, ctrl.id);
314 return iRet;
315 }
316
317 return ctrl.value;
318 }
319
create(enum MODE eMode)320 int ExynosJpegBase::create(enum MODE eMode)
321 {
322 if (t_bFlagCreate == true) {
323 return ERROR_JPEG_DEVICE_ALREADY_CREATE;
324 }
325
326 int iRet = ERROR_NONE;
327
328 switch (eMode) {
329 case MODE_ENCODE:
330 t_iJpegFd = open(JPEG_ENC_NODE, O_RDWR, 0);
331 break;
332 case MODE_DECODE:
333 t_iJpegFd = open(JPEG_DEC_NODE, O_RDWR, 0);
334 break;
335 default:
336 t_iJpegFd = -1;
337 return ERROR_INVALID_JPEG_MODE;
338 break;
339 }
340
341 if (t_iJpegFd < 0) {
342 t_iJpegFd = -1;
343 JPEG_ERROR_LOG("[%s]: JPEG_NODE open failed\n", __func__);
344 return ERROR_CANNOT_OPEN_JPEG_DEVICE;
345 }
346
347 if (t_iJpegFd <= 0) {
348 t_iJpegFd = -1;
349 JPEG_ERROR_LOG("ERR(%s):JPEG device was closed\n", __func__);
350 return ERROR_JPEG_DEVICE_ALREADY_CLOSED;
351 }
352
353 iRet = t_v4l2Querycap(t_iJpegFd);
354 if (iRet < 0) {
355 JPEG_ERROR_LOG("[%s]: QUERYCAP failed\n", __func__);
356 close(t_iJpegFd);
357 return ERROR_CANNOT_OPEN_JPEG_DEVICE;
358 }
359
360 memset(&t_stJpegConfig, 0, sizeof(struct CONFIG));
361 memset(&t_stJpegInbuf, 0, sizeof(struct BUFFER));
362 memset(&t_stJpegOutbuf, 0, sizeof(struct BUFFER));
363
364 t_stJpegConfig.mode = eMode;
365
366 t_bFlagCreate = true;
367 t_bFlagCreateInBuf = false;
368 t_bFlagCreateOutBuf = false;
369 t_bFlagExcute = false;
370
371 t_iPlaneNum = 0;
372
373 return ERROR_NONE;
374 }
375
destroy(int iInBufs,int iOutBufs)376 int ExynosJpegBase::destroy(int iInBufs, int iOutBufs)
377 {
378 if (t_bFlagCreate == false) {
379 return ERROR_JPEG_DEVICE_ALREADY_DESTROY;
380 }
381
382 if (t_iJpegFd > 0) {
383 struct BUF_INFO stBufInfo;
384
385 if (t_bFlagExcute) {
386 t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
387 t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
388 }
389
390 if (t_bFlagExcute) {
391 stBufInfo.numOfPlanes = iInBufs;
392 stBufInfo.memory = V4L2_MEMORY_MMAP;
393
394 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
395 t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo);
396
397 stBufInfo.numOfPlanes = iOutBufs;
398 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
399 t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo);
400 }
401
402 close(t_iJpegFd);
403 }
404
405 t_iJpegFd = -1;
406 t_bFlagCreate = false;
407 return ERROR_NONE;
408 }
409
setSize(int iW,int iH)410 int ExynosJpegBase::setSize(int iW, int iH)
411 {
412 if (t_bFlagCreate == false) {
413 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
414 }
415
416 if (iW < 0 || MAX_JPG_WIDTH < iW) {
417 return ERROR_INVALID_IMAGE_SIZE;
418 }
419
420 if (iH < 0 || MAX_JPG_HEIGHT < iH) {
421 return ERROR_INVALID_IMAGE_SIZE;
422 }
423
424 t_stJpegConfig.width = iW;
425 t_stJpegConfig.height = iH;
426
427 return ERROR_NONE;
428 }
429
setJpegConfig(enum MODE eMode,void * pConfig)430 int ExynosJpegBase::setJpegConfig(enum MODE eMode, void *pConfig)
431 {
432 if (t_bFlagCreate == false) {
433 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
434 }
435
436 if (pConfig == NULL) {
437 return ERROR_JPEG_CONFIG_POINTER_NULL;
438 }
439
440 memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG));
441
442 switch (eMode) {
443 case MODE_ENCODE:
444 switch (t_stJpegConfig.pix.enc_fmt.in_fmt) {
445 case V4L2_PIX_FMT_YUV420:
446 case V4L2_PIX_FMT_NV16:
447 case V4L2_PIX_FMT_YUYV:
448 case V4L2_PIX_FMT_RGB565X:
449 case V4L2_PIX_FMT_BGR32:
450 case V4L2_PIX_FMT_RGB32:
451 t_iPlaneNum = 1;
452 break;
453 default:
454 JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, t_stJpegConfig.pix.enc_fmt.in_fmt);
455 t_iPlaneNum = 0;
456 return ERROR_INVALID_COLOR_FORMAT;
457 }
458 break;
459 case MODE_DECODE:
460 switch (t_stJpegConfig.pix.dec_fmt.out_fmt) {
461 case V4L2_PIX_FMT_YUV420:
462 case V4L2_PIX_FMT_NV16:
463 case V4L2_PIX_FMT_YUYV:
464 case V4L2_PIX_FMT_RGB565X:
465 case V4L2_PIX_FMT_BGR32:
466 case V4L2_PIX_FMT_RGB32:
467 t_iPlaneNum = 1;
468 break;
469 default:
470 JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, t_stJpegConfig.pix.dec_fmt.out_fmt);
471 t_iPlaneNum = 0;
472 return ERROR_INVALID_COLOR_FORMAT;
473 }
474 break;
475 default:
476 t_iPlaneNum = 0;
477 return ERROR_INVALID_JPEG_MODE;
478 break;
479 }
480
481 return ERROR_NONE;
482 }
483
getJpegConfig(void)484 void *ExynosJpegBase::getJpegConfig(void)
485 {
486 if (t_bFlagCreate == false) {
487 return NULL;
488 }
489
490 return &t_stJpegConfig;
491 }
492
getBuf(bool bCreateBuf,struct BUFFER * pstBuf,int * piBuf,int * iBufSize,int iSize,int iPlaneNum)493 int ExynosJpegBase::getBuf(bool bCreateBuf, struct BUFFER *pstBuf, int *piBuf, int *iBufSize, int iSize, int iPlaneNum)
494 {
495 if (t_bFlagCreate == false) {
496 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
497 }
498
499 if (bCreateBuf == false) {
500 return ERROR_BUF_NOT_SET_YET;
501 }
502
503 if ((piBuf == NULL) || (iSize == 0)) {
504 return ERROR_BUFFR_IS_NULL;
505 }
506
507 if (iSize < iPlaneNum) {
508 return ERROR_BUFFER_TOO_SMALL;
509 }
510
511 for (int i=0;i<iPlaneNum;i++) {
512 piBuf[i] = pstBuf->addr[i];
513 }
514
515 for (int i=0;i<iPlaneNum;i++) {
516 iBufSize[i] = pstBuf->size[i];
517 }
518
519 return ERROR_NONE;
520 }
521
setBuf(struct BUFFER * pstBuf,int * piBuf,int * iSize,int iPlaneNum)522 int ExynosJpegBase::setBuf(struct BUFFER *pstBuf, int *piBuf, int *iSize, int iPlaneNum)
523 {
524 if (t_bFlagCreate == false) {
525 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
526 }
527
528 if (iPlaneNum <= 0) {
529 return ERROR_BUFFER_TOO_SMALL;
530 }
531
532 for(int i=0;i<iPlaneNum;i++) {
533 if (piBuf[i] == NULL) {
534 memset(pstBuf, 0, sizeof(struct BUFFER));
535 return ERROR_BUFFR_IS_NULL;
536 }
537 if (iSize[i] <= 0) {
538 memset(pstBuf, 0, sizeof(struct BUFFER));
539 return ERROR_BUFFER_TOO_SMALL;
540 }
541 pstBuf->addr[i] = piBuf[i];
542 pstBuf->size[i] = iSize[i];
543 }
544
545 pstBuf->numOfPlanes = iPlaneNum;
546
547 return ERROR_NONE;
548 }
549
setCache(int iValue)550 int ExynosJpegBase::setCache(int iValue)
551 {
552 if (t_bFlagCreate == false) {
553 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
554 }
555
556 if (t_v4l2SetCtrl(t_iJpegFd, V4L2_CID_CACHEABLE, iValue)<0) {
557 JPEG_ERROR_LOG("%s::cache setting failed\n", __func__);
558 return ERROR_CANNOT_CHANGE_CACHE_SETTING;
559 }
560
561 return ERROR_NONE;
562 }
563
setColorFormat(enum MODE eMode,int iV4l2ColorFormat)564 int ExynosJpegBase::setColorFormat(enum MODE eMode, int iV4l2ColorFormat)
565 {
566 if (t_bFlagCreate == false) {
567 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
568 }
569
570 switch(iV4l2ColorFormat) {
571 case V4L2_PIX_FMT_YUYV:
572 case V4L2_PIX_FMT_YUV420:
573 case V4L2_PIX_FMT_NV16:
574 case V4L2_PIX_FMT_RGB565X:
575 case V4L2_PIX_FMT_BGR32:
576 case V4L2_PIX_FMT_RGB32:
577 switch (eMode) {
578 case MODE_ENCODE:
579 t_stJpegConfig.pix.enc_fmt.in_fmt = iV4l2ColorFormat;
580 break;
581 case MODE_DECODE:
582 t_stJpegConfig.pix.dec_fmt.out_fmt = iV4l2ColorFormat;
583 break;
584 default:
585 return ERROR_INVALID_JPEG_MODE;
586 break;
587 }
588 break;
589 default:
590 JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, iV4l2ColorFormat);
591 t_iPlaneNum = 0;
592 return ERROR_INVALID_COLOR_FORMAT;
593 break;
594 }
595
596 switch (iV4l2ColorFormat) {
597 case V4L2_PIX_FMT_YUV420:
598 case V4L2_PIX_FMT_NV16:
599 case V4L2_PIX_FMT_YUYV:
600 case V4L2_PIX_FMT_RGB565X:
601 case V4L2_PIX_FMT_BGR32:
602 case V4L2_PIX_FMT_RGB32:
603 t_iPlaneNum = 1;
604 break;
605 default:
606 JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, iV4l2ColorFormat);
607 t_iPlaneNum = 0;
608 return ERROR_INVALID_COLOR_FORMAT;
609 }
610
611 return ERROR_NONE;
612 }
613
setJpegFormat(enum MODE eMode,int iV4l2JpegFormat)614 int ExynosJpegBase::setJpegFormat(enum MODE eMode, int iV4l2JpegFormat)
615 {
616 if (t_bFlagCreate == false) {
617 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
618 }
619
620 switch(iV4l2JpegFormat) {
621 case V4L2_PIX_FMT_JPEG_444:
622 case V4L2_PIX_FMT_JPEG_422:
623 case V4L2_PIX_FMT_JPEG_420:
624 case V4L2_PIX_FMT_JPEG_GRAY:
625 switch (eMode) {
626 case MODE_ENCODE:
627 t_stJpegConfig.pix.enc_fmt.out_fmt = iV4l2JpegFormat;
628 break;
629 case MODE_DECODE:
630 t_stJpegConfig.pix.dec_fmt.in_fmt = iV4l2JpegFormat;
631 break;
632 default:
633 return ERROR_INVALID_JPEG_MODE;
634 break;
635 }
636 break;
637 default:
638 return ERROR_INVALID_JPEG_FORMAT;
639 break;
640 }
641
642 return ERROR_NONE;
643 }
644
setColorBufSize(enum MODE eMode,int * piBufSize,int iSize)645 int ExynosJpegBase::setColorBufSize(enum MODE eMode, int *piBufSize, int iSize)
646 {
647 int iFormat;
648
649 switch (eMode) {
650 case MODE_ENCODE:
651 iFormat = t_stJpegConfig.pix.enc_fmt.in_fmt;
652 break;
653 case MODE_DECODE:
654 iFormat = t_stJpegConfig.pix.dec_fmt.out_fmt;
655 break;
656 default:
657 return ERROR_INVALID_JPEG_MODE;
658 break;
659 }
660
661 return setColorBufSize(iFormat, piBufSize, iSize, t_stJpegConfig.width, t_stJpegConfig.height);
662 }
663
setColorBufSize(int iFormat,int * piBufSize,int iSize,int width,int height)664 int ExynosJpegBase::setColorBufSize(int iFormat, int *piBufSize, int iSize, int width, int height)
665 {
666 int pBufSize[3];
667
668 if(iSize>3) {
669 return ERROR_INVALID_IMAGE_SIZE;
670 }
671
672 switch (iFormat) {
673 case V4L2_PIX_FMT_YUYV:
674 case V4L2_PIX_FMT_RGB565X:
675 case V4L2_PIX_FMT_NV16:
676 pBufSize[0] = width*height*2;
677 pBufSize[1] = 0;
678 pBufSize[2] = 0;
679 break;
680 case V4L2_PIX_FMT_RGB32:
681 case V4L2_PIX_FMT_BGR32:
682 pBufSize[0] = width*height*4;
683 pBufSize[1] = 0;
684 pBufSize[2] = 0;
685 break;
686 case V4L2_PIX_FMT_YUV420:
687 pBufSize[0] = (width*height*3)/2;
688 pBufSize[1] = 0;
689 pBufSize[2] = 0;
690 break;
691 default:
692 pBufSize[0] = width*height*4;
693 pBufSize[1] = width*height*4;
694 pBufSize[2] = width*height*4;
695 break;
696 }
697
698 memcpy(piBufSize, pBufSize, iSize*sizeof(int));
699
700 return ERROR_NONE;
701 }
702
updateConfig(enum MODE eMode,int iInBufs,int iOutBufs,int iInBufPlanes,int iOutBufPlanes)703 int ExynosJpegBase::updateConfig(enum MODE eMode, int iInBufs, int iOutBufs, int iInBufPlanes, int iOutBufPlanes)
704 {
705 if (t_bFlagCreate == false) {
706 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
707 }
708
709 int iRet = ERROR_NONE;
710
711 if (eMode == MODE_ENCODE) {
712 iRet = t_v4l2SetJpegcomp(t_iJpegFd, t_stJpegConfig.enc_qual);
713 if (iRet < 0) {
714 JPEG_ERROR_LOG("[%s,%d]: S_JPEGCOMP failed\n", __func__,iRet);
715 return ERROR_INVALID_JPEG_CONFIG;
716 }
717 }
718
719 t_stJpegConfig.numOfPlanes = iInBufPlanes;
720 t_stJpegConfig.mode = eMode;
721
722 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &t_stJpegConfig);
723 if (iRet < 0) {
724 JPEG_ERROR_LOG("[%s,%d]: jpeg input S_FMT failed\n", __func__,iRet);
725 return ERROR_INVALID_JPEG_CONFIG;
726 }
727
728 struct BUF_INFO stBufInfo;
729
730 stBufInfo.numOfPlanes = iInBufs;
731 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
732 stBufInfo.memory = V4L2_MEMORY_DMABUF;
733
734 iRet = t_v4l2Reqbufs(t_iJpegFd, iInBufs, &stBufInfo);
735 if (iRet < 0) {
736 JPEG_ERROR_LOG("[%s:%d]: Input REQBUFS failed\n", __func__, iRet);
737 return ERROR_EXCUTE_FAIL;
738 }
739
740 t_stJpegConfig.numOfPlanes = iOutBufPlanes;
741 iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &t_stJpegConfig);
742 if (iRet < 0) {
743 JPEG_ERROR_LOG("[%s,%d]: jpeg output S_FMT failed\n", __func__,iRet);
744 return ERROR_INVALID_JPEG_CONFIG;
745 }
746
747 stBufInfo.numOfPlanes = iOutBufs;
748 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
749
750 iRet = t_v4l2Reqbufs(t_iJpegFd, iOutBufs, &stBufInfo);
751 if (iRet < 0) {
752 JPEG_ERROR_LOG("[%s:%d]: Output REQBUFS failed\n", __func__, iRet);
753 return ERROR_REQBUF_FAIL;
754 }
755
756 return ERROR_NONE;
757 }
758
execute(int iInBufPlanes,int iOutBufPlanes)759 int ExynosJpegBase::execute(int iInBufPlanes, int iOutBufPlanes)
760 {
761 if (t_bFlagCreate == false) {
762 return ERROR_JPEG_DEVICE_NOT_CREATE_YET;
763 }
764
765 struct BUF_INFO stBufInfo;
766 int iRet = ERROR_NONE;
767
768 t_bFlagExcute = true;
769
770 stBufInfo.numOfPlanes = iInBufPlanes;
771 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
772
773 stBufInfo.memory = V4L2_MEMORY_DMABUF;
774
775 iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegInbuf);
776 if (iRet < 0) {
777 JPEG_ERROR_LOG("[%s:%d]: Input QBUF failed\n", __func__, iRet);
778 return ERROR_EXCUTE_FAIL;
779 }
780
781 stBufInfo.numOfPlanes = iOutBufPlanes;
782 stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
783
784 iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegOutbuf);
785 if (iRet < 0) {
786 JPEG_ERROR_LOG("[%s:%d]: Output QBUF failed\n", __func__, iRet);
787 return ERROR_EXCUTE_FAIL;
788 }
789
790 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
791 if (iRet < 0) {
792 JPEG_ERROR_LOG("[%s:%d]: input stream on failed\n", __func__, iRet);
793 return ERROR_EXCUTE_FAIL;
794 }
795 iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
796 if (iRet < 0) {
797 JPEG_ERROR_LOG("[%s:%d]: output stream on failed\n", __func__, iRet);
798 return ERROR_EXCUTE_FAIL;
799 }
800
801 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP, iInBufPlanes);
802 if (iRet < 0) {
803 JPEG_ERROR_LOG("[%s:%d]: Intput DQBUF failed\n", __func__, iRet);
804 return ERROR_EXCUTE_FAIL;
805 }
806 iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, iOutBufPlanes);
807 if (iRet < 0) {
808 JPEG_ERROR_LOG("[%s:%d]: Output DQBUF failed\n", __func__, iRet);
809 return ERROR_EXCUTE_FAIL;
810 }
811
812 return ERROR_NONE;
813 }
814
815