Expand ArFramePlayback to allow to be loaded from single file ArFrames saved with "SaveToFile"
This commit is contained in:
@@ -19,26 +19,68 @@ namespace OpenVulkano::AR::Playback
|
|||||||
if (session->GetCapabilities().IsDepthSupported())
|
if (session->GetCapabilities().IsDepthSupported())
|
||||||
{
|
{
|
||||||
auto depth = frameReader.ReadDepthImage();
|
auto depth = frameReader.ReadDepthImage();
|
||||||
confImgData = std::move(depth.confidence.image);
|
SetDepthImgInfo(depth);
|
||||||
depthImgData = std::move(depth.depth.image);
|
|
||||||
depthImage.format = session->GetSessionMetadata().depthFormat;
|
|
||||||
depthImage.intrinsic = frameMetadata.intrinsic.GetForResolution({depth.depth.header.width, depth.depth.header.height});
|
|
||||||
depthImage.depth.data = depthImgData.get();
|
|
||||||
depthImage.depth.resolution = {depth.depth.header.width, depth.depth.header.height};
|
|
||||||
depthImage.confidence.data = confImgData.get();
|
|
||||||
depthImage.confidence.resolution = {depth.confidence.header.width, depth.confidence.header.height};
|
|
||||||
}
|
}
|
||||||
if (session->IsLoadColorEnabled())
|
if (session->IsLoadColorEnabled())
|
||||||
{
|
{
|
||||||
colorImgData = frameReader.ReadColorImage();
|
colorImgData = frameReader.ReadColorImage();
|
||||||
colorImage.intrinsic = frameMetadata.intrinsic.GetForResolution({colorImgData.cols, colorImgData.rows});
|
SetColorImgInfo();
|
||||||
colorImage.format = ArImagePlanar::Format::RGB;
|
|
||||||
colorImage.luminescenceOrColor = {colorImgData.data, {colorImgData.cols, colorImgData.rows}};
|
|
||||||
colorImage.luminescenceOrColor.numChannels = colorImgData.channels;
|
|
||||||
}
|
}
|
||||||
SetSaved();
|
SetSaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArFramePlayback::ArFramePlayback(const std::shared_ptr<ArSessionPlayback>& session, const std::filesystem::path& imagePath)
|
||||||
|
: ArFrame(session, 99999) // TODO find better way to generate id
|
||||||
|
{
|
||||||
|
ArchiveReader reader(imagePath);
|
||||||
|
DepthImage dImage;
|
||||||
|
while(reader.HasNext())
|
||||||
|
{
|
||||||
|
reader.GetNextFileAsStream([this, &dImage](const FileDescription& desc, std::istream& data)
|
||||||
|
{
|
||||||
|
if (desc.path.find("depth") != std::string::npos)
|
||||||
|
{
|
||||||
|
dImage.depth.TryRead(data);
|
||||||
|
}
|
||||||
|
else if (desc.path.find("confidence") != std::string::npos)
|
||||||
|
{
|
||||||
|
dImage.confidence.TryRead(data);
|
||||||
|
}
|
||||||
|
else if (desc.path.find("metadata") != std::string::npos)
|
||||||
|
{
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << data.rdbuf();
|
||||||
|
std::string str = buffer.str();
|
||||||
|
frameMetadata = ArFrameMetadata::FromContent(str.data(), str.size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
colorImgData.channels = ColorImg::RGBA; // TODO test if defaulting to NV12
|
||||||
|
colorImgData.Decode(Utils::ReadFile(imagePath));
|
||||||
|
SetDepthImgInfo(dImage);
|
||||||
|
SetSaved();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArFramePlayback::SetDepthImgInfo(DepthImage& depth)
|
||||||
|
{
|
||||||
|
confImgData = std::move(depth.confidence.image);
|
||||||
|
depthImgData = std::move(depth.depth.image);
|
||||||
|
depthImage.format = ArDepthFormat::METER_FP32; //TODO session->GetSessionMetadata().depthFormat;
|
||||||
|
depthImage.intrinsic = frameMetadata.intrinsic.GetForResolution({depth.depth.header.width, depth.depth.header.height});
|
||||||
|
depthImage.depth.data = depthImgData.get();
|
||||||
|
depthImage.depth.resolution = {depth.depth.header.width, depth.depth.header.height};
|
||||||
|
depthImage.confidence.data = confImgData.get();
|
||||||
|
depthImage.confidence.resolution = {depth.confidence.header.width, depth.confidence.header.height};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArFramePlayback::SetColorImgInfo()
|
||||||
|
{
|
||||||
|
colorImage.intrinsic = frameMetadata.intrinsic.GetForResolution({colorImgData.cols, colorImgData.rows});
|
||||||
|
colorImage.format = ArImagePlanar::Format::RGB;
|
||||||
|
colorImage.luminescenceOrColor = {colorImgData.data, {colorImgData.cols, colorImgData.rows}};
|
||||||
|
colorImage.luminescenceOrColor.numChannels = colorImgData.channels;
|
||||||
|
}
|
||||||
|
|
||||||
ArImagePlanar ArFramePlayback::GetCameraImage()
|
ArImagePlanar ArFramePlayback::GetCameraImage()
|
||||||
{
|
{
|
||||||
return colorImage;
|
return colorImage;
|
||||||
|
|||||||
@@ -15,9 +15,18 @@ namespace OpenVulkano::AR::Playback
|
|||||||
|
|
||||||
class ArFramePlayback final : public ArFrame
|
class ArFramePlayback final : public ArFrame
|
||||||
{
|
{
|
||||||
|
ArImagePlanar colorImage;
|
||||||
|
ArDepthImage depthImage;
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> confImgData;
|
||||||
|
std::unique_ptr<float[]> depthImgData;
|
||||||
|
ColorImg colorImgData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArFramePlayback(const std::shared_ptr<ArSessionPlayback>& session, ArPlaybackReader& frameReader);
|
ArFramePlayback(const std::shared_ptr<ArSessionPlayback>& session, ArPlaybackReader& frameReader);
|
||||||
|
|
||||||
|
ArFramePlayback(const std::shared_ptr<ArSessionPlayback>& session, const std::filesystem::path& imagePath);
|
||||||
|
|
||||||
ArImagePlanar GetCameraImage() override;
|
ArImagePlanar GetCameraImage() override;
|
||||||
|
|
||||||
ArDepthImage GetDepthImage() override;
|
ArDepthImage GetDepthImage() override;
|
||||||
@@ -27,11 +36,7 @@ namespace OpenVulkano::AR::Playback
|
|||||||
Math::Matrix4f GetCameraProjection(Math::Vector2f viewportSize, float near, float far) override;
|
Math::Matrix4f GetCameraProjection(Math::Vector2f viewportSize, float near, float far) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ArImagePlanar colorImage;
|
void SetDepthImgInfo(DepthImage& depth);
|
||||||
ArDepthImage depthImage;
|
void SetColorImgInfo();
|
||||||
|
|
||||||
std::unique_ptr<char[]> confImgData;
|
|
||||||
std::unique_ptr<float[]> depthImgData;
|
|
||||||
ColorImg colorImgData;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,64 +15,61 @@
|
|||||||
|
|
||||||
namespace OpenVulkano::AR::Playback
|
namespace OpenVulkano::AR::Playback
|
||||||
{
|
{
|
||||||
void ArPlaybackReader::ReadColorImage(ColorImg& img)
|
void ColorImg::Decode(const Array<char>& dataIn)
|
||||||
{
|
{
|
||||||
//BlockProfiler profiler("Load jpeg");
|
//BlockProfiler profiler("Load jpeg");
|
||||||
std::optional<std::pair<FileDescription, Array<char>>> file = ReadColorImageRaw();
|
|
||||||
|
|
||||||
long unsigned int jpegSize = file->second.Size();
|
long unsigned int jpegSize = dataIn.Size();
|
||||||
unsigned char* compressedImage = reinterpret_cast<uint8_t*>(file->second.Data());
|
unsigned char* compressedImage = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(dataIn.Data()));
|
||||||
|
|
||||||
int jpegSubsamp;
|
int jpegSubsamp;
|
||||||
tjhandle jpegDecompressor = tjInitDecompress();
|
tjhandle jpegDecompressor = tjInitDecompress();
|
||||||
tjDecompressHeader2(jpegDecompressor, compressedImage, jpegSize, &img.cols, &img.rows, &jpegSubsamp);
|
tjDecompressHeader2(jpegDecompressor, compressedImage, jpegSize, &cols, &rows, &jpegSubsamp);
|
||||||
|
|
||||||
if (img.UseRGB())
|
if (UseRGB())
|
||||||
{
|
{
|
||||||
img.channels = 4;
|
channels = 4;
|
||||||
if (!img.data) img.Allocate();
|
if (!data) Allocate();
|
||||||
|
|
||||||
tjDecompress2(jpegDecompressor, compressedImage, jpegSize, img.data, img.cols, 0/*pitch*/, img.rows, TJPF_RGBA, TJFLAG_FASTDCT);
|
tjDecompress2(jpegDecompressor, compressedImage, jpegSize, data, cols, 0/*pitch*/, rows, TJPF_RGBA, TJFLAG_FASTDCT);
|
||||||
}
|
}
|
||||||
else if (img.channels == 1)
|
else if (channels == 1)
|
||||||
{
|
{
|
||||||
if (!img.data) img.Allocate();
|
if (!data) Allocate();
|
||||||
|
|
||||||
tjDecompress2(jpegDecompressor, compressedImage, jpegSize, img.data, img.cols, 0/*pitch*/, img.rows, TJPF_GRAY, TJFLAG_FASTDCT);
|
tjDecompress2(jpegDecompressor, compressedImage, jpegSize, data, cols, 0/*pitch*/, rows, TJPF_GRAY, TJFLAG_FASTDCT);
|
||||||
}
|
}
|
||||||
else if (img.channels != 0)
|
else if (channels != 0)
|
||||||
{
|
{
|
||||||
if (!img.data) img.Allocate();
|
if (!data) Allocate();
|
||||||
|
|
||||||
std::array<uint8_t*, 3> planes;
|
std::array<uint8_t*, 3> planes;
|
||||||
size_t chromaSize = img.cols * img.rows / 4;
|
size_t chromaSize = cols * rows / 4;
|
||||||
planes[0] = img.data;
|
planes[0] = data;
|
||||||
if (!img.dataUV) img.dataUV = img.data + (img.cols * img.rows);
|
if (!dataUV) dataUV = data + (cols * rows);
|
||||||
Unique<uint8_t[]> chromaTmp;
|
Unique<uint8_t[]> chromaTmp;
|
||||||
if (img.channels == ColorImg::NV12 && !img.dataPtr)
|
if (channels == ColorImg::NV12 && !dataPtr)
|
||||||
{
|
{
|
||||||
chromaTmp = std::make_unique<uint8_t[]>(img.cols * img.rows / 2);
|
chromaTmp = std::make_unique<uint8_t[]>(cols * rows / 2);
|
||||||
planes[1] = chromaTmp.get();
|
planes[1] = chromaTmp.get();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
planes[1] = img.dataUV;
|
planes[1] = dataUV;
|
||||||
if (img.channels == ColorImg::NV12) planes[1] += chromaSize;
|
if (channels == ColorImg::NV12) planes[1] += chromaSize;
|
||||||
}
|
}
|
||||||
planes[2] = planes[1] + chromaSize;
|
planes[2] = planes[1] + chromaSize;
|
||||||
std::array<int, 3> rowSize = { img.cols, img.cols / 2, img.cols / 2 };
|
std::array<int, 3> rowSize = { cols, cols / 2, cols / 2 };
|
||||||
|
|
||||||
tjDecompressToYUVPlanes(jpegDecompressor, compressedImage, jpegSize, planes.data(),
|
tjDecompressToYUVPlanes(jpegDecompressor, compressedImage, jpegSize, planes.data(),
|
||||||
img.cols, rowSize.data(), img.rows, TJFLAG_FASTDCT);
|
cols, rowSize.data(), rows, TJFLAG_FASTDCT);
|
||||||
|
|
||||||
if (img.channels == ColorImg::NV12)
|
if (channels == ColorImg::NV12)
|
||||||
{
|
{
|
||||||
YuvUtils::NV12FromChromaPlanes(planes[1], img.data + (img.cols * img.rows), chromaSize);
|
YuvUtils::NV12FromChromaPlanes(planes[1], data + (cols * rows), chromaSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tjDestroy(jpegDecompressor);
|
tjDestroy(jpegDecompressor);
|
||||||
|
|
||||||
m_imgReadSize += 1000 + file.value().first.size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +84,7 @@ namespace OpenVulkano::AR::Playback
|
|||||||
ColorImg img;
|
ColorImg img;
|
||||||
auto file = m_archiveColor.GetNextFile();
|
auto file = m_archiveColor.GetNextFile();
|
||||||
img.dataPtr = std::shared_ptr<uint8_t>(
|
img.dataPtr = std::shared_ptr<uint8_t>(
|
||||||
stbi_load_from_memory(reinterpret_cast<stbi_uc*>(file->second.Data()), file->second.Size(), &img.cols, &img.rows, &img.channels, 3),
|
stbi_load_from_memory(reinterpret_cast<stbi_uc*>(data.Data()), data.Size(), &img.cols, &img.rows, &img.channels, 3),
|
||||||
&stbi_image_free);
|
&stbi_image_free);
|
||||||
img.data = img.dataPtr.get();
|
img.data = img.dataPtr.get();
|
||||||
m_imgReadSize += 1000 + file.value().first.size;
|
m_imgReadSize += 1000 + file.value().first.size;
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace OpenVulkano::AR::Playback
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool UseRGB() const { return channels == RGBA; }
|
bool UseRGB() const { return channels == RGBA; }
|
||||||
|
|
||||||
|
void Decode(const Array<char>& data);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArPlaybackReader final
|
class ArPlaybackReader final
|
||||||
@@ -72,14 +74,14 @@ namespace OpenVulkano::AR::Playback
|
|||||||
{
|
{
|
||||||
ColorImg img;
|
ColorImg img;
|
||||||
img.channels = ColorImg::RGBA; // TODO test if defaulting to NV12
|
img.channels = ColorImg::RGBA; // TODO test if defaulting to NV12
|
||||||
ReadColorImage(img);
|
std::optional<std::pair<FileDescription, Array<char>>> file = ReadColorImageRaw();
|
||||||
|
img.Decode(file->second);
|
||||||
|
m_imgReadSize += 1000 + file.value().first.size;
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::pair<FileDescription, Array<char>>> ReadColorImageRaw() { return m_archiveColor.GetNextFile(); }
|
std::optional<std::pair<FileDescription, Array<char>>> ReadColorImageRaw() { return m_archiveColor.GetNextFile(); }
|
||||||
|
|
||||||
void ReadColorImage(ColorImg& img);
|
|
||||||
|
|
||||||
DepthImage ReadDepthImage()
|
DepthImage ReadDepthImage()
|
||||||
{
|
{
|
||||||
DepthImage img;
|
DepthImage img;
|
||||||
|
|||||||
Reference in New Issue
Block a user