202 lines
6.6 KiB
C++
202 lines
6.6 KiB
C++
/*
|
|
*******************************************************************************
|
|
* INCLUDE
|
|
*******************************************************************************
|
|
*/
|
|
#include "VideoInput.h"
|
|
#include "IVE.h"
|
|
#include "ResourceManager.h"
|
|
#include "../../core/Notifications.h"
|
|
#include "Application.h"
|
|
#include "Logger.h"
|
|
|
|
namespace Video
|
|
{
|
|
namespace MPP5
|
|
{
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
VideoFrame::Ptr VideoInput::_pUserVideoFrame = nullptr;
|
|
|
|
VideoInput::VideoInput(uint32_t deviceID, uint32_t channelID, bool dataReverseEnable)
|
|
: Core::VideoComponent(Poco::format("MPP5::VI#%u", deviceID)), MPPChannel((uint32_t)HI_ID_VI, deviceID, channelID),
|
|
_dataReverseEnable(dataReverseEnable), _channelId(deviceID == 2 ? 0 : 1)
|
|
{
|
|
setWidth(1920);
|
|
setHeight(1080);
|
|
setFrameRate(30);
|
|
|
|
setVideoScanMode(Core::VideoScanMode::PROGRESSIVE);
|
|
}
|
|
|
|
VideoInput::~VideoInput()
|
|
{
|
|
}
|
|
|
|
void VideoInput::start()
|
|
{
|
|
uint32_t width = getWidth();
|
|
uint32_t height = getHeight();
|
|
|
|
hi_vi_dev_attr devAttr;
|
|
devAttr.intf_mode = HI_VI_MODE_BT1120_STANDARD;
|
|
devAttr.work_mode = HI_VI_WORK_MODE_MULTIPLEX_1;
|
|
devAttr.component_mask[0] = 0x00000ff0;
|
|
devAttr.component_mask[1] = 0x000ff000;
|
|
devAttr.clk_edge = HI_VI_CLK_EDGE_SINGLE_UP;
|
|
devAttr.data_seq = HI_VI_IN_DATA_VUVU;
|
|
|
|
devAttr.sync_cfg.vsync = HI_VI_VSYNC_PULSE;
|
|
devAttr.sync_cfg.vsync_neg = HI_VI_VSYNC_NEG_LOW;
|
|
devAttr.sync_cfg.hsync = HI_VI_HSYNC_VALID_SIG;
|
|
devAttr.sync_cfg.hsync_neg = HI_VI_HSYNC_NEG_HIGH;
|
|
devAttr.sync_cfg.vsync_valid = HI_VI_VSYNC_VALID_SIG;
|
|
devAttr.sync_cfg.vsync_valid_neg = HI_VI_VSYNC_VALID_NEG_HIGH;
|
|
|
|
devAttr.sync_cfg.timing_blank.hsync_hfb = 0;
|
|
devAttr.sync_cfg.timing_blank.hsync_act = width;
|
|
devAttr.sync_cfg.timing_blank.hsync_hbb = 0;
|
|
devAttr.sync_cfg.timing_blank.vsync_vfb = 0;
|
|
devAttr.sync_cfg.timing_blank.vsync_vact = height;
|
|
devAttr.sync_cfg.timing_blank.vsync_vbb = 0;
|
|
devAttr.sync_cfg.timing_blank.vsync_vbfb = 0;
|
|
devAttr.sync_cfg.timing_blank.vsync_vbact = 0;
|
|
devAttr.sync_cfg.timing_blank.vsync_vbbb = 0;
|
|
|
|
devAttr.data_reverse_en = (hi_bool)_dataReverseEnable;
|
|
devAttr.mixed_capture_en = HI_FALSE;
|
|
|
|
auto rc = hi_mpi_vi_set_dev_attr(deviceID(), &devAttr);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(Poco::format("%s: Set attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
|
|
|
rc = hi_mpi_vi_enable_dev(deviceID());
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(Poco::format("%s: Enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
|
|
|
hi_vi_chn_attr chnAttr;
|
|
chnAttr.capture_rect.x = 0;
|
|
chnAttr.capture_rect.y = 0;
|
|
chnAttr.capture_rect.width = width;
|
|
chnAttr.capture_rect.height = height;
|
|
chnAttr.dst_size.width = width;
|
|
chnAttr.dst_size.height = height;
|
|
chnAttr.capture_select = HI_VI_CAPTURE_SELECT_BOTH;
|
|
chnAttr.scan_mode = getVIScanMode();
|
|
chnAttr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
|
|
chnAttr.mirror_en = HI_FALSE;
|
|
chnAttr.flip_en = HI_FALSE;
|
|
chnAttr.compress_mode = HI_COMPRESS_MODE_NONE;
|
|
chnAttr.src_frame_rate = -1;
|
|
chnAttr.dst_frame_rate = -1;
|
|
|
|
auto channel = channelID();
|
|
rc = hi_mpi_vi_set_chn_attr(channel, &chnAttr);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(
|
|
Poco::format("%s: Configure channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
|
|
|
rc = hi_mpi_vi_set_frame_depth(channel, 4);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(
|
|
Poco::format("%s: Configure frame depth FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
|
|
|
rc = hi_mpi_vi_enable_chn(channel);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(Poco::format("%s: Enable channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
|
|
rc);
|
|
|
|
enableUserPic(getSignalLost());
|
|
}
|
|
|
|
void VideoInput::stop()
|
|
{
|
|
enableUserPic(false);
|
|
hi_mpi_vi_disable_chn(channelID());
|
|
hi_mpi_vi_disable_dev(deviceID());
|
|
}
|
|
|
|
void VideoInput::onConfigChanged(ParameterNames& names)
|
|
{
|
|
if (!started())
|
|
return;
|
|
|
|
notifyNextComponents(sharedFromThis(), new Core::ParameterChangedNotification(names));
|
|
|
|
if (names.exists(_Width) || names.exists(_Height))
|
|
{
|
|
stop();
|
|
start();
|
|
return;
|
|
}
|
|
|
|
if (names.exists(_VideoScanMode))
|
|
{
|
|
hi_vi_chn_attr attr;
|
|
hi_mpi_vi_get_chn_attr(channelID(), &attr);
|
|
attr.scan_mode = getVIScanMode();
|
|
int rc = hi_mpi_vi_set_chn_attr(channelID(), &attr);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(
|
|
Poco::format("%s: Configure channel FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
|
|
}
|
|
|
|
if (names.exists(_SignalLost))
|
|
enableUserPic(getSignalLost());
|
|
}
|
|
|
|
uint32_t VideoInput::traffic()
|
|
{
|
|
hi_vi_chn_status s;
|
|
return hi_mpi_vi_query(channelID(), &s) == HI_SUCCESS ? s.interrupt_cnt : 0;
|
|
}
|
|
|
|
void VideoInput::enableUserPic(bool enable)
|
|
{
|
|
if (enable)
|
|
hi_mpi_vi_enable_user_pic(channelID());
|
|
else
|
|
hi_mpi_vi_disable_user_pic(channelID());
|
|
}
|
|
|
|
hi_vi_scan_mode VideoInput::getVIScanMode()
|
|
{
|
|
return getVideoScanMode() == Core::VideoScanMode::PROGRESSIVE ? HI_VI_SCAN_PROGRESSIVE : HI_VI_SCAN_INTERLACED;
|
|
}
|
|
|
|
void VideoInput::initModule()
|
|
{
|
|
hi_vi_mod_param param;
|
|
hi_mpi_vi_get_mod_param(¶m);
|
|
param.yc_reverse = 0;
|
|
hi_mpi_vi_set_mod_param(¶m);
|
|
|
|
if (!_pUserVideoFrame)
|
|
_pUserVideoFrame =
|
|
VideoFrame::create(NO_SIGNAL_YUV_FORMAT, NO_SIGNAL_YUV_WIDTH, NO_SIGNAL_YUV_HEIGHT, NO_SIGNAL_YUV_PATH);
|
|
|
|
hi_vi_user_pic_attr attr = {};
|
|
|
|
attr.pub_en = HI_TRUE;
|
|
attr.user_pic_mode = HI_VI_USER_PIC_MODE_PIC;
|
|
attr.user_pic_info.user_pic_frame_info.mod_id = HI_ID_VI;
|
|
attr.user_pic_info.user_pic_frame_info.pool_id = 0;
|
|
attr.user_pic_info.user_pic_frame_info = *_pUserVideoFrame->info();
|
|
int rc = hi_mpi_vi_set_user_pic(0, &attr);
|
|
if (rc != HI_SUCCESS)
|
|
throw Poco::InvalidAccessException(Poco::format("MPP::VI: Set user pic FAIL: %d(%#x)", rc, (uint32_t)rc), rc);
|
|
}
|
|
|
|
void VideoInput::deinitModule()
|
|
{
|
|
_pUserVideoFrame.reset();
|
|
}
|
|
|
|
void VideoInput::reset()
|
|
{
|
|
}
|
|
}
|
|
}
|