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