我一直在努力使Agora在虚幻引擎5中正常工作两天,没有任何运气。它的包装正确,但在打开相机后,它崩溃了。我已经找到了导致崩溃的函数和线路,我已经尝试了我能想到的每一个解决方案,但它仍然崩溃。这是坠机信息。
LogOutputDevice: Error: Ensure condition failed: oldValue == newValue [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\ThreadingBase.cpp] [Line: 300]
oldValue(1) newValue(0) If this check fails make sure that there is a FTaskTagScope(ETaskTag::EParallelRenderingThread) as deep as possible on the current callstack, you can see the current value in ActiveNamedThreads(1), GRenderingThread(d606da40), GIsRenderingThreadSuspended(0)
LogStats: FDebug::EnsureFailed - 0.000 s
坠机日志:
未处理异常: EXCEPTION_ACCESS_VIOLATION读取地址0x000002428c15b020
我在插件中使用了模板项目。这个项目在4.26上做得很好。我把它转换成UE5和,只有从目标平台上禁用了安卓和IOS。
这是我的代码:
VideoFrameObserver.cpp
bool VideoFrameObserver::onCaptureVideoFrame( VideoFrame& videoFrame )
{
const std::lock_guard<std::mutex> lock( localFrameMutex );
if( !localFrame.texture ||
localFrame.texture->GetSizeX() != videoFrame.width ||
localFrame.texture->GetSizeY() != videoFrame.height )
{
localFrame.region.reset( new FUpdateTextureRegion2D( 0, 0, 0, 0, videoFrame.width, videoFrame.height ) );
localFrame.texture = UTexture2D::CreateTransient( videoFrame.width, videoFrame.height, PF_R8G8B8A8 );
//Causes the crash on Unreal Engine 5
localFrame.texture->UpdateResource();
}
if (!ensure(localFrame.texture != nullptr))
{
return false;
}
localFrame.texture->UpdateTextureRegions( 0, 1, localFrame.region.get(), videoFrame.yStride, ( uint32 ) argbPixSize, static_cast< uint8_t* >( videoFrame.yBuffer ) );
localFrame.fresh = true;
return true;
}
void VideoFrameObserver::OnTick( float DeltaTime )
{
localFrameMutex.lock();
if( localFrame.fresh )
{
if( m_agora )
m_agora->OnLocalFrameReceivedDelegate.Broadcast( localFrame.texture );
localFrame.fresh = false;
}
localFrameMutex.unlock();
remoteFrameMutex.lock();
std::for_each( remoteUsersFrames.begin(), remoteUsersFrames.end(),
[this]( auto& frame )
{
if( frame.second.fresh )
{
if( m_agora )
m_agora->OnRemoteFrameReceivedDelegate.Broadcast( frame.first, frame.second.texture );
frame.second.fresh = false;
}
} );
remoteFrameMutex.unlock();
}
导致崩溃的行:
localFrame.texture->UpdateResource()
下面是调用堆栈:呼叫堆栈
启用引擎代码调试之后,它将在这里抛出异常。
ThreadingBase.cpp
另一件事是,如果我在调试模式下打开编辑器,当我点击play并打开相机时,它会抛出异常,但是如果我按下“继续”,它就会工作得很好,相机也会正常播放!!这很奇怪。这个问题可以通过尝试接球来解决,但它在虚幻引擎中被禁用和阻止。
模板项目:https://github.com/AgoraIO-Community/Agora-Unreal-SDK-Blueprint
Agora插件:https://github.com/AgoraIO-Community/Agora-Unreal-SDK-Blueprint/releases
发布于 2022-06-26 02:00:57
我在Agora和UE5中遇到了几乎完全正确的错误,虽然我不能100%肯定这会为您修复它,但我已经无法重现崩溃了。
第一个问题是(根据非真实的UE5引擎Texture.cpp源代码),任何纹理复制操作都不能发生在呈现线程上。为了满足明显的需求,我将整个代码块包装在一个GameThread lambda中-参见:
AsyncTask(ENamedThreads::GameThread, [=](){
// your routine
})
然而,还有第二个问题。Agora没有责任保持帧的任何时间超过这个召唤。对UpdateTextureRegions()的调用可能会失败,因为videoFrame.yBuffer可能会失效。为了避免这种情况,我手动使用memcpy()将原始缓冲区复制到瞬态内存,然后在空闲时复制该副本(在异步lambda中异步复制)。
int yStride = videoFrame.yStride;
uint8* yBuffer2 = new uint8[ videoFrame.height * videoFrame.yStride ];
memcpy(yBuffer2,videoFrame.yBuffer,videoFrame.height * videoFrame.yStride);
AsyncTask(ENamedThreads::GameThread, [=](){
// ... insert other code here
// copy buffer at your leisure
localFrame.texture->UpdateTextureRegions(
0, 1,
localFrame.region.get(),
yStride,
( uint32 ) argbPixSize,
static_cast< uint8_t* >( yBuffer2 )
);
// liberate the buffer
delete[] yBuffer2;
})
记住使用delete[]删除缓冲区。希望这能有所帮助。
稍后编辑:我修改了我的方法,在这里我有一个更完整的例子:https://gist.github.com/anselm/2c786cc7f395c5c819197d511726c27a
https://stackoverflow.com/questions/72596102
复制相似问题