blob: 7c7bcb9c89a0445b620a0f0767a80452797b8f01 [file] [log] [blame]
#include <cstring>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <cstdio>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
#include <log/log.h>
#include <system/graphics.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <hardware/exynos/sbwcdecoder.h>
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Trace.h>
#define MSCLPATH "/dev/video50"
#ifndef ALOGERR
#define ALOGERR(fmt, args...) ((void)ALOG(LOG_ERROR, LOG_TAG, fmt " [%s]", ##args, strerror(errno)))
#endif
#define ARRSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define V4L2_PIX_FMT_NV12N v4l2_fourcc('N', 'N', '1', '2')
#define V4L2_PIX_FMT_NV12M_P010 v4l2_fourcc('P', 'M', '1', '2')
/* 12 Y/CbCr 4:2:0 SBWC */
#define V4L2_PIX_FMT_NV12M_SBWC_8B v4l2_fourcc('M', '1', 'S', '8')
#define V4L2_PIX_FMT_NV12M_SBWC_10B v4l2_fourcc('M', '1', 'S', '1')
/* 21 Y/CrCb 4:2:0 SBWC */
#define V4L2_PIX_FMT_NV21M_SBWC_8B v4l2_fourcc('M', '2', 'S', '8')
#define V4L2_PIX_FMT_NV21M_SBWC_10B v4l2_fourcc('M', '2', 'S', '1')
/* 12 Y/CbCr 4:2:0 SBWC single */
#define V4L2_PIX_FMT_NV12N_SBWC_8B v4l2_fourcc('N', '1', 'S', '8')
#define V4L2_PIX_FMT_NV12N_SBWC_10B v4l2_fourcc('N', '1', 'S', '1')
/* 12 Y/CbCr 4:2:0 SBWC Lossy */
#define V4L2_PIX_FMT_NV12M_SBWCL_8B v4l2_fourcc('M', '1', 'L', '8')
#define V4L2_PIX_FMT_NV12M_SBWCL_10B v4l2_fourcc('M', '1', 'L', '1')
#define EXYNOS_CID_BASE (V4L2_CTRL_CLASS_USER| 0x2000U)
#define V4L2_CID_CONTENT_PROTECTION (EXYNOS_CID_BASE + 201)
#define SC_CID_FRAMERATE (EXYNOS_CID_BASE + 110)
enum {
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M = 0x105,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN = 0x123,
/* 10-bit format (2 fd, 10bit, 2x byte) custom formats */
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M = 0x127,
/* SBWC format */
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC = 0x130,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC = 0x131,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC = 0x132,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC = 0x133,
HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC = 0x134,
/* SBWC Lossy formats */
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50 = 0x140,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75 = 0x141,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50 = 0x150,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75 = 0x151,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40 = 0x160,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60 = 0x161,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80 = 0x162,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40 = 0x170,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60 = 0x171,
HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80 = 0x172,
};
SbwcDecoder::SbwcDecoder()
{
fd_dev = open(MSCLPATH, O_RDWR);
if (fd_dev < 0) {
ALOGERR("Failed to open %s", MSCLPATH);
return;
}
}
SbwcDecoder::~SbwcDecoder()
{
if (fd_dev >= 0)
close(fd_dev);
}
bool SbwcDecoder::reqBufsWithCount(unsigned int count)
{
ATRACE_CALL();
v4l2_requestbuffers reqbufs;
reqbufs.count = count;
reqbufs.memory = V4L2_MEMORY_DMABUF;
reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
if (ioctl(fd_dev, VIDIOC_REQBUFS, &reqbufs) < 0) {
ALOGERR("Failed to REQBUFS(SRC)");
return false;
}
reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if (ioctl(fd_dev, VIDIOC_REQBUFS, &reqbufs) < 0) {
ALOGERR("Failed to REQBUFS(DST)");
return false;
}
return true;
}
static struct {
unsigned int hal;
uint32_t v4l2;
} __halDataspaceToV4L2[] = {
{HAL_DATASPACE_STANDARD_BT709, V4L2_COLORSPACE_REC709},
{HAL_DATASPACE_STANDARD_BT601_625, V4L2_COLORSPACE_SMPTE170M},
{HAL_DATASPACE_STANDARD_BT601_525, V4L2_COLORSPACE_SMPTE170M},
{HAL_DATASPACE_STANDARD_BT2020, V4L2_COLORSPACE_BT2020},
{HAL_DATASPACE_STANDARD_FILM, V4L2_COLORSPACE_REC709},
{HAL_DATASPACE_SRGB, V4L2_COLORSPACE_REC709},
{HAL_DATASPACE_JFIF, V4L2_COLORSPACE_SMPTE170M},
{HAL_DATASPACE_BT601_525, V4L2_COLORSPACE_SMPTE170M},
{HAL_DATASPACE_BT601_625, V4L2_COLORSPACE_SMPTE170M},
{HAL_DATASPACE_BT709, V4L2_COLORSPACE_REC709},
};
#define HAL_DATASPACE_LEGACY_TYPE_MASK ((1 << HAL_DATASPACE_STANDARD_SHIFT) - 1)
uint32_t halDataspaceToV4L2(unsigned int dataspace, unsigned int width, unsigned int height)
{
if ((dataspace & HAL_DATASPACE_LEGACY_TYPE_MASK) != 0) {
dataspace &= HAL_DATASPACE_LEGACY_TYPE_MASK;
} else {
dataspace &= ~HAL_DATASPACE_RANGE_MASK;
dataspace &= ~HAL_DATASPACE_TRANSFER_MASK;
if ((dataspace & HAL_DATASPACE_STANDARD_MASK) == 0) {
dataspace |= ((width * height) < (1280 * 720)) ? HAL_DATASPACE_STANDARD_BT601_625
: HAL_DATASPACE_STANDARD_BT709;
}
}
for (int i = 0; i < ARRSIZE(__halDataspaceToV4L2); i++) {
if (dataspace == __halDataspaceToV4L2[i].hal)
return __halDataspaceToV4L2[i].v4l2;
}
return V4L2_COLORSPACE_DEFAULT;
}
#define V4L2_CID_CSC_EQ (EXYNOS_CID_BASE + 101)
#define V4L2_CID_CSC_RANGE (EXYNOS_CID_BASE + 102)
#define DATASPACE_RANGE_FULL 1
#define DATASPACE_RANGE_LIMITED 0
#define isRGB(fmt) (fmt == V4L2_PIX_FMT_RGB32)
bool SbwcDecoder::setCtrl()
{
ATRACE_CALL();
v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTENT_PROTECTION;
ctrl.value = mIsProtected;
if (ioctl(fd_dev, VIDIOC_S_CTRL, &ctrl) < 0) {
ALOGERR("Failed to S_CTRL to make [%s]",
(mIsProtected) ? "SECURE mode" : "NORMAL mode");
return false;
}
if (isRGB(mDst.fmt)) {
ctrl.id = V4L2_CID_CSC_EQ;
ctrl.value = halDataspaceToV4L2(mDataspace, mSrc.width, mSrc.height);
if (ioctl(fd_dev, VIDIOC_S_CTRL, &ctrl) < 0) {
ALOGERR("Failed to set csc_dataspace to %d", ctrl.value);
return false;
}
ctrl.id = V4L2_CID_CSC_RANGE;
ctrl.value = (mDataspace & HAL_DATASPACE_RANGE_FULL) ? DATASPACE_RANGE_FULL
: DATASPACE_RANGE_LIMITED;
if (ioctl(fd_dev, VIDIOC_S_CTRL, &ctrl) < 0) {
ALOGERR("Failed to set csc_range to %s",
(ctrl.value == DATASPACE_RANGE_FULL) ? "WIDE" : "NARROW");
return false;
}
}
return true;
}
bool SbwcDecoder::setFrameRate()
{
ATRACE_CALL();
v4l2_control ctrl;
ctrl.id = SC_CID_FRAMERATE;
ctrl.value = mFrameRate;
if (ioctl(fd_dev, VIDIOC_S_CTRL, &ctrl) < 0) {
ALOGERR("Failed to S_CTRL to set framerate %d", mFrameRate);
return false;
}
return true;
}
#define ALIGN_SBWC(val) (((val) + 31) & ~31)
bool SbwcDecoder::setFmt()
{
ATRACE_CALL();
v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.fmt.pix_mp.height = mSrc.height;
// TODO : how to get colorspace, but MSCL driver doesn't use this.
//fmt.fmt.pix_mp.colorspace = haldataspace_to_v4l2(canvas.getDataspace(), coord.hori, coord.vert);
fmt.fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
fmt.fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
fmt.fmt.pix_mp.width = mSrc.stride;
fmt.fmt.pix_mp.pixelformat = mSrc.fmt;
fmt.fmt.pix_mp.flags = mLossyBlockSize;
if (ioctl(fd_dev, VIDIOC_S_FMT, &fmt) < 0) {
ALOGERR("Failed to S_FMT(SRC):width(%d), height(%d), fmt(%#x)",
mSrc.stride, mSrc.height, mSrc.fmt);
return false;
}
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix_mp.width = mDst.stride;
fmt.fmt.pix_mp.pixelformat = mDst.fmt;
fmt.fmt.pix_mp.flags = 0;
if (ioctl(fd_dev, VIDIOC_S_FMT, &fmt) < 0) {
ALOGERR("Failed to S_FMT(DST):width(%d), height(%d), fmt(%#x)",
mDst.stride, mDst.height, mDst.fmt);
return false;
}
return true;
}
bool SbwcDecoder::setCrop()
{
ATRACE_CALL();
v4l2_crop crop;
crop.c.left = 0;
crop.c.top = 0;
crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
crop.c.width = mSrc.width;
crop.c.height = mSrc.height;
if (ioctl(fd_dev, VIDIOC_S_CROP, &crop) < 0) {
ALOGERR("Failed to S_CROP(SRC):width(%d), height(%d)", mSrc.width, mSrc.height);
return false;
}
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
crop.c.width = mDst.width;
crop.c.height = mDst.height;
if (ioctl(fd_dev, VIDIOC_S_CROP, &crop) < 0) {
ALOGERR("Failed to S_CROP(DST):width(%d), height(%d)", mDst.width, mDst.height);
return false;
}
return true;
}
bool SbwcDecoder::streamOn()
{
ATRACE_CALL();
enum v4l2_buf_type bufType;
bufType = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
if (ioctl(fd_dev, VIDIOC_STREAMON, &bufType) < 0) {
ALOGERR("Failed to STREAMON(SRC)");
return false;
}
bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if (ioctl(fd_dev, VIDIOC_STREAMON, &bufType) < 0) {
ALOGERR("Failed to STREAMON(DST)");
return false;
}
return true;
}
bool SbwcDecoder::streamOff()
{
ATRACE_CALL();
enum v4l2_buf_type bufType;
bufType = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
if (ioctl(fd_dev, VIDIOC_STREAMOFF, &bufType) < 0) {
ALOGERR("Failed to STREAMOFF(SRC)");
return false;
}
bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if (ioctl(fd_dev, VIDIOC_STREAMOFF, &bufType) < 0) {
ALOGERR("Failed to STREAMOFF(DST)");
return false;
}
return true;
}
//TODO : data_offset is not set, calculate byteused
bool SbwcDecoder::queueBuf(int inBuf[], size_t inLen[],
int outBuf[], size_t outLen[])
{
ATRACE_CALL();
v4l2_buffer buffer;
v4l2_plane planes[4];
memset(&buffer, 0, sizeof(buffer));
buffer.memory = V4L2_MEMORY_DMABUF;
memset(planes, 0, sizeof(planes));
buffer.length = mSrcNumFd;
buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
for (unsigned int i = 0; i < mSrcNumFd; i++) {
planes[i].length = static_cast<unsigned int>(inLen[i]);
//planes[i].bytesused = ;
planes[i].m.fd = inBuf[i];
//planes[i].data_offset = ;
}
buffer.m.planes = planes;
if (ioctl(fd_dev, VIDIOC_QBUF, &buffer) < 0) {
ALOGERR("Failed to QBUF(SRC)");
return false;
}
memset(planes, 0, sizeof(planes));
buffer.length = mDstNumFd;
buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
for (unsigned int i = 0; i < mDstNumFd; i++) {
planes[i].length = static_cast<unsigned int>(outLen[i]);
planes[i].m.fd = outBuf[i];
//planes[i].data_offset = ;
}
buffer.m.planes = planes;
if (ioctl(fd_dev, VIDIOC_QBUF, &buffer) < 0) {
ALOGERR("Failed to QBUF(DST)");
return false;
}
return true;
}
bool SbwcDecoder::dequeueBuf()
{
ATRACE_CALL();
v4l2_buffer buffer;
v4l2_plane planes[4];
memset(&buffer, 0, sizeof(buffer));
buffer.memory = V4L2_MEMORY_DMABUF;
buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
memset(planes, 0, sizeof(planes));
buffer.length = 4;
buffer.m.planes = planes;
if (ioctl(fd_dev, VIDIOC_DQBUF, &buffer) < 0) {
ALOGERR("Failed to DQBUF(SRC)");
return false;
} else if (!!(buffer.flags & V4L2_BUF_FLAG_ERROR)) {
ALOGERR("%s:Error during running(SRC)", __func__);
return false;
}
buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
memset(planes, 0, sizeof(planes));
buffer.length = 4;
buffer.m.planes = planes;
if (ioctl(fd_dev, VIDIOC_DQBUF, &buffer) < 0) {
ALOGERR("Failed to DQBUF(DST)");
return false;
} else if (!!(buffer.flags & V4L2_BUF_FLAG_ERROR)) {
ALOGERR("%s:Error during running(DST)", __func__);
return false;
}
return true;
}
bool SbwcDecoder::decode(int inBuf[], size_t inLen[],
int outBuf[], size_t outLen[])
{
bool ret;
ret = setCtrl();
if (ret)
ret = setFmt();
if (ret)
ret = setCrop();
if (ret)
ret = setFrameRate();
if (ret)
ret = reqBufsWithCount(1);
if (ret)
ret = streamOn();
if (ret)
ret = queueBuf(inBuf, inLen, outBuf, outLen);
if (ret)
ret = dequeueBuf();
streamOff();
reqBufsWithCount(0);
return ret;
}
static struct {
uint32_t halFmtSBWC;
uint32_t halFmtNonSBWC;
} __halfmtSBWC_to_halfmtNonSBWC[] = {
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M },
};
static struct {
uint32_t fmtHal;
uint32_t fmtV4L2;
uint32_t numFd;
uint32_t blockSz;
} __halfmtSBWC_to_v4l2[] = {
// { (HAL format), (V4L2 format), (num fd), (block size of sbwc lossy) }
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, V4L2_PIX_FMT_NV12M_SBWC_8B, 2, 0 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, V4L2_PIX_FMT_NV12M_SBWC_10B, 2, 0 },
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, V4L2_PIX_FMT_NV21M_SBWC_8B, 2, 0 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, V4L2_PIX_FMT_NV12N_SBWC_8B, 1, 0 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, V4L2_PIX_FMT_NV12N_SBWC_10B, 1, 0 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, V4L2_PIX_FMT_NV12M_SBWCL_8B, 2, 64},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, V4L2_PIX_FMT_NV12M_SBWCL_8B, 2, 96},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, V4L2_PIX_FMT_NV12M_SBWCL_10B, 2, 64 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, V4L2_PIX_FMT_NV12M_SBWCL_10B, 2, 96 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, V4L2_PIX_FMT_NV12M_SBWCL_10B, 2, 128},
};
static struct {
uint32_t fmtHal;
uint32_t fmtV4L2;
uint32_t numFd;
} __halfmtNonSBWC_to_v4l2[] = {
// { (HAL format), (V4L2 format), (num fd) }
{HAL_PIXEL_FORMAT_YCBCR_420_888, V4L2_PIX_FMT_NV12N, 1 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, V4L2_PIX_FMT_NV12N, 1 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, V4L2_PIX_FMT_NV12M, 2 },
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, V4L2_PIX_FMT_NV12M_P010, 2 },
{HAL_PIXEL_FORMAT_RGBA_8888, V4L2_PIX_FMT_RGB32, 1 },
};
bool SbwcDecoder::setImage(unsigned int format, unsigned int width,
unsigned int height, unsigned int stride)
{
return setImage(format, width, height, stride, 0);
}
bool SbwcDecoder::setImage(unsigned int format, unsigned int width,
unsigned int height, unsigned int stride,
unsigned int attr, unsigned int framerate)
{
unsigned int dstFmt = 0;
for (size_t i = 0; i < ARRSIZE(__halfmtSBWC_to_halfmtNonSBWC); i++) {
if (format == __halfmtSBWC_to_halfmtNonSBWC[i].halFmtSBWC) {
dstFmt = __halfmtSBWC_to_halfmtNonSBWC[i].halFmtNonSBWC;
break;
}
}
if (dstFmt == 0) {
ALOGE("Unable to find the proper v4l2 format for HAL format(SBWC) %#x", format);
return false;
}
SbwcImgInfo src{format, width, height, ALIGN_SBWC(stride)};
SbwcImgInfo dst{dstFmt, width, height, stride};
return setImage(src, dst, 0, attr, framerate);
}
bool SbwcDecoder::setImage(SbwcImgInfo &src, SbwcImgInfo &dst,
unsigned int dataspace, unsigned int attr, unsigned int framerate)
{
ATRACE_CALL();
mSrc.fmt = 0;
for (size_t i = 0; i < ARRSIZE(__halfmtSBWC_to_v4l2); i++) {
if (src.fmt == __halfmtSBWC_to_v4l2[i].fmtHal) {
mSrc.fmt = __halfmtSBWC_to_v4l2[i].fmtV4L2;
mSrcNumFd = __halfmtSBWC_to_v4l2[i].numFd;
mLossyBlockSize = __halfmtSBWC_to_v4l2[i].blockSz;
break;
}
}
if (mSrc.fmt == 0) {
for (size_t i = 0; i < ARRSIZE(__halfmtNonSBWC_to_v4l2); i++) {
if (src.fmt == __halfmtNonSBWC_to_v4l2[i].fmtHal) {
mSrc.fmt = __halfmtNonSBWC_to_v4l2[i].fmtV4L2;
mSrcNumFd = __halfmtNonSBWC_to_v4l2[i].numFd;
mLossyBlockSize = 0;
break;
}
}
}
if (mSrc.fmt == 0) {
ALOGE("fail to find the proper v4l2 format for HAL format(SRC) %#x", mSrc.fmt);
return false;
}
mDst.fmt = 0;
for (size_t i = 0; i < ARRSIZE(__halfmtNonSBWC_to_v4l2); i++) {
if (dst.fmt == __halfmtNonSBWC_to_v4l2[i].fmtHal) {
mDst.fmt = __halfmtNonSBWC_to_v4l2[i].fmtV4L2;
mDstNumFd = __halfmtNonSBWC_to_v4l2[i].numFd;
break;
}
}
if (mDst.fmt == 0) {
ALOGE("fail to find the proper v4l2 format for HAL format(DST) %#x", mDst.fmt);
return false;
}
mSrc.width = src.width;
mSrc.height = src.height;
mSrc.stride = src.stride;
mDst.width = dst.width;
mDst.height = dst.height;
mDst.stride = dst.stride;
mDataspace = dataspace;
mFrameRate = framerate;
mIsProtected = !!(attr & SBWCDECODER_ATTR_SECURE_BUFFER);
return true;
}