Update AR data recording to use Events for new frame recording, add more config options and prepare for async recording

This commit is contained in:
2021-07-26 21:57:56 +02:00
parent 440b6ca0e5
commit 7faf3a7a7d
6 changed files with 141 additions and 43 deletions

View File

@@ -42,12 +42,15 @@ namespace openVulkanoCpp::AR
}
ArRecorder::ArRecorder(ArSession* session)
: m_session(session), m_path(GeneratePath(AppFolders::GetAppDataHomeDir(), "ar_recording"))
{}
: m_session(session)
{
m_settings.path = GeneratePath(AppFolders::GetAppDataHomeDir(), "ar_recording");
session->OnNewFrameHighResolution += EventHandler(this, &ArRecorder::SaveHighResolution);
}
ArRecorder::~ArRecorder() = default;
void ArRecorder::WriteColorImage(ArFrame* arFrame)
void ArRecorder::WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, bool highRes)
{
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
#ifndef TURBO_JPEG
@@ -66,8 +69,7 @@ namespace openVulkanoCpp::AR
tjhandle handle = tjInitCompress();
const uint8_t* buffers[3];
std::unique_ptr<uint8_t[]> dataBuffer;
bool downsampleRecording = true;
if (downsampleRecording)
if (m_settings.downsampleColor && !highRes)
{
dataBuffer = YuvUtils::PlansFromNV12(static_cast<uint8_t*>(img.luminescenceOrColor.data), static_cast<uint8_t*>(img.uv.data),
resX, resY, img.uv.resolution.x, img.uv.resolution.y, 2, 2);
@@ -91,12 +93,12 @@ namespace openVulkanoCpp::AR
if (tjCompressFromYUVPlanes(handle, buffers, resX, nullptr, resY, TJSAMP_420, &outBuffer, &size, 95, TJFLAG_FASTDCT))
Logger::AR->error("Failed to create JPEG! {}", tjGetErrorStr());
else
m_colorWriter->AddFile(fileName.c_str(), outBuffer, size);
colorWriter->AddFile(fileName.c_str(), outBuffer, size);
tjFree(outBuffer);
#endif
}
void ArRecorder::WriteDepthImage(ArFrame* arFrame)
void ArRecorder::WriteDepthImage(ArFrame* arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter)
{
if (!m_depthWriter || !m_confidenceWriter) return;
auto depthImg = arFrame->GetDepthImage();
@@ -111,7 +113,7 @@ namespace openVulkanoCpp::AR
buffers[1].second = depthImg.depth.resolution.x * depthImg.depth.resolution.y * sizeof(float);
const std::string fileName = GetFileName(arFrame->GetFrameId(), "pfm");
m_depthWriter->AddFile(fileName.c_str(), buffers);
depthWriter->AddFile(fileName.c_str(), buffers);
}
{
@@ -124,29 +126,31 @@ namespace openVulkanoCpp::AR
buffers[1].second = static_cast<size_t>(depthImg.confidence.resolution.x * depthImg.confidence.resolution.y);
const std::string fileName = GetFileName(arFrame->GetFrameId(), "pgm");
m_confidenceWriter->AddFile(fileName.c_str(), buffers);
confWriter->AddFile(fileName.c_str(), buffers);
}
}
void ArRecorder::Save(ArFrame* frame)
void ArRecorder::Write(ArFrame* frame, bool highRes)
{
if (!m_recording || frame->IsSaved()) return;
if (frame->IsSaved()) return;
frame->SetSaved();
bool useHighResWriter = highRes && m_settings.highResFramesInSeparateArchive;
BlockProfiler profile("Save AR Frame");
{
BlockProfiler profile("Save AR Frame - Image");
WriteColorImage(frame);
}
{
//BlockProfiler profile("Save AR Frame - Depth");
WriteDepthImage(frame);
}
{
BlockProfiler profileMeta("Save AR Frame - Meta");
std::string metaContent = frame->GetFrameMetadata().ToXML();
std::string fileName = GetFileName(frame->GetFrameId(), "meta");
m_metadataWriter->AddFile(fileName.c_str(), metaContent.c_str(), metaContent.size());
(useHighResWriter ? m_highResWriter : m_metadataWriter)->AddFile(fileName.c_str(), metaContent.c_str(), metaContent.size());
}
{
BlockProfiler profile("Save AR Frame - Image");
WriteColorImage(frame, useHighResWriter ? m_highResWriter.get() : m_colorWriter.get(), highRes);
}
{
//BlockProfiler profile("Save AR Frame - Depth");
WriteDepthImage(frame,
useHighResWriter ? m_highResWriter.get() : m_depthWriter.get(),
useHighResWriter ? m_highResWriter.get() : m_confidenceWriter.get());
}
}
@@ -154,12 +158,13 @@ namespace openVulkanoCpp::AR
{
if (!m_colorWriter)
{
m_colorWriter = std::make_unique<MultiPartArchiveWriter>(m_path, "color_{:05d}.tar", ArchiveConfig::TAR);
m_depthWriter = std::make_unique<MultiPartArchiveWriter>(m_path, "depth_{:05d}.tar", ArchiveConfig::TAR);
m_confidenceWriter = std::make_unique<MultiPartArchiveWriter>(m_path, "confidence_{:05d}.tar", ArchiveConfig::TAR_GZ);
m_metadataWriter = std::make_unique<MultiPartArchiveWriter>(m_path, "meta_{:05d}.tar", ArchiveConfig::TAR_GZ);
m_colorWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path, "color_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true);
m_depthWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path, "depth_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true);
m_confidenceWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path, "confidence_{:05d}.tar.gz", ArchiveConfig::TAR_GZ, m_settings.archiveSize, true);
m_metadataWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path, "meta_{:05d}.tar.gz", ArchiveConfig::TAR_GZ, m_settings.archiveSize, true);
m_highResWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path, "highres_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true);
std::ofstream platformInfoStream(m_path / "ArRecording.xml");
std::ofstream platformInfoStream(m_settings.path / "ArRecording.xml");
platformInfoStream << m_session->GetSessionMetadata().ToXML();
platformInfoStream.close();
}
@@ -170,7 +175,7 @@ namespace openVulkanoCpp::AR
{
if (!m_recording) return;
m_recording = false;
for(MultiPartArchiveWriter* writer : { m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get() })
for(MultiPartArchiveWriter* writer : { m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get(), m_highResWriter.get() })
{
writer->Split();
}
@@ -180,14 +185,49 @@ namespace openVulkanoCpp::AR
{
if (!m_colorWriter)
{
for (MultiPartArchiveWriter* writer: {m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get()})
for (MultiPartArchiveWriter* writer: { m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get(), m_highResWriter.get() })
{
writer->Move(path);
}
std::filesystem::rename(m_path / "ArRecording.xml", path + "/ArRecording.xml");
std::filesystem::rename(m_settings.path / "ArRecording.xml", path + "/ArRecording.xml");
}
m_persistent = true;
m_path = path;
m_settings.path = path;
}
void ArRecorder::SetRecordingMode(RecordingMode mode)
{
if (m_settings.recordingMode == mode) return;
if (m_settings.recordingMode == RecordingMode::NEW_FRAME && m_newFrameHandler)
{
m_session->OnNewFrame -= m_newFrameHandler;
m_newFrameHandler = nullptr;
}
m_settings.recordingMode = mode;
if (m_settings.recordingMode == RecordingMode::NEW_FRAME)
{
m_newFrameHandler = m_session->OnNewFrame += EventHandler(this, &ArRecorder::Save);
}
}
void ArRecorder::Save(const std::shared_ptr<ArFrame>& frame)
{
if (!m_recording) return;
if (m_settings.asyncRecording)
{
}
else Write(frame.get());
}
void ArRecorder::SaveHighResolution(const std::shared_ptr<ArFrame>& frame)
{
if (!m_recording) return;
if (m_settings.asyncRecording)
{
}
else Write(frame.get(), true);
}
}