整理代码

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,317 @@
/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "VideoOverlay.h"
#include "MPPChannel.h"
#include "ResourceManager.h"
#include "util/Math.h"
#include "Logger.h"
#include <hi_mpi_tde.h>
#include <hi_mpi_sys.h>
#include <hi_mpi_vb.h>
#include <Poco/Exception.h>
#include <cstring>
namespace Video
{
namespace MPP5
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
VideoOverlay::VideoOverlay(Core::VideoOverlayType type, const std::string& name, const Core::Rect& region)
: Core::VideoOverlay(type, name, region), _handle(ResourceManager::allocRGNHandle()), _imagePhyAddr(0),
_pImageVirAddr(nullptr)
{
hi_rgn_attr attr = {};
switch (type)
{
case Core::VideoOverlayType::CANVAS:
attr.type = HI_RGN_OVERLAY;
attr.attr.overlay.pixel_format = HI_PIXEL_FORMAT_ARGB_8888;
_bytesPerPixel = 4;
attr.attr.overlay.size.width = ::Util::Math::alignup(region.width, 2);
attr.attr.overlay.size.height = ::Util::Math::alignup(region.height, 2);
attr.attr.overlay.bg_color = 0;
attr.attr.overlay.canvas_num = 2;
break;
case Core::VideoOverlayType::MOSAIC:
attr.type = HI_RGN_MOSAIC;
break;
default:
throw Poco::LogicException(name + ": Unimplemented type: " + std::to_string((int)type));
}
int rc = hi_mpi_rgn_create(_handle, &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidArgumentException(Poco::format("%s: Create FAIL: %#x", name, (uint32_t)rc), rc);
}
VideoOverlay::~VideoOverlay()
{
_timer.cancel(true);
if (_pImageVirAddr != nullptr && _imagePhyAddr != 0)
hi_mpi_sys_mmz_free(_imagePhyAddr, _pImageVirAddr);
Core::VideoComponent::Ptr o = target();
auto chn = dynamic_cast<MPPChannel*>(o.get())->raw();
hi_mpi_rgn_detach_from_chn(_handle, &chn);
hi_mpi_rgn_destroy(_handle);
ResourceManager::freeRGNHandle(_handle);
}
void VideoOverlay::render(Core::Image::Ptr pImage)
{
hi_rgn_canvas_info info;
hi_mpi_rgn_get_canvas_info(_handle, &info);
uint32_t height = ::Util::Math::min((uint32_t)pImage->height(), (uint32_t)region().height);
for (uint32_t y = 0; y < height; y++)
{
int i = 0;
Core::Color color;
uint8_t* pLine = (uint8_t*)info.virt_addr + y * info.stride;
cimg_forX(*pImage, x)
{
if (x >= region().width)
continue;
pImage->getPixel(x, y, color);
color.toARGB8888Pixel(&pLine[i]);
i += _bytesPerPixel;
}
}
hi_mpi_rgn_update_canvas(_handle);
}
void VideoOverlay::scrollRender(Core::Image::Ptr pImage, int hscroll)
{
const int W = (int)region().width;
const int H = (int)::Util::Math::min((uint32_t)pImage->height(), (uint32_t)region().height);
const int textWidth = (int)pImage->width();
const int winW = (int)::Util::Math::min((uint32_t)W, 4096u);
const int period = 2 * W + textWidth;
const uint32_t stride = ::Util::Math::alignup((uint32_t)winW * _bytesPerPixel, 8);
int rc = hi_mpi_sys_mmz_alloc(&_imagePhyAddr, (void**)&_pImageVirAddr, nullptr, nullptr, (uint32_t)H * stride);
if (rc != HI_SUCCESS)
throw Poco::OutOfMemoryException(Poco::format("%s: Alloc MMZ FAIL: %#x", name(), (uint32_t)rc), rc);
_pTextImage = pImage;
_textWidth = textWidth;
_winW = winW;
_winH = H;
_stride = stride;
_period = period;
if (hscroll > 0)
_progressX = 0;
else
_progressX = period - W;
const int movePixels = hscroll;
const long interval = 30;
_timer.schedule(Poco::Util::Timer::func(
[this, W, movePixels]()
{
const int H = _winH;
const int winW = _winW;
const int textW = _textWidth;
const uint32_t stride = _stride;
const int period = _period;
::memset(_pImageVirAddr, 0, (uint32_t)H * stride);
int startStrip = (_progressX > W) ? _progressX : W;
int endStrip = ((_progressX + winW) < (W + textW)) ? (_progressX + winW) : (W + textW);
if (startStrip < endStrip)
{
int textStart = startStrip - W;
int winStart = startStrip - _progressX;
int count = endStrip - startStrip;
for (int y = 0; y < H; y++)
{
uint8_t* pWin =
_pImageVirAddr + (uint32_t)y * stride + (uint32_t)winStart * _bytesPerPixel;
Core::Color color;
for (int x = 0; x < count; x++)
{
_pTextImage->getPixel(textStart + x, y, color);
color.toARGB8888Pixel(&pWin[x * (int)_bytesPerPixel]);
}
}
}
hi_tde_surface srcSurface = {};
srcSurface.phys_addr = _imagePhyAddr;
srcSurface.color_format = HI_TDE_COLOR_FORMAT_ARGB8888;
srcSurface.height = (uint32_t)H;
srcSurface.width = (uint32_t)winW;
srcSurface.stride = stride;
srcSurface.is_ycbcr_clut = HI_FALSE;
srcSurface.alpha_max_is_255 = HI_TRUE;
srcSurface.support_alpha_ex_1555 = HI_FALSE;
srcSurface.alpha0 = 0XFF;
srcSurface.alpha1 = 0XFF;
hi_rgn_canvas_info info;
hi_mpi_rgn_get_canvas_info(_handle, &info);
const uint32_t dstW = ::Util::Math::min((uint32_t)region().width, 4096u);
const uint32_t dstH = ::Util::Math::min((uint32_t)region().height, 4096u);
hi_tde_surface dstSurface = {};
dstSurface.phys_addr = info.phys_addr;
dstSurface.color_format = HI_TDE_COLOR_FORMAT_ARGB8888;
dstSurface.height = dstH;
dstSurface.width = dstW;
dstSurface.stride = info.stride;
dstSurface.is_ycbcr_clut = HI_FALSE;
dstSurface.support_alpha_ex_1555 = HI_FALSE;
dstSurface.alpha_max_is_255 = HI_TRUE;
dstSurface.alpha0 = 0XFF;
dstSurface.alpha1 = 0XFF;
hi_tde_rect srcRect;
srcRect.pos_x = 0;
srcRect.pos_y = 0;
srcRect.width = (uint32_t)winW;
srcRect.height = (uint32_t)H;
hi_tde_rect dstRect;
dstRect.pos_x = 0;
dstRect.pos_y = 0;
dstRect.width = (uint32_t)winW;
dstRect.height = (uint32_t)H;
hi_s32 handle = hi_tde_begin_job();
hi_tde_single_src src;
src.src_surface = (hi_tde_surface*)&srcSurface;
src.dst_surface = (hi_tde_surface*)&dstSurface;
src.src_rect = (hi_tde_rect*)&srcRect;
src.dst_rect = (hi_tde_rect*)&dstRect;
int rc = hi_tde_quick_copy(handle, &src);
if (rc != HI_SUCCESS)
{
logger().error("%s: TDE quick copy FAIL: %#x", name(), (uint32_t)rc);
_timer.cancel(false);
return;
}
hi_tde_end_job(handle, HI_FALSE, HI_TRUE, 10);
hi_mpi_rgn_update_canvas(_handle);
_progressX += movePixels;
if (movePixels > 0)
{
if (_progressX >= period - W)
_progressX = 0;
}
else
{
if (_progressX <= 0)
_progressX = period - W;
}
}),
interval, interval);
}
void VideoOverlay::attach(Core::VideoComponent::Ptr pVideoComponent)
{
Core::VideoOverlay::attach(pVideoComponent);
hi_rgn_chn_attr attr = {};
attr.is_show = HI_TRUE;
switch (type())
{
case Core::VideoOverlayType::CANVAS:
attr.type = HI_RGN_OVERLAY;
attr.attr.overlay_chn.point.x = ::Util::Math::alignup(region().x, 2);
attr.attr.overlay_chn.point.y = ::Util::Math::alignup(region().y, 2);
attr.attr.overlay_chn.fg_alpha = 0;
attr.attr.overlay_chn.bg_alpha = 0;
attr.attr.overlay_chn.layer = getLayer();
attr.attr.overlay_chn.qp_info.enable = HI_FALSE;
attr.attr.overlay_chn.qp_info.is_abs_qp = HI_FALSE;
attr.attr.overlay_chn.qp_info.qp_val = 0;
attr.attr.overlay_chn.dst = HI_RGN_ATTACH_JPEG_MAIN;
break;
case Core::VideoOverlayType::MOSAIC:
attr.type = HI_RGN_MOSAIC;
attr.attr.mosaic_chn.rect.x = ::Util::Math::alignup(region().x, 4);
;
attr.attr.mosaic_chn.rect.y = ::Util::Math::alignup(region().y, 2);
attr.attr.mosaic_chn.rect.width = ::Util::Math::alignup(region().width, 4);
attr.attr.mosaic_chn.rect.height = ::Util::Math::alignup(region().height, 2);
attr.attr.mosaic_chn.blk_size = getBlockSize();
attr.attr.mosaic_chn.layer = getLayer();
break;
default:
throw Poco::LogicException(name() + ": Unimplemented type: " + std::to_string((int)type()));
}
auto t = target();
auto pChannel = dynamic_cast<MPPChannel*>(t.get());
if (!pChannel)
throw Poco::LogicException(name() + ": Unsupported target: " + target()->name());
auto chn = pChannel->raw();
int rc = hi_mpi_rgn_attach_to_chn(_handle, &chn, &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidArgumentException(Poco::format("%s: Attach FAIL: %#x", name(), (uint32_t)rc), rc);
}
void VideoOverlay::onConfigChanged(ParameterNames& names)
{
if (names.exists(_ZOrder))
{
auto t = target();
auto pChannel = dynamic_cast<MPPChannel*>(t.get());
auto chn = pChannel->raw();
hi_rgn_chn_attr attr;
hi_mpi_rgn_get_display_attr(_handle, &chn, &attr);
switch (attr.type)
{
case HI_RGN_OVERLAY:
attr.attr.overlay_chn.layer = getZOrder();
break;
default:
break;
}
hi_mpi_rgn_set_display_attr(_handle, &chn, &attr);
}
}
hi_mosaic_blk_size VideoOverlay::getBlockSize()
{
switch (getBlock())
{
default:
case 8:
return HI_MOSAIC_BLK_SIZE_8;
case 16:
return HI_MOSAIC_BLK_SIZE_16;
case 32:
return HI_MOSAIC_BLK_SIZE_32;
}
}
hi_u32 VideoOverlay::getLayer()
{
return ::Util::Math::clamp(getZOrder(), 0, 4);
}
}
}