整理代码

This commit is contained in:
蒲爽 2026-09-28 21:33:04 +08:00
commit c7b4e178ec
364 changed files with 59691 additions and 0 deletions

View file

@ -0,0 +1,403 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "HDMIVideoOutput.h"
#include "Logger.h"
#include "util/Math.h"
#include <array>
namespace Video
{
namespace MPP5
{
/*
*******************************************************************************
* CONSTANTS
*******************************************************************************
*/
#define VO_DEVICE_ID 0
#define VIDEO_LAYER_ID 0
#define HDMI_ID HI_HDMI_ID_0
/*
*******************************************************************************
* TYPEDEFS
*******************************************************************************
*/
struct TimingDesc
{
std::string desc;
uint32_t width;
uint32_t height;
uint32_t frameRate;
hi_vo_intf_sync intf;
hi_hdmi_video_format format;
};
/*
*******************************************************************************
* LOCAL VARIABLES
*******************************************************************************
*/
static const std::array<TimingDesc, 27> timingDescTable = {{
{"3840x2160P30", 3840, 2160, 30, HI_VO_OUT_3840x2160_30, HI_HDMI_VIDEO_FORMAT_3840X2160P_30},
{"2560x1600P60", 2560, 1600, 60, HI_VO_OUT_2560x1600_60, HI_HDMI_VIDEO_FORMAT_2560x1600_60},
{"2560x1440P60", 2560, 1440, 60, HI_VO_OUT_2560x1440_60, HI_HDMI_VIDEO_FORMAT_2560x1440_60},
{"2560x1440P30", 2560, 1440, 30, HI_VO_OUT_2560x1440_30, HI_HDMI_VIDEO_FORMAT_2560x1440_30},
{"1920x1080P60", 1920, 1080, 60, HI_VO_OUT_1080P60, HI_HDMI_VIDEO_FORMAT_1080P_60},
{"1920x1080I60", 1920, 1080, 60, HI_VO_OUT_1080I60, HI_HDMI_VIDEO_FORMAT_1080i_60},
{"1920x1080P50", 1920, 1080, 50, HI_VO_OUT_1080P50, HI_HDMI_VIDEO_FORMAT_1080P_50},
{"1920x1080I50", 1920, 1080, 50, HI_VO_OUT_1080I50, HI_HDMI_VIDEO_FORMAT_1080i_50},
{"1920x1080P30", 1920, 1080, 30, HI_VO_OUT_1080P30, HI_HDMI_VIDEO_FORMAT_1080P_30},
{"1920x1080P25", 1920, 1080, 25, HI_VO_OUT_1080P25, HI_HDMI_VIDEO_FORMAT_1080P_25},
{"1920x1080P24", 1920, 1080, 24, HI_VO_OUT_1080P24, HI_HDMI_VIDEO_FORMAT_1080P_24},
{"1280x720P60", 1280, 720, 60, HI_VO_OUT_720P60, HI_HDMI_VIDEO_FORMAT_720P_60},
{"1280x720P50", 1280, 720, 50, HI_VO_OUT_720P50, HI_HDMI_VIDEO_FORMAT_720P_50},
{"720x576P50", 720, 576, 50, HI_VO_OUT_576P50, HI_HDMI_VIDEO_FORMAT_576P_50},
{"720x480P50", 720, 480, 60, HI_VO_OUT_480P60, HI_HDMI_VIDEO_FORMAT_480P_60},
{"1920x2160P30", 1920, 2160, 30, HI_VO_OUT_1920x2160_30, HI_HDMI_VIDEO_FORMAT_1920x2160_30},
{"1920x1200P60", 1920, 1200, 60, HI_VO_OUT_1920x1200_60, HI_HDMI_VIDEO_FORMAT_VESA_1920X1200_60},
{"1680x1050P60", 1680, 1050, 60, HI_VO_OUT_1680x1050_60, HI_HDMI_VIDEO_FORMAT_VESA_1680X1050_60},
{"1600x1200P60", 1600, 1200, 60, HI_VO_OUT_1600x1200_60, HI_HDMI_VIDEO_FORMAT_VESA_1600X1200_60},
{"1440x900P60", 1440, 900, 60, HI_VO_OUT_1440x900_60, HI_HDMI_VIDEO_FORMAT_VESA_1440X900_60},
{"1366x768P60", 1366, 768, 60, HI_VO_OUT_1366x768_60, HI_HDMI_VIDEO_FORMAT_VESA_1366X768_60},
{"1280x1024P60", 1280, 1024, 60, HI_VO_OUT_1280x1024_60, HI_HDMI_VIDEO_FORMAT_VESA_1280X1024_60},
{"1280x800P60", 1280, 800, 60, HI_VO_OUT_1280x800_60, HI_HDMI_VIDEO_FORMAT_VESA_1280X800_60},
{"1024x768P60", 1024, 768, 60, HI_VO_OUT_1024x768_60, HI_HDMI_VIDEO_FORMAT_VESA_1024X768_60},
{"800x600P60", 800, 600, 60, HI_VO_OUT_800x600_60, HI_HDMI_VIDEO_FORMAT_VESA_800X600_60},
}};
const TimingDesc& defaultTime = timingDescTable[4];
/*
*******************************************************************************
* LOCAL FUNCTIONS
*******************************************************************************
*/
static const TimingDesc& getTimingDesc(const std::string& desc)
{
for (const auto& t : timingDescTable)
{
if (t.desc == desc)
return t;
}
logger().warning("HDMIVideoOutput: Could NOT found '%s', using %s", desc, defaultTime.desc);
return defaultTime;
}
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
HDMIVideoOutput::HDMIVideoOutput(const std::string& name)
: Core::VideoOutput(name + "(MPP5::HDMI)"), MPPChannel((uint32_t)HI_ID_VO, VO_DEVICE_ID, 0)
{
hi_mpi_hdmi_init();
stopOutput();
}
HDMIVideoOutput::~HDMIVideoOutput()
{
stopOutput();
hi_mpi_hdmi_deinit();
}
void HDMIVideoOutput::start()
{
hi_mpi_hdmi_open(HDMI_ID);
onHotPlug();
}
void HDMIVideoOutput::stop()
{
onNoPlug();
hi_mpi_hdmi_close(HDMI_ID);
}
void HDMIVideoOutput::onConfigChanged(ParameterNames& names)
{
if (!getHDMIStarted())
return;
if (names.exists(_Timing))
{
try
{
stopOutput();
startOutput();
}
catch (Poco::Exception& e)
{
logger().error(e.displayText());
stopOutput();
}
}
if (names.exists(_Mode))
{
hi_mpi_hdmi_stop(HDMI_ID);
hi_hdmi_attr attr;
int rc = hi_mpi_hdmi_get_attr(HDMI_ID, &attr);
if (rc != HI_SUCCESS)
logger().error("%s: get HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
attr.hdmi_en = getUsingHDMIMode();
rc = hi_mpi_hdmi_set_attr(HDMI_ID, &attr);
if (rc != HI_SUCCESS)
logger().error("%s: set HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
rc = hi_mpi_hdmi_start(HDMI_ID);
if (rc != HI_SUCCESS)
logger().error("%s: start HDMI FAIL: %d(%#x)", name(), rc, (uint32_t)rc);
}
if (names.exists(_Luma) || names.exists(_Contrast) || names.exists(_Hue) || names.exists(_Saturation) ||
names.exists(_ColorType))
{
hi_vo_hdmi_param param;
if (names.exists(_ColorType))
hi_mpi_hdmi_stop(HDMI_ID);
hi_mpi_vo_get_hdmi_param(deviceID(), &param);
if (names.exists(_ColorType))
param.csc.csc_matrix = getCSCMatrix();
param.csc.luma = ::Util::Math::clamp(getLuma(), 0, 100);
param.csc.contrast = ::Util::Math::clamp(getContrast(), 0, 100);
param.csc.hue = ::Util::Math::clamp(getHue(), 0, 100);
param.csc.saturation = ::Util::Math::clamp(getSaturation(), 0, 100);
hi_mpi_vo_set_hdmi_param(deviceID(), &param);
if (names.exists(_ColorType))
hi_mpi_hdmi_start(HDMI_ID);
}
if (names.exists(_Mirror))
hi_mpi_vo_set_chn_mirror(VIDEO_LAYER_ID, channelID(), getMirror() ? HI_VO_MIRROR_HOR : HI_VO_MIRROR_NONE);
if (names.exists(_Rotation))
hi_mpi_vo_set_chn_rotation(VIDEO_LAYER_ID, channelID(), getRotationValue());
}
void HDMIVideoOutput::onLink(Core::Component::Ptr pPrevious)
{
MPPChannel::doLink(pPrevious);
}
void HDMIVideoOutput::onUnlink(Core::Component::Ptr pPrevious)
{
MPPChannel::doUnlink(pPrevious);
}
void HDMIVideoOutput::onHotPlug()
{
logger().debug("%s: HDMI HOTPLUG", name());
setPluged(true);
try
{
startOutput();
}
catch (Poco::Exception& e)
{
logger().error(e.displayText());
}
}
void HDMIVideoOutput::onNoPlug()
{
logger().debug("%s: HDMI NOPLUG", name());
setPluged(false);
stopOutput();
}
void HDMIVideoOutput::onEDIDFail()
{
logger().debug("EDID FAIL");
}
void HDMIVideoOutput::startOutput()
{
const TimingDesc& timing = getTimingDesc(getTiming());
hi_vo_pub_attr attr;
attr.bg_color = 0x000000;
attr.intf_type = HI_VO_INTF_HDMI;
attr.intf_sync = timing.intf;
int rc = hi_mpi_vo_set_pub_attr(deviceID(), &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: set-pub FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
rc = hi_mpi_vo_enable(deviceID());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: enable VO FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
{
hi_vo_video_layer_attr attr;
attr.display_rect.x = 0;
attr.display_rect.y = 0;
attr.display_rect.width = timing.width;
attr.display_rect.height = timing.height;
attr.img_size.width = timing.width;
attr.img_size.height = timing.height;
attr.display_frame_rate = timing.frameRate;
attr.pixel_format = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422;
attr.double_frame_en = HI_FALSE;
attr.cluster_mode_en = HI_FALSE;
attr.dst_dynamic_range = HI_DYNAMIC_RANGE_SDR8;
attr.display_buf_len = 4;
attr.partition_mode = HI_VO_PARTITION_MODE_SINGLE;
attr.compress_mode = HI_COMPRESS_MODE_NONE;
rc = hi_mpi_vo_set_video_layer_attr(VIDEO_LAYER_ID, &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: set video layer attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
rc = hi_mpi_vo_enable_video_layer(VIDEO_LAYER_ID);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: enable video layer FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
}
{
hi_vo_chn_attr attr;
attr.priority = 0;
attr.rect.x = 0;
attr.rect.y = 0;
attr.rect.width = timing.width;
attr.rect.height = timing.height;
attr.deflicker_en = HI_FALSE;
rc = hi_mpi_vo_set_chn_attr(VIDEO_LAYER_ID, channelID(), &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: set chn attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
rc);
rc = hi_mpi_vo_enable_chn(VIDEO_LAYER_ID, channelID());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
hi_mpi_vo_set_chn_mirror(VIDEO_LAYER_ID, channelID(), getMirror() ? HI_VO_MIRROR_HOR : HI_VO_MIRROR_NONE);
hi_mpi_vo_set_chn_rotation(VIDEO_LAYER_ID, channelID(), getRotationValue());
}
{
hi_hdmi_attr attr;
rc = hi_mpi_hdmi_get_attr(HDMI_ID, &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: get HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
attr.hdmi_en = getUsingHDMIMode();
attr.video_format = timing.format;
attr.deep_color_mode = HI_HDMI_DEEP_COLOR_24BIT;
attr.audio_en = attr.hdmi_en ? HI_TRUE : HI_FALSE;
attr.sample_rate = HI_HDMI_SAMPLE_RATE_48K;
attr.bit_depth = HI_HDMI_BIT_DEPTH_16;
attr.auth_mode_en = HI_TRUE;
attr.deep_color_adapt_en = HI_TRUE;
rc = hi_mpi_hdmi_set_attr(HDMI_ID, &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: set HDMI attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
hi_vo_hdmi_param param;
hi_mpi_vo_get_hdmi_param(deviceID(), &param);
param.csc.csc_matrix = getCSCMatrix();
param.csc.luma = ::Util::Math::clamp(getLuma(), 0, 100);
param.csc.contrast = ::Util::Math::clamp(getContrast(), 0, 100);
param.csc.hue = ::Util::Math::clamp(getHue(), 0, 100);
param.csc.saturation = ::Util::Math::clamp(getSaturation(), 0, 100);
hi_mpi_vo_set_hdmi_param(deviceID(), &param);
rc = hi_mpi_hdmi_start(HDMI_ID);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: start HDMI FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
rc);
}
setHDMIStarted(true);
}
void HDMIVideoOutput::stopOutput()
{
hi_mpi_hdmi_stop(HDMI_ID);
hi_mpi_vo_disable_chn(VIDEO_LAYER_ID, channelID());
hi_mpi_vo_disable_video_layer(VIDEO_LAYER_ID);
hi_mpi_vo_disable(VO_DEVICE_ID);
setHDMIStarted(false);
}
hi_bool HDMIVideoOutput::getUsingHDMIMode()
{
return getMode() == Core::VideoOutput::Mode::HDMI ? HI_TRUE : HI_FALSE;
}
hi_vo_csc_matrix HDMIVideoOutput::getCSCMatrix()
{
if (getMode() == Core::VideoOutput::Mode::DVI || getColorType() == Core::VideoOutput::ColorType::RGB)
return HI_VO_CSC_MATRIX_BT709LIMIT_TO_RGBFULL;
return HI_VO_CSC_MATRIX_BT709LIMIT_TO_BT709FULL;
}
hi_rotation HDMIVideoOutput::getRotationValue()
{
switch (getRotation())
{
default:
case 0:
return HI_ROTATION_0;
case 90:
return HI_ROTATION_90;
case 180:
return HI_ROTATION_180;
case 270:
return HI_ROTATION_270;
}
}
void HDMIVideoOutput::eventCallback(hi_hdmi_event_type event, td_void* p)
{
switch (event)
{
case HI_HDMI_EVENT_HOTPLUG:
static_cast<HDMIVideoOutput*>(p)->onHotPlug();
break;
case HI_HDMI_EVENT_NO_PLUG:
static_cast<HDMIVideoOutput*>(p)->onNoPlug();
break;
case HI_HDMI_EVENT_EDID_FAIL:
static_cast<HDMIVideoOutput*>(p)->onEDIDFail();
break;
default:
break;
}
}
}
}