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 47 ExynosJpegBase::ExynosJpegBase() 48 { 49 } 50 51 ExynosJpegBase::~ExynosJpegBase() 52 { 53 } 54 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 484 void *ExynosJpegBase::getJpegConfig(void) 485 { 486 if (t_bFlagCreate == false) { 487 return NULL; 488 } 489 490 return &t_stJpegConfig; 491 } 492 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 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 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 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 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 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 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 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 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