/*
* 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;
}