Update ArRecorder to append metadata and depth image to jpg

This commit is contained in:
Georg Hagen
2025-05-19 20:58:05 +02:00
parent 8716857efe
commit 257430da1d
3 changed files with 35 additions and 19 deletions

View File

@@ -8,6 +8,7 @@
#include "ArSession.hpp" #include "ArSession.hpp"
#include "ArFrame.hpp" #include "ArFrame.hpp"
#include "IO/Archive/MultiPartArchiveWriter.hpp" #include "IO/Archive/MultiPartArchiveWriter.hpp"
#include "IO/Archive/ArchiveConfiguration.hpp"
#include "IO/Files/Pfm.hpp" #include "IO/Files/Pfm.hpp"
#include "IO/Files/Pnm.hpp" #include "IO/Files/Pnm.hpp"
#include "IO/AppFolders.hpp" #include "IO/AppFolders.hpp"
@@ -85,7 +86,7 @@ namespace OpenVulkano::AR
else m_asyncProcessor.Close(); else m_asyncProcessor.Close();
} }
void ArRecorder::WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const void ArRecorder::WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, JpegWithTagsWriter* jpgWriter, bool highRes) const
{ {
//BlockProfiler profile("Save AR Frame - Image"); //BlockProfiler profile("Save AR Frame - Image");
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg"); std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
@@ -134,13 +135,9 @@ namespace OpenVulkano::AR
{ {
if (colorWriter) [[likely]] if (colorWriter) [[likely]]
colorWriter->AddFile(fileName.c_str(), outBuffer, size); colorWriter->AddFile(fileName.c_str(), outBuffer, size);
if (path) [[unlikely]] if (jpgWriter) [[unlikely]]
{ {
auto exif = MakeExifTag(arFrame); jpgWriter->WriteImageData({ outBuffer, size }, false); // Keep open, livetime is managed outside
JpegWithTagsWriter writer(*path);
writer.WriteExifTag(exif);
writer.WriteXmpTag(MakeXmpTag(arFrame));
writer.WriteImageData({ outBuffer, size });
} }
} }
tjFree(outBuffer); tjFree(outBuffer);
@@ -302,14 +299,18 @@ namespace OpenVulkano::AR
void ArRecorder::WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool includeAux) void ArRecorder::WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool includeAux)
{ {
WriteColorImage(frame.get(), nullptr, &path, !downsample); JpegWithTagsWriter jpgWriter(path);
jpgWriter.WriteExifTag(MakeExifTag(frame.get()));
jpgWriter.WriteXmpTag(MakeXmpTag(frame.get()));
WriteColorImage(frame.get(), nullptr, &jpgWriter, !downsample);
if (includeAux) if (includeAux)
{ {
auto fName = path.string(); FILE* file = jpgWriter.GetFilePtr();
fName.replace(fName.size() - 3, 3, "aux"); {
ArchiveWriter writer(fName); ArchiveWriter writer(file, ArchiveConfiguration(ArchiveType::ZIP));
WriteMetadata(frame.get(), &writer); WriteMetadata(frame.get(), &writer);
WriteDepthImage(frame.get(), &writer, &writer); WriteDepthImage(frame.get(), &writer, &writer);
}
} }
} }

View File

@@ -24,6 +24,7 @@ namespace OpenVulkano
class IEventHandler; class IEventHandler;
class IArchiveWriter; class IArchiveWriter;
class MultiPartArchiveWriter; class MultiPartArchiveWriter;
class JpegWithTagsWriter;
} }
namespace OpenVulkano::AR namespace OpenVulkano::AR
@@ -100,7 +101,7 @@ namespace OpenVulkano::AR
void Write(ArFrame* frame, bool highRes = false); void Write(ArFrame* frame, bool highRes = false);
void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter); void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter);
void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const; void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, JpegWithTagsWriter* jpgWriter, bool highRes) const;
void WriteDepthImage(ArFrame *arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter); void WriteDepthImage(ArFrame *arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter);
void WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux); void WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux);

View File

@@ -36,6 +36,7 @@ namespace OpenVulkano
// ReSharper disable once CppDFAConstantParameter // ReSharper disable once CppDFAConstantParameter
void WriteAppMarker(const int app = 1) const void WriteAppMarker(const int app = 1) const
{ {
Check();
// ReSharper disable once CppDFAConstantConditions // ReSharper disable once CppDFAConstantConditions
if (app > 0xF) [[unlikely]] throw std::runtime_error("App marker is out of range."); if (app > 0xF) [[unlikely]] throw std::runtime_error("App marker is out of range.");
fputc(0xFF, file); fputc(0xFF, file);
@@ -72,8 +73,20 @@ namespace OpenVulkano
fputc(0xFF, file); fputc(0xFF, file);
fputc(0xD8, file); fputc(0xD8, file);
} }
~JpegWithTagsWriter()
{
if (file) Close();
}
void Close()
{
if (!file) throw std::runtime_error("Jpeg file alreay closed!");
fclose(file);
file = nullptr;
}
void WriteExifTag(const std::span<uint8_t>& exifTag) const void WriteExifTag(const std::span<const uint8_t>& exifTag) const
{ {
WriteAppMarker(); WriteAppMarker();
Write16(exifTag.size() + 2); // 2 byte extra for the size value itself Write16(exifTag.size() + 2); // 2 byte extra for the size value itself
@@ -91,17 +104,18 @@ namespace OpenVulkano
} }
// Must be called as last function, as this will finalize the image writing and will close the file // Must be called as last function, as this will finalize the image writing and will close the file
void WriteImageData(const std::span<uint8_t>& imageData) void WriteImageData(const std::span<uint8_t>& imageData, bool close = true)
{ {
Check(); Check();
// write image data and skip soi marker from og data // write image data and skip soi marker from og data
fwrite(imageData.data() + 2, sizeof(uint8_t), imageData.size() - 2, file); fwrite(imageData.data() + 2, sizeof(uint8_t), imageData.size() - 2, file);
fclose(file); if (close) Close();
file = nullptr;
} }
operator bool() const { return file != nullptr; } operator bool() const { return file != nullptr; }
bool IsOpen() const { return file != nullptr; } [[nodiscard]] bool IsOpen() const { return file != nullptr; }
[[nodiscard]] FILE* GetFilePtr() const { return file; }
}; };
} }