整理代码
This commit is contained in:
commit
c7b4e178ec
364 changed files with 59691 additions and 0 deletions
317
video/hisi/mpp5/VideoOverlay.cpp
Normal file
317
video/hisi/mpp5/VideoOverlay.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue