Part1前言

在用UE5进行项目开发的时候,进程需要进行安防视频的播放,如rtsp的视频流。本文针对这一需求,开发了基于UE5的InVideo插件,使用了安防视频的播放。

Part2实现思路

视频流的获取基于opencv库实现,之后将获取的数据转成Texture2D对象,再通过Image组件进行更新播放。另外,为了提高渲染的性能,我将所有的操作都移植到子系统进行,从而避免game线程卡主,影响整体渲染性能。

1引用opencv库

我们在InOpenCV.Build.cs文件中,设置相关依赖库的加载。方法如下:

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.IO;
using UnrealBuildTool;public class InOpenCV : ModuleRules
{public InOpenCV(ReadOnlyTargetRules Target) : base(Target){Type = ModuleType.External;string PlatformDir = Target.Platform.ToString();string IncPath = Path.Combine(ModuleDirectory, "include");string BinaryPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../Binaries/ThirdParty", PlatformDir));if (Target.Platform == UnrealTargetPlatform.Win64){PublicSystemIncludePaths.Add(IncPath);string LibPath = Path.Combine(ModuleDirectory, "lib", PlatformDir);string LibName = "opencv_world460";string LibFfmpeg = "opencv_videoio_ffmpeg460_64";PublicAdditionalLibraries.Add(Path.Combine(LibPath, LibName + ".lib"));string DLLName = LibName + ".dll";string DLLFfmpeg = LibFfmpeg + ".dll";PublicDelayLoadDLLs.Add(DLLName);PublicDelayLoadDLLs.Add(DLLFfmpeg);RuntimeDependencies.Add(Path.Combine(BinaryPath, DLLName));RuntimeDependencies.Add(Path.Combine(BinaryPath, DLLFfmpeg));PublicDefinitions.Add("OPENCV_PLATFORM_PATH=Binaries/ThirdParty/" + PlatformDir);PublicDefinitions.Add("OPENCV_DLL_NAME=" + DLLName);PublicDefinitions.Add("OPENCV_DLL_FFMPEG=" + DLLFfmpeg);}else // unsupported platform{}}
}

2使用Opencv库

由于虚幻的check宏定义和opencv的check冲突,所以直接使用编译是无法通过的。我们需要是使用头文件的时候,增加PreOpenCVHeaders和PostOpenCVHeaders两个文件,一前一后。

#include "PreOpenCVHeaders.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include "PostOpenCVHeaders.h"

3子线程

为了提高渲染效率,我们采用FRunnable方式使用子线程进行相关操作。
创建子线程

m_Thread = FRunnableThread::Create(this, TEXT("Video Thread"));

线程同步

由于UTexture2D只能在GameThread进行创建,但是我们使用是在子线程进行,所以这里需要进行线程同步。我们采用事件的方式进行。示例如下:

FEvent* SyncEvent = FGenericPlatformProcess::GetSynchEventFromPool(false);AsyncTask(ENamedThreads::GameThread, [this, SyncEvent](){VideoTexture = UTexture2D::CreateTransient(m_VideoSize.X, m_VideoSize.Y);if (VideoTexture){VideoTexture->UpdateResource();}m_Texture2DResource = (FTexture2DResource*)VideoTexture->GetResource();UE_LOG(LogTemp, Log, TEXT("UInVideoWidget UpdateTexture CreateTransient"));SyncEvent->Trigger();});SyncEvent->Wait();FGenericPlatformProcess::ReturnSynchEventToPool(SyncEvent);

原子对象

在控制线程退出时,我们通过原子变量进行控制。示例如下

TAtomic<bool> m_Stopping = false;while (false == m_Stopping)
{}

4更新纹理

再获取到数据之后,我们直接将数据更新到渲染线程的纹理中,不再进行gpu进行,示例代码如下 另外,UE5也提供了UpdateTextureRegions函数,但是经过测试这个函数只能在GameThread进行使用,我们改造了一下,使得其可以适应在子线程中运行。

for (int y = 0; y < m_VideoSize.Y; y++){for (int x = 0; x < m_VideoSize.X; x++){int i = x + (y * m_VideoSize.X);Data[i].B = m_WrapOpenCv->m_Frame.data[i * 3 + 0];Data[i].G = m_WrapOpenCv->m_Frame.data[i * 3 + 1];Data[i].R = m_WrapOpenCv->m_Frame.data[i * 3 + 2];}}
UpdateTextureRegions(VideoTexture,(int32)0, (uint32)1, m_VideoUpdateTextureRegion, (uint32)(4 * m_VideoSize.X), (uint32)4, (uint8*)Data.GetData(), false);
void UInVideoWidget::UpdateTextureRegions(UTexture2D* Texture, int32 MipIndex, uint32 NumRegions, FUpdateTextureRegion2D* Regions, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, bool bFreeData)
{if (m_Texture2DResource){struct FUpdateTextureRegionsData{FTexture2DResource* Texture2DResource;int32 MipIndex;uint32 NumRegions;FUpdateTextureRegion2D* Regions;uint32 SrcPitch;uint32 SrcBpp;uint8* SrcData;};FUpdateTextureRegionsData* RegionData = new FUpdateTextureRegionsData;RegionData->Texture2DResource = m_Texture2DResource;RegionData->MipIndex = MipIndex;RegionData->NumRegions = NumRegions;RegionData->Regions = Regions;RegionData->SrcPitch = SrcPitch;RegionData->SrcBpp = SrcBpp;RegionData->SrcData = SrcData;ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData)([RegionData, bFreeData](FRHICommandListImmediate& RHICmdList) {for (uint32 RegionIndex = 0; RegionIndex < RegionData->NumRegions; ++RegionIndex){int32 CurrentFirstMip = RegionData->Texture2DResource->GetCurrentFirstMip();if (RegionData->MipIndex >= CurrentFirstMip){RHIUpdateTexture2D(RegionData->Texture2DResource->GetTexture2DRHI(),RegionData->MipIndex - CurrentFirstMip,RegionData->Regions[RegionIndex],RegionData->SrcPitch,RegionData->SrcData+ RegionData->Regions[RegionIndex].SrcY * RegionData->SrcPitch+ RegionData->Regions[RegionIndex].SrcX * RegionData->SrcBpp);}}if (bFreeData){FMemory::Free(RegionData->Regions);FMemory::Free(RegionData->SrcData);}delete RegionData;});}
}

5更新视频

直接调用ImageVideo更新纹理即可实现视频的播放

ImageVideo->SetBrushFromTexture(VideoTexture);

6插件使用

新建一个蓝图widget继承自InVideoWgidget,并新建一个Image对象,重新命名为ImageVideo。即可进行调用,可以参考videoUmg组件。

打开视频方法

关闭视频方法

Part3总结

本文主要介绍了一种基于UE5的安防视频播放思路。最后划重点,项目开源地址如下:https://github.com/inveta/InVideo

Part4关于IN VETA

IN VETA是一支由建模、美术、UE5组成的年轻团队。

我们致力于三维数字孪生技术分享与研发。
欢迎与各界朋友一起探讨技术与商务合作,一起推动数字孪生的发展。

紧急!UE5插播一条安防视频相关推荐

  1. 安防视频监控无处不在 密织安全防控网必不可少

    [导读]随着社会的不断发展,安防视屏监控已经成为城市发展的重点,覆盖率极高.无论是上商用还是私用,都很受欢迎,下面虽笔者一起看看这些城市的安防监控视频都干了些啥? 安防监控系统是应用光纤.同轴电缆或微 ...

  2. Qt编写安防视频监控系统26-硬件加速

    一.前言 硬件加速这个功能在一年多以前就已经具备,当时对两个内核一个是ffmpeg内核.一个是vlc内核都做了对应的接口函数,只是当时为了简单没有在系统设置中做出接口,vlc做硬件加速不用自己写代码实 ...

  3. 支付宝技术专家李战斌:安防视频行为分析系统的技术演进及应用场景 | 2018FMI人工智能与大数据高峰论坛(深圳站)

    10月28日FMI 2018人工智能与大数据高峰论坛深圳场圆满落幕,支付宝技术专家李战斌以安防视频行为分析系统的技术演进及应用场景为主题进行了精彩的分享. 支付宝技术专家李战斌 以下是李战斌的演讲内容 ...

  4. 2022-2028年中国安防视频行业市场前景分析预测报告

    [报告类型]产业研究 [报告价格]4500起 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了中国安防视频行业市场行业相关概述.中国安防视 ...

  5. 中国安防视频监控行业发展前景分析

    [导读]视频监控系统作为安防必不可少的技术手段,正在全球安防领域扮演越来越重要的角色,其已逐渐发展为世界各国政府.企业乃至个人家庭安防系统建设领域的刚性需求. 一.全球安防视频监控市场容量巨大,未来仍 ...

  6. 从交换机浅谈安防视频会卡顿现象

    解决视频卡顿.重新定义适用于安防视频数据的交换机才是正途.超高性价比(与企业级相当).宽温(保证室外应用稳定).大缓存(保证每一个端口大数据帧不卡顿).高防护(IP30 40,保证适用恶劣环境).电源 ...

  7. 【解决方案】SkeyeVSS综合安防视频云服务在零售连锁巡店中的应用

    在当前消费升级的大环境下,用户的购物体验是很多零售行业的基础建设目标,因此技术化和数字化管理也得到更加广泛的应用.零售行业视频监控系统是通过新技术的运用,提高零售行业的防损及运营管理的效率,降低人力成 ...

  8. 文读懂安防视频监控系统中H.265、SVAC、GB/T28181、ONVIF、PSIA的区别。

    概览 H.265是和H.26x/MPEG-x AVC一样是一种编码压缩的技术,其具体高效率的编码方式. SVAC<安全防范监控数字视音频编解码技术标准>是国家规范化的编码方式,安全防范监控 ...

  9. 2021安防视频监控运维市场回顾和展望

    2021安防视频监控运维市场回顾和展望 --专访弘度科技产品总监李焕佳 摘自<中国安防>2021.12期 随着国家"十四五"规划指出要加快数字化发展.建设数字中国等众多 ...

最新文章

  1. AI一分钟|苹果无人车可根据乘客情绪调整行车方式;快商通完成近亿元融资
  2. Windows Server 2012 R2 WSUS-11:经典的客户端排错操作
  3. C# WinForm控件、自定义控件整理(大全)
  4. 在计算机硬盘中没有什么,如果在打开计算机后找不到硬盘,应该怎么办?
  5. [转]携程大数据实践:高并发应用架构及推荐系统案例
  6. python中isalpha()、isdigit()、isalnum()、isupper()、islower()的含义、区别和细节
  7. 第一章 前缀和与差分
  8. php图片颤抖,PHP-使用jquery 怎么做出图片的震荡效果
  9. python快速读取大文件_Python学习的窍门:如何读取大文件
  10. 解读机械图样——剖视图
  11. C语言编程>第十六周 ⑤ 请补充fun函数,该函数的功能是:依次取出字符串中所有大写字母,形成新的字符串,并取代原字符串。
  12. 急!灾区的食物依然短缺!(找不到原题出处只能这样了.....)
  13. from keras.preprocessing.sequence import pad_sequences 标红
  14. 帝国CMS7.5基于es(Elasticsearch)7.x的全文搜索插件
  15. Oracle VM VirtualBox上配置新的Ubuntu20.04
  16. wps office android,WPS Office
  17. 泛融云计算机研究院,深圳泛融云计算研究院正式成立
  18. 在CSDN的六载时光,由你来决定今年的博客之星
  19. 华为云ECS,如何助力数字化企业创新发展
  20. 计算机语音未来发展趋势,语音助手横评:发展现状|未来展望

热门文章

  1. 如何让DIV相对于body水平和垂直居中
  2. android qq字体大小设置快捷键,电脑端QQ怎么将字体选择设置为气泡模式
  3. 新手如何入门学习车载测试
  4. Python——根据散点数据绘制三维曲面图( meshgrid函数以及Axes3D [plot_surface] )
  5. python第十一章习题
  6. SSM医院住院管理系统
  7. CentOS7初始化配置教程
  8. cmd 查看端口的一些命令
  9. HR怎么通过简历判断程序员是否优秀?
  10. FutureTask原理解析-java多线程(实现并行计算)