• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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