#include <ftl/codecs/opencv_decoder.hpp> #include <loguru.hpp> using ftl::codecs::OpenCVDecoder; using ftl::codecs::codec_t; OpenCVDecoder::OpenCVDecoder() { } OpenCVDecoder::~OpenCVDecoder() { } bool OpenCVDecoder::accepts(const ftl::codecs::Packet &pkt) { return (pkt.codec == codec_t::JPG || pkt.codec == codec_t::PNG); } bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) { //CHECK(cv::Size(ftl::codecs::getWidth(pkt.definition), ftl::codecs::getHeight(pkt.definition)) == out.size()); int chunk_dim = std::sqrt(pkt.block_total); int chunk_width = out.cols / chunk_dim; int chunk_height = out.rows / chunk_dim; // Build chunk head int cx = (pkt.block_number % chunk_dim) * chunk_width; int cy = (pkt.block_number / chunk_dim) * chunk_height; cv::Rect roi(cx,cy,chunk_width,chunk_height); cv::cuda::GpuMat chunkHead = out(roi); //LOG(INFO) << "DECODE JPEG " << (int)pkt.block_number << "/" << chunk_dim; cv::Mat tmp2_, tmp_; // Decode in temporary buffers to prevent long locks cv::imdecode(pkt.data, cv::IMREAD_UNCHANGED, &tmp2_); if (tmp2_.type() == CV_8UC3) { cv::cvtColor(tmp2_, tmp_, cv::COLOR_BGR2BGRA); } else { tmp_ = tmp2_; } // Apply colour correction to chunk //ftl::rgbd::colourCorrection(tmp_rgb, gamma_, temperature_); // TODO:(Nick) Decode directly into double buffer if no scaling // Can either check JPG/PNG headers or just use pkt definition. // Original size so just copy if (tmp_.cols == chunkHead.cols) { if (!tmp_.empty() && tmp_.type() == CV_16U && chunkHead.type() == CV_32F) { tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f); chunkHead.upload(tmp_); } else if (!tmp_.empty() && tmp_.type() == CV_8UC4 && chunkHead.type() == CV_8UC4) { //tmp_.copyTo(chunkHead); chunkHead.upload(tmp_); } else { // Silent ignore? } // Downsized so needs a scale up } else { if (!tmp_.empty() && tmp_.type() == CV_16U && chunkHead.type() == CV_32F) { tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f); //(16.0f*10.0f)); cv::resize(tmp_, tmp_, chunkHead.size(), 0, 0, cv::INTER_NEAREST); chunkHead.upload(tmp_); } else if (!tmp_.empty() && tmp_.type() == CV_8UC4 && chunkHead.type() == CV_8UC4) { cv::resize(tmp_, tmp_, chunkHead.size()); chunkHead.upload(tmp_); } else { // Silent ignore? } } return true; }