You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
9.0 KiB
338 lines
9.0 KiB
/*
|
|
* 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 "SecJpegCodecHal.h"
|
|
|
|
#define JPEG_ERROR_LOG(fmt,...)
|
|
|
|
SecJpegCodecHal::SecJpegCodecHal()
|
|
{
|
|
}
|
|
|
|
SecJpegCodecHal::~SecJpegCodecHal()
|
|
{
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __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 SecJpegCodecHal::t_v4l2Reqbufs(int iFd, int iBufCount, struct BUF_INFO *pstBufInfo)
|
|
{
|
|
struct v4l2_requestbuffers req;
|
|
int iRet = ERROR_NONE;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
|
|
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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::t_v4l2Querybuf(int iFd, struct BUF_INFO *pstBufInfo, struct BUFFER *pstBuf)
|
|
{
|
|
struct v4l2_buffer v4l2_buf;
|
|
struct v4l2_plane plane[JPEG_MAX_PLANE_CNT];
|
|
int iRet = ERROR_NONE;
|
|
int i;
|
|
|
|
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.length = pstBufInfo->numOfPlanes;
|
|
v4l2_buf.m.planes = plane;
|
|
|
|
iRet = ioctl(iFd, VIDIOC_QUERYBUF, &v4l2_buf);
|
|
if (iRet < 0) {
|
|
JPEG_ERROR_LOG("[%s:%d]: VIDIOC_QUERYBUF failed", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
for (i= 0; i < v4l2_buf.length; i++) {
|
|
pstBuf->size[i] = v4l2_buf.m.planes[i].length;
|
|
pstBuf->addr[i] = (char *) mmap(0,
|
|
pstBuf->size[i],
|
|
PROT_READ | PROT_WRITE, MAP_SHARED, iFd,
|
|
v4l2_buf.m.planes[i].m.mem_offset);
|
|
|
|
if (pstBuf->addr[i] == MAP_FAILED) {
|
|
JPEG_ERROR_LOG("[%s]: mmap failed", __func__);
|
|
return -ERROR_MMAP_FAILED;
|
|
}
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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.length = pstBufInfo->numOfPlanes;
|
|
v4l2_buf.m.planes = plane;
|
|
|
|
if (pstBufInfo->memory == V4L2_MEMORY_USERPTR) {
|
|
for (i = 0; i < pstBufInfo->numOfPlanes; i++) {
|
|
v4l2_buf.m.planes[i].m.userptr = (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", __func__, iRet);
|
|
pstBuf->numOfPlanes = 0;
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::t_v4l2Dqbuf(int iFd, enum v4l2_buf_type eType, enum v4l2_memory eMemory)
|
|
{
|
|
struct v4l2_buffer buf;
|
|
int iRet = ERROR_NONE;
|
|
|
|
memset(&buf, 0, sizeof(struct v4l2_buffer));
|
|
|
|
buf.type = eType;
|
|
buf.memory = eMemory;
|
|
|
|
iRet = ioctl(iFd, VIDIOC_DQBUF, &buf);
|
|
if (iRet < 0) {
|
|
JPEG_ERROR_LOG("[%s:%d] VIDIOC_DQBUF failed", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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", __func__, iRet);
|
|
return iRet;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
int SecJpegCodecHal::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 SecJpegCodecHal::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;
|
|
}
|
|
|
|
|