/* ******************************************************************************* * 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() { } } }