Skip to content
Snippets Groups Projects
file_source.cpp 2.45 KiB
Newer Older
#include "file_source.hpp"

using ftl::rgbd::detail::FileSource;
using ftl::codecs::codec_t;

void FileSource::_createDecoder(int ix, const ftl::codecs::Packet &pkt) {
	if (decoders_[ix]) {
		if (!decoders_[ix]->accepts(pkt)) {
			ftl::codecs::free(decoders_[ix]);
		} else {
			return;
		}
	}

	LOG(INFO) << "Create a decoder: " << ix;
	decoders_[ix] = ftl::codecs::allocateDecoder(pkt);
}

FileSource::FileSource(ftl::rgbd::Source *s, ftl::codecs::Reader *r, int sid) : ftl::rgbd::detail::Source(s) {
    reader_ = r;
	has_calibration_ = false;
	decoders_[0] = nullptr;
	decoders_[1] = nullptr;
	cache_read_ = -1;
	cache_write_ = 0;

    r->onPacket(sid, [this](const ftl::codecs::StreamPacket &spkt, ftl::codecs::Packet &pkt) {
		if (pkt.codec == codec_t::POSE) {
			Eigen::Matrix4d p = Eigen::Map<Eigen::Matrix4d>((double*)pkt.data.data());
			host_->setPose(p);
		} else if (pkt.codec == codec_t::CALIBRATION) {
			ftl::rgbd::Camera *camera = (ftl::rgbd::Camera*)pkt.data.data();
            LOG(INFO) << "Have calibration: " << camera->fx;
			params_ = *camera;
			has_calibration_ = true;
		} else {
			cache_[cache_write_].emplace_back();
			auto &c = cache_[cache_write_].back();

			// TODO: Attempt to avoid this copy operation
			c.spkt = spkt;
			c.pkt = pkt;
		}
    });
}

FileSource::~FileSource() {

}

bool FileSource::capture(int64_t ts) {
    timestamp_ = ts;
    return true;
}

bool FileSource::retrieve() {
	if (!reader_->read(timestamp_)) {
		cache_write_ = -1;
	}
void FileSource::swap() {
	cache_read_ = cache_write_;
	cache_write_ = (cache_write_ == 0) ? 1 : 0;
}

bool FileSource::compute(int n, int b) {
	if (cache_read_ < 0) return false;

	for (auto i=cache_[cache_read_].begin(); i!=cache_[cache_read_].end(); ++i) {
		auto &c = *i;

		if (c.spkt.channel == 0) {
			rgb_.create(cv::Size(ftl::codecs::getWidth(c.pkt.definition),ftl::codecs::getHeight(c.pkt.definition)), CV_8UC3);
		} else {
			depth_.create(cv::Size(ftl::codecs::getWidth(c.pkt.definition),ftl::codecs::getHeight(c.pkt.definition)), CV_32F);
		}
	
		_createDecoder(c.spkt.channel, c.pkt);

		try {
			decoders_[c.spkt.channel]->decode(c.pkt, (c.spkt.channel == 0) ? rgb_ : depth_);
		} catch (std::exception &e) {
			LOG(INFO) << "Decoder exception: " << e.what();
		}
	}

	cache_[cache_read_].clear();

	if (rgb_.empty() || depth_.empty()) return false;

	auto cb = host_->callback();
	if (cb) cb(timestamp_, rgb_, depth_);
    return true;
}

bool FileSource::isReady() {
    return true;
}