/* * Copyright Samsung Electronics Co.,LTD. * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <ctype.h> #include <unistd.h> #include <sys/mman.h> #include <string.h> #include <errno.h> #include <signal.h> #include <math.h> #include <sys/poll.h> #include <cutils/log.h> #include <utils/Log.h> #include "ExynosJpegApi.h" #define JPEG_DEC_NODE "/dev/video11" #define JPEG_ENC_NODE "/dev/video12" #define MAX_JPG_WIDTH (8192) #define MAX_JPG_HEIGHT (8192) #define JPEG_ERROR_LOG(fmt,...) ExynosJpegBase::ExynosJpegBase() { } ExynosJpegBase::~ExynosJpegBase() { } int ExynosJpegBase::t_v4l2Querycap(int iFd) { struct v4l2_capability cap; int iRet = ERROR_NONE; iRet = ioctl(iFd, VIDIOC_QUERYCAP, &cap); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYCAP failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2SetJpegcomp(int iFd, int iQuality) { struct v4l2_jpegcompression arg; int iRet = ERROR_NONE; arg.quality = iQuality; iRet = ioctl(iFd, VIDIOC_S_JPEGCOMP, &arg); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_JPEGCOMP failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2SetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig) { struct v4l2_format fmt; int iRet = ERROR_NONE; fmt.type = eType; fmt.fmt.pix_mp.width = pstConfig->width; fmt.fmt.pix_mp.height = pstConfig->height; fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; fmt.fmt.pix_mp.num_planes = pstConfig->numOfPlanes; if (pstConfig->mode == MODE_ENCODE) fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; switch (fmt.type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through case V4L2_BUF_TYPE_VIDEO_CAPTURE: break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: if (pstConfig->mode == MODE_ENCODE) { fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.in_fmt; } else { fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.in_fmt; fmt.fmt.pix_mp.plane_fmt[0].sizeimage = pstConfig->sizeJpeg; } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: if (pstConfig->mode == MODE_ENCODE) { fmt.fmt.pix_mp.pixelformat = pstConfig->pix.enc_fmt.out_fmt; } else { fmt.fmt.pix_mp.pixelformat = pstConfig->pix.dec_fmt.out_fmt; fmt.fmt.pix_mp.width = pstConfig->scaled_width; fmt.fmt.pix_mp.height = pstConfig->scaled_height; } break; default: return ERROR_INVALID_V4l2_BUF_TYPE; break; } iRet = ioctl(iFd, VIDIOC_S_FMT, &fmt); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: VIDIOC_S_FMT failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2GetFmt(int iFd, enum v4l2_buf_type eType, struct CONFIG *pstConfig) { struct v4l2_format fmt; int iRet = ERROR_NONE; fmt.type = eType; iRet = ioctl(iFd, VIDIOC_G_FMT, &fmt); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: VIDIOC_G_FMT failed\n", __func__, iRet); return iRet; } switch (fmt.type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: // fall through case V4L2_BUF_TYPE_VIDEO_CAPTURE: pstConfig->width = fmt.fmt.pix.width; pstConfig->height = fmt.fmt.pix.height; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: pstConfig->width = fmt.fmt.pix_mp.width; pstConfig->height = fmt.fmt.pix_mp.height; if (pstConfig->mode == MODE_ENCODE) pstConfig->pix.enc_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; else pstConfig->pix.dec_fmt.in_fmt = fmt.fmt.pix_mp.pixelformat; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: pstConfig->width = fmt.fmt.pix_mp.width; pstConfig->height = fmt.fmt.pix_mp.height; if (pstConfig->mode == MODE_ENCODE) pstConfig->pix.enc_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; else pstConfig->pix.dec_fmt.out_fmt = fmt.fmt.pix_mp.pixelformat; break; default: return ERROR_INVALID_V4l2_BUF_TYPE; } return iRet; } int ExynosJpegBase::t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo) { struct v4l2_requestbuffers req; int iRet = ERROR_NONE; memset(&req, 0, sizeof(v4l2_requestbuffers)); req.type = pstBufInfo->buf_type; req.memory = pstBufInfo->memory; //if (pstBufInfo->memory == V4L2_MEMORY_MMAP) req.count = iBufCount; iRet = ioctl(iFd, VIDIOC_REQBUFS, &req); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: VIDIOC_REQBUFS failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2Qbuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf) { struct v4l2_buffer v4l2_buf; struct v4l2_plane plane[JPEG_MAX_PLANE_CNT]; int i; int iRet = ERROR_NONE; memset(&v4l2_buf, 0, sizeof(struct v4l2_buffer)); memset(plane, 0, (int)JPEG_MAX_PLANE_CNT * sizeof(struct v4l2_plane)); v4l2_buf.index = 0; v4l2_buf.type = pstBufInfo->buf_type; v4l2_buf.memory = pstBufInfo->memory; v4l2_buf.field = V4L2_FIELD_ANY; v4l2_buf.length = pstBufInfo->numOfPlanes; v4l2_buf.m.planes = plane; if (pstBufInfo->memory == V4L2_MEMORY_DMABUF) { for (i = 0; i < pstBufInfo->numOfPlanes; i++) { v4l2_buf.m.planes[i].m.fd = (unsigned long)pstBuf->addr[i]; v4l2_buf.m.planes[i].length = pstBuf->size[i]; } } iRet = ioctl(iFd, VIDIOC_QBUF, &v4l2_buf); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d] VIDIOC_QBUF failed\n", __func__, iRet); pstBuf->numOfPlanes = 0; return iRet; } return iRet; } int ExynosJpegBase::t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory, int iNumPlanes) { struct v4l2_buffer buf; struct v4l2_plane planes[3]; int iRet = ERROR_NONE; memset(&buf, 0, sizeof(struct v4l2_buffer)); memset(planes, 0, sizeof(struct v4l2_plane)*3); buf.type = eType; buf.memory = eMemory; buf.length = iNumPlanes; buf.m.planes = planes; iRet = ioctl(iFd, VIDIOC_DQBUF, &buf); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d] VIDIOC_DQBUF failed\n", __func__, iRet); return iRet; } #ifdef KERNEL_33_JPEG_API if ((eType == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) && \ (t_stJpegConfig.mode == MODE_ENCODE)) { t_stJpegConfig.sizeJpeg = buf.m.planes[0].bytesused; } #endif return iRet; } int ExynosJpegBase::t_v4l2StreamOn(int iFd, enum v4l2_buf_type eType) { int iRet = ERROR_NONE; iRet = ioctl(iFd, VIDIOC_STREAMON, &eType); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMON failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2StreamOff(int iFd, enum v4l2_buf_type eType) { int iRet = ERROR_NONE; iRet = ioctl(iFd, VIDIOC_STREAMOFF, &eType); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d] VIDIOC_STREAMOFF failed\n", __func__, iRet); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2SetCtrl(int iFd, int iCid, int iValue) { struct v4l2_control vc; int iRet = ERROR_NONE; vc.id = iCid; vc.value = iValue; iRet = ioctl(iFd, VIDIOC_S_CTRL, &vc); if (iRet < 0) { JPEG_ERROR_LOG("[%s] VIDIOC_S_CTRL failed : cid(%d), value(%d)\n", __func__, iCid, iValue); return iRet; } return iRet; } int ExynosJpegBase::t_v4l2GetCtrl(int iFd, int iCid) { struct v4l2_control ctrl; int iRet = ERROR_NONE; ctrl.id = iCid; iRet = ioctl(iFd, VIDIOC_G_CTRL, &ctrl); if (iRet < 0) { JPEG_ERROR_LOG("[%s] VIDIOC_G_CTRL failed : cid(%d)\n", __func__, ctrl.id); return iRet; } return ctrl.value; } int ExynosJpegBase::create(enum MODE eMode) { if (t_bFlagCreate == true) { return ERROR_JPEG_DEVICE_ALREADY_CREATE; } int iRet = ERROR_NONE; switch (eMode) { case MODE_ENCODE: t_iJpegFd = open(JPEG_ENC_NODE, O_RDWR, 0); break; case MODE_DECODE: t_iJpegFd = open(JPEG_DEC_NODE, O_RDWR, 0); break; default: t_iJpegFd = -1; return ERROR_INVALID_JPEG_MODE; break; } if (t_iJpegFd < 0) { t_iJpegFd = -1; JPEG_ERROR_LOG("[%s]: JPEG_NODE open failed\n", __func__); return ERROR_CANNOT_OPEN_JPEG_DEVICE; } if (t_iJpegFd <= 0) { t_iJpegFd = -1; JPEG_ERROR_LOG("ERR(%s):JPEG device was closed\n", __func__); return ERROR_JPEG_DEVICE_ALREADY_CLOSED; } iRet = t_v4l2Querycap(t_iJpegFd); if (iRet < 0) { JPEG_ERROR_LOG("[%s]: QUERYCAP failed\n", __func__); close(t_iJpegFd); return ERROR_CANNOT_OPEN_JPEG_DEVICE; } memset(&t_stJpegConfig, 0, sizeof(struct CONFIG)); memset(&t_stJpegInbuf, 0, sizeof(struct BUFFER)); memset(&t_stJpegOutbuf, 0, sizeof(struct BUFFER)); t_stJpegConfig.mode = eMode; t_bFlagCreate = true; t_bFlagCreateInBuf = false; t_bFlagCreateOutBuf = false; t_bFlagExcute = false; t_iPlaneNum = 0; return ERROR_NONE; } int ExynosJpegBase::destroy(int iInBufs, int iOutBufs) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_ALREADY_DESTROY; } if (t_iJpegFd > 0) { struct BUF_INFO stBufInfo; if (t_bFlagExcute) { t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); t_v4l2StreamOff(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); } if (t_bFlagExcute) { stBufInfo.numOfPlanes = iInBufs; stBufInfo.memory = V4L2_MEMORY_MMAP; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); stBufInfo.numOfPlanes = iOutBufs; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; t_v4l2Reqbufs(t_iJpegFd, 0, &stBufInfo); } close(t_iJpegFd); } t_iJpegFd = -1; t_bFlagCreate = false; return ERROR_NONE; } int ExynosJpegBase::setSize(int iW, int iH) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } if (iW < 0 || MAX_JPG_WIDTH < iW) { return ERROR_INVALID_IMAGE_SIZE; } if (iH < 0 || MAX_JPG_HEIGHT < iH) { return ERROR_INVALID_IMAGE_SIZE; } t_stJpegConfig.width = iW; t_stJpegConfig.height = iH; return ERROR_NONE; } int ExynosJpegBase::setJpegConfig(enum MODE eMode, void *pConfig) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } if (pConfig == NULL) { return ERROR_JPEG_CONFIG_POINTER_NULL; } memcpy(&t_stJpegConfig, pConfig, sizeof(struct CONFIG)); switch (eMode) { case MODE_ENCODE: switch (t_stJpegConfig.pix.enc_fmt.in_fmt) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_BGR32: case V4L2_PIX_FMT_RGB32: t_iPlaneNum = 1; break; default: JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, t_stJpegConfig.pix.enc_fmt.in_fmt); t_iPlaneNum = 0; return ERROR_INVALID_COLOR_FORMAT; } break; case MODE_DECODE: switch (t_stJpegConfig.pix.dec_fmt.out_fmt) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_BGR32: case V4L2_PIX_FMT_RGB32: t_iPlaneNum = 1; break; default: JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, t_stJpegConfig.pix.dec_fmt.out_fmt); t_iPlaneNum = 0; return ERROR_INVALID_COLOR_FORMAT; } break; default: t_iPlaneNum = 0; return ERROR_INVALID_JPEG_MODE; break; } return ERROR_NONE; } void *ExynosJpegBase::getJpegConfig(void) { if (t_bFlagCreate == false) { return NULL; } return &t_stJpegConfig; } int ExynosJpegBase::getBuf(bool bCreateBuf, struct BUFFER *pstBuf, int *piBuf, int *iBufSize, int iSize, int iPlaneNum) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } if (bCreateBuf == false) { return ERROR_BUF_NOT_SET_YET; } if ((piBuf == NULL) || (iSize == 0)) { return ERROR_BUFFR_IS_NULL; } if (iSize < iPlaneNum) { return ERROR_BUFFER_TOO_SMALL; } for (int i=0;i<iPlaneNum;i++) { piBuf[i] = pstBuf->addr[i]; } for (int i=0;i<iPlaneNum;i++) { iBufSize[i] = pstBuf->size[i]; } return ERROR_NONE; } int ExynosJpegBase::setBuf(struct BUFFER *pstBuf, int *piBuf, int *iSize, int iPlaneNum) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } if (iPlaneNum <= 0) { return ERROR_BUFFER_TOO_SMALL; } for(int i=0;i<iPlaneNum;i++) { if (piBuf[i] == NULL) { memset(pstBuf, 0, sizeof(struct BUFFER)); return ERROR_BUFFR_IS_NULL; } if (iSize[i] <= 0) { memset(pstBuf, 0, sizeof(struct BUFFER)); return ERROR_BUFFER_TOO_SMALL; } pstBuf->addr[i] = piBuf[i]; pstBuf->size[i] = iSize[i]; } pstBuf->numOfPlanes = iPlaneNum; return ERROR_NONE; } int ExynosJpegBase::setCache(int iValue) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } if (t_v4l2SetCtrl(t_iJpegFd, V4L2_CID_CACHEABLE, iValue)<0) { JPEG_ERROR_LOG("%s::cache setting failed\n", __func__); return ERROR_CANNOT_CHANGE_CACHE_SETTING; } return ERROR_NONE; } int ExynosJpegBase::setColorFormat(enum MODE eMode, int iV4l2ColorFormat) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } switch(iV4l2ColorFormat) { case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_BGR32: case V4L2_PIX_FMT_RGB32: switch (eMode) { case MODE_ENCODE: t_stJpegConfig.pix.enc_fmt.in_fmt = iV4l2ColorFormat; break; case MODE_DECODE: t_stJpegConfig.pix.dec_fmt.out_fmt = iV4l2ColorFormat; break; default: return ERROR_INVALID_JPEG_MODE; break; } break; default: JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, iV4l2ColorFormat); t_iPlaneNum = 0; return ERROR_INVALID_COLOR_FORMAT; break; } switch (iV4l2ColorFormat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_BGR32: case V4L2_PIX_FMT_RGB32: t_iPlaneNum = 1; break; default: JPEG_ERROR_LOG("%s::Invalid input color format(%d) fail\n", __func__, iV4l2ColorFormat); t_iPlaneNum = 0; return ERROR_INVALID_COLOR_FORMAT; } return ERROR_NONE; } int ExynosJpegBase::setJpegFormat(enum MODE eMode, int iV4l2JpegFormat) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } switch(iV4l2JpegFormat) { case V4L2_PIX_FMT_JPEG_444: case V4L2_PIX_FMT_JPEG_422: case V4L2_PIX_FMT_JPEG_420: case V4L2_PIX_FMT_JPEG_GRAY: switch (eMode) { case MODE_ENCODE: t_stJpegConfig.pix.enc_fmt.out_fmt = iV4l2JpegFormat; break; case MODE_DECODE: t_stJpegConfig.pix.dec_fmt.in_fmt = iV4l2JpegFormat; break; default: return ERROR_INVALID_JPEG_MODE; break; } break; default: return ERROR_INVALID_JPEG_FORMAT; break; } return ERROR_NONE; } int ExynosJpegBase::setColorBufSize(enum MODE eMode, int *piBufSize, int iSize) { int iFormat; switch (eMode) { case MODE_ENCODE: iFormat = t_stJpegConfig.pix.enc_fmt.in_fmt; break; case MODE_DECODE: iFormat = t_stJpegConfig.pix.dec_fmt.out_fmt; break; default: return ERROR_INVALID_JPEG_MODE; break; } return setColorBufSize(iFormat, piBufSize, iSize, t_stJpegConfig.width, t_stJpegConfig.height); } int ExynosJpegBase::setColorBufSize(int iFormat, int *piBufSize, int iSize, int width, int height) { int pBufSize[3]; if(iSize>3) { return ERROR_INVALID_IMAGE_SIZE; } switch (iFormat) { case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_NV16: pBufSize[0] = width*height*2; pBufSize[1] = 0; pBufSize[2] = 0; break; case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_BGR32: pBufSize[0] = width*height*4; pBufSize[1] = 0; pBufSize[2] = 0; break; case V4L2_PIX_FMT_YUV420: pBufSize[0] = (width*height*3)/2; pBufSize[1] = 0; pBufSize[2] = 0; break; default: pBufSize[0] = width*height*4; pBufSize[1] = width*height*4; pBufSize[2] = width*height*4; break; } memcpy(piBufSize, pBufSize, iSize*sizeof(int)); return ERROR_NONE; } int ExynosJpegBase::updateConfig(enum MODE eMode, int iInBufs, int iOutBufs, int iInBufPlanes, int iOutBufPlanes) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } int iRet = ERROR_NONE; if (eMode == MODE_ENCODE) { iRet = t_v4l2SetJpegcomp(t_iJpegFd, t_stJpegConfig.enc_qual); if (iRet < 0) { JPEG_ERROR_LOG("[%s,%d]: S_JPEGCOMP failed\n", __func__,iRet); return ERROR_INVALID_JPEG_CONFIG; } } t_stJpegConfig.numOfPlanes = iInBufPlanes; t_stJpegConfig.mode = eMode; iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &t_stJpegConfig); if (iRet < 0) { JPEG_ERROR_LOG("[%s,%d]: jpeg input S_FMT failed\n", __func__,iRet); return ERROR_INVALID_JPEG_CONFIG; } struct BUF_INFO stBufInfo; stBufInfo.numOfPlanes = iInBufs; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; stBufInfo.memory = V4L2_MEMORY_DMABUF; iRet = t_v4l2Reqbufs(t_iJpegFd, iInBufs, &stBufInfo); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Input REQBUFS failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } t_stJpegConfig.numOfPlanes = iOutBufPlanes; iRet = t_v4l2SetFmt(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &t_stJpegConfig); if (iRet < 0) { JPEG_ERROR_LOG("[%s,%d]: jpeg output S_FMT failed\n", __func__,iRet); return ERROR_INVALID_JPEG_CONFIG; } stBufInfo.numOfPlanes = iOutBufs; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; iRet = t_v4l2Reqbufs(t_iJpegFd, iOutBufs, &stBufInfo); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Output REQBUFS failed\n", __func__, iRet); return ERROR_REQBUF_FAIL; } return ERROR_NONE; } int ExynosJpegBase::execute(int iInBufPlanes, int iOutBufPlanes) { if (t_bFlagCreate == false) { return ERROR_JPEG_DEVICE_NOT_CREATE_YET; } struct BUF_INFO stBufInfo; int iRet = ERROR_NONE; t_bFlagExcute = true; stBufInfo.numOfPlanes = iInBufPlanes; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; stBufInfo.memory = V4L2_MEMORY_DMABUF; iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegInbuf); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Input QBUF failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } stBufInfo.numOfPlanes = iOutBufPlanes; stBufInfo.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; iRet = t_v4l2Qbuf(t_iJpegFd, &stBufInfo, &t_stJpegOutbuf); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Output QBUF failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: input stream on failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } iRet = t_v4l2StreamOn(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: output stream on failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP, iInBufPlanes); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Intput DQBUF failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } iRet = t_v4l2Dqbuf(t_iJpegFd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP, iOutBufPlanes); if (iRet < 0) { JPEG_ERROR_LOG("[%s:%d]: Output DQBUF failed\n", __func__, iRet); return ERROR_EXCUTE_FAIL; } return ERROR_NONE; }