308 lines
7.5 KiB
C++
308 lines
7.5 KiB
C++
#include "CamHwIsp20.h"
|
|
#include "rk_aiq_comm.h"
|
|
#include "fake_v4l2_device.h"
|
|
#include "rkcif-config.h"
|
|
|
|
namespace RkCam {
|
|
|
|
CifSclStream::CifSclStream()
|
|
: _working_mode(0)
|
|
, _bpp(0)
|
|
, index(0)
|
|
, _width(0)
|
|
, _height(0)
|
|
, _sns_v4l_pix_fmt(0)
|
|
, _ratio(0)
|
|
, _first_start(true)
|
|
{}
|
|
|
|
CifSclStream::~CifSclStream() {}
|
|
|
|
bool
|
|
CifSclStream::setPollCallback (PollCallback *callback)
|
|
{
|
|
for (int i = 0; i < index; i++) {
|
|
_stream[i]->setPollCallback(callback);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::set_format(const struct v4l2_subdev_format& sns_sd_fmt,
|
|
uint32_t sns_v4l_pix_fmt, int bpp)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
_width = sns_sd_fmt.format.width;
|
|
_height = sns_sd_fmt.format.height;
|
|
_bpp = bpp;
|
|
|
|
switch (sns_v4l_pix_fmt)
|
|
{
|
|
case V4L2_PIX_FMT_SBGGR8:
|
|
case V4L2_PIX_FMT_SBGGR10:
|
|
case V4L2_PIX_FMT_SBGGR12:
|
|
case V4L2_PIX_FMT_SBGGR14:
|
|
case V4L2_PIX_FMT_SBGGR16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SBGGR16;
|
|
break;
|
|
case V4L2_PIX_FMT_SGBRG8:
|
|
case V4L2_PIX_FMT_SGBRG10:
|
|
case V4L2_PIX_FMT_SGBRG12:
|
|
case V4L2_PIX_FMT_SGBRG14:
|
|
case V4L2_PIX_FMT_SGBRG16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SGBRG16;
|
|
break;
|
|
case V4L2_PIX_FMT_SGRBG8:
|
|
case V4L2_PIX_FMT_SGRBG10:
|
|
case V4L2_PIX_FMT_SGRBG12:
|
|
case V4L2_PIX_FMT_SGRBG14:
|
|
case V4L2_PIX_FMT_SGRBG16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SGRBG16;
|
|
break;
|
|
case V4L2_PIX_FMT_SRGGB8:
|
|
case V4L2_PIX_FMT_SRGGB10:
|
|
case V4L2_PIX_FMT_SRGGB12:
|
|
case V4L2_PIX_FMT_SRGGB14:
|
|
case V4L2_PIX_FMT_SRGGB16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SRGGB16;
|
|
break;
|
|
default:
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "unknown format");
|
|
return XCAM_RETURN_ERROR_PARAM;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::set_format(const struct v4l2_subdev_selection& sns_sd_sel,
|
|
uint32_t sns_v4l_pix_fmt, int bpp)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
_width = sns_sd_sel.r.width;
|
|
_height = sns_sd_sel.r.height;
|
|
_bpp = bpp;
|
|
|
|
switch (sns_v4l_pix_fmt)
|
|
{
|
|
case V4L2_PIX_FMT_SBGGR8:
|
|
case V4L2_PIX_FMT_SBGGR10:
|
|
case V4L2_PIX_FMT_SBGGR12:
|
|
case V4L2_PIX_FMT_SBGGR14:
|
|
case V4L2_PIX_FMT_SBGGR16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SBGGR16;
|
|
break;
|
|
case V4L2_PIX_FMT_SGBRG8:
|
|
case V4L2_PIX_FMT_SGBRG10:
|
|
case V4L2_PIX_FMT_SGBRG12:
|
|
case V4L2_PIX_FMT_SGBRG14:
|
|
case V4L2_PIX_FMT_SGBRG16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SGBRG16;
|
|
break;
|
|
case V4L2_PIX_FMT_SGRBG8:
|
|
case V4L2_PIX_FMT_SGRBG10:
|
|
case V4L2_PIX_FMT_SGRBG12:
|
|
case V4L2_PIX_FMT_SGRBG14:
|
|
case V4L2_PIX_FMT_SGRBG16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SGRBG16;
|
|
break;
|
|
case V4L2_PIX_FMT_SRGGB8:
|
|
case V4L2_PIX_FMT_SRGGB10:
|
|
case V4L2_PIX_FMT_SRGGB12:
|
|
case V4L2_PIX_FMT_SRGGB14:
|
|
case V4L2_PIX_FMT_SRGGB16:
|
|
_sns_v4l_pix_fmt = V4L2_PIX_FMT_SRGGB16;
|
|
break;
|
|
default:
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "unknown format");
|
|
return XCAM_RETURN_ERROR_PARAM;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
CifSclStream::set_working_mode(int mode)
|
|
{
|
|
_working_mode = mode;
|
|
}
|
|
|
|
XCamReturn CifSclStream::start()
|
|
{
|
|
if (_init && !_active) {
|
|
for (int i = 0; i < index; i++) {
|
|
if (_stream[i].ptr())
|
|
_stream[i]->start();
|
|
}
|
|
_active = true;
|
|
}
|
|
return XCAM_RETURN_NO_ERROR;
|
|
}
|
|
|
|
XCamReturn CifSclStream::stop()
|
|
{
|
|
for (int i = 0; i < index; i++) {
|
|
if (_stream[i].ptr())
|
|
_stream[i]->stop();
|
|
}
|
|
_active = false;
|
|
return XCAM_RETURN_NO_ERROR;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::restart(const rk_sensor_full_info_t *s_info, int ratio, PollCallback *callback, int mode)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
if (mode) {
|
|
if (!_init)
|
|
ret = init(s_info, callback);
|
|
|
|
if (ratio != _ratio) {
|
|
if (_active) {
|
|
stop();
|
|
}
|
|
ret = set_ratio_fmt(ratio);
|
|
}
|
|
|
|
if (!_active && _init) {
|
|
ret = prepare();
|
|
ret = start();
|
|
}
|
|
} else {
|
|
if (_active)
|
|
ret = stop();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::init(const rk_sensor_full_info_t *s_info, PollCallback *callback)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
if (!s_info->cif_info) {
|
|
LOGD_CAMHW("no link to vicap\n");
|
|
return XCAM_RETURN_NO_ERROR;
|
|
}
|
|
|
|
switch (_working_mode)
|
|
{
|
|
case 0x0:
|
|
index = 1;
|
|
break;
|
|
case 0x11:
|
|
case 0x12:
|
|
index = 2;
|
|
break;
|
|
case 0x21:
|
|
case 0x22:
|
|
index = 3;
|
|
break;
|
|
default:
|
|
index = 0;
|
|
break;
|
|
}
|
|
|
|
|
|
if (index >= 1) {
|
|
if (strlen(s_info->cif_info->mipi_scl0)) {
|
|
_dev[0] = new V4l2Device(s_info->cif_info->mipi_scl0);
|
|
}
|
|
if (_dev[0].ptr())
|
|
_dev[0]->open();
|
|
}
|
|
if (index >= 2) {
|
|
if (strlen(s_info->cif_info->mipi_scl1)) {
|
|
_dev[1] = new V4l2Device(s_info->cif_info->mipi_scl1);
|
|
}
|
|
if (_dev[1].ptr())
|
|
_dev[1]->open();
|
|
}
|
|
if (index == 3) {
|
|
if (strlen(s_info->cif_info->mipi_scl2)) {
|
|
_dev[2] = new V4l2Device(s_info->cif_info->mipi_scl2);
|
|
}
|
|
if (_dev[2].ptr())
|
|
_dev[2]->open();
|
|
}
|
|
for (int i = 0; i < index; i++) {
|
|
if (_dev[i].ptr()) {
|
|
_stream[i] = new RKRawStream(_dev[i], i, VICAP_POLL_SCL);
|
|
_stream[i]->setPollCallback(callback);
|
|
SmartPtr<RKRawStream> stream = _stream[i].dynamic_cast_ptr<RKRawStream>();
|
|
stream->set_reserved_data(_bpp);
|
|
}
|
|
}
|
|
|
|
_init = true;
|
|
|
|
return ret;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::set_ratio_fmt(int ratio)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
if (ratio > 0 && ratio <= 8) {
|
|
_ratio = 8;
|
|
} else if (ratio > 8 && ratio <= 16) {
|
|
_ratio = 16;
|
|
} else {
|
|
_ratio = 32;
|
|
}
|
|
|
|
uint32_t dst_width = _width / _ratio;
|
|
if ((dst_width % 2) != 0)
|
|
dst_width -= 1;
|
|
|
|
uint32_t dst_height = _height / _ratio;
|
|
if ((dst_height % 2) != 0)
|
|
dst_height -= 1;
|
|
|
|
for (int i = 0; i < index; i++) {
|
|
ret = _dev[i]->set_format(dst_width,
|
|
dst_height,
|
|
_sns_v4l_pix_fmt,
|
|
V4L2_FIELD_NONE,
|
|
0);
|
|
if (ret < 0) {
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "device(%s) set format failed", _dev[i]->get_device_name());
|
|
} else {
|
|
LOGD_CAMHW_SUBM(ISP20HW_SUBM, "device(%s) set fmt info: fmt 0x%x, %dx%d !",
|
|
_dev[i]->get_device_name(), _sns_v4l_pix_fmt,
|
|
dst_width, dst_height);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
XCamReturn
|
|
CifSclStream::prepare()
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
if (!_init || _active)
|
|
return XCAM_RETURN_NO_ERROR;
|
|
|
|
for (int i = 0; i < index; i++) {
|
|
ret = _dev[i]->prepare();
|
|
if (ret < 0)
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "mipi tx:%d prepare err: %d\n", ret);
|
|
|
|
_stream[i]->set_device_prepared(true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool
|
|
CifSclStream::getIsActive()
|
|
{
|
|
return _active;
|
|
}
|
|
|
|
} |