diff --git a/components/codecs/src/opencv_decoder.cpp b/components/codecs/src/opencv_decoder.cpp index f4b3c0a202888497bea5c865c61beb7aecc96c0d..b7f1a600ff2887330f9266cf8198b048d1770e73 100644 --- a/components/codecs/src/opencv_decoder.cpp +++ b/components/codecs/src/opencv_decoder.cpp @@ -20,7 +20,7 @@ bool OpenCVDecoder::accepts(const ftl::codecs::Packet &pkt) { } bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) { - int chunk_dim = 1; //std::sqrt(pkt.frame_count); + /*int chunk_dim = 1; //std::sqrt(pkt.frame_count); int chunk_width = out.cols / chunk_dim; int chunk_height = out.rows / chunk_dim; @@ -28,7 +28,7 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out int cx = 0; //(pkt.block_number % chunk_dim) * chunk_width; int cy = 0; //(pkt.block_number / chunk_dim) * chunk_height; cv::Rect roi(cx,cy,chunk_width,chunk_height); - cv::cuda::GpuMat chunkHead = out(roi); + cv::cuda::GpuMat chunkHead = out(roi);*/ cv::Mat tmp2_, tmp_; // Decode in temporary buffers to prevent long locks @@ -47,22 +47,22 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out // 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) { + //if (tmp_.cols == chunkHead.cols) { + if (!tmp_.empty() && tmp_.type() == CV_16U) { tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f); - chunkHead.upload(tmp_); - } else if (!tmp_.empty() && tmp_.type() == CV_8UC4 && chunkHead.type() == CV_8UC4) { + out.upload(tmp_); + } else if (!tmp_.empty() && tmp_.type() == CV_8UC4) { //tmp_.copyTo(chunkHead); - chunkHead.upload(tmp_); - } else if (!tmp_.empty() && tmp_.type() == CV_16U && chunkHead.type() == CV_16U) { - chunkHead.upload(tmp_); - } else if (!tmp_.empty() && tmp_.type() == CV_8UC1 && chunkHead.type() == CV_8UC1) { - chunkHead.upload(tmp_); + out.upload(tmp_); + } else if (!tmp_.empty() && tmp_.type() == CV_16U) { + out.upload(tmp_); + } else if (!tmp_.empty() && tmp_.type() == CV_8UC1) { + out.upload(tmp_); } else { // Silent ignore? } // Downsized so needs a scale up - } else { + /*} 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); @@ -73,7 +73,7 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out } else { // Silent ignore? } - } + }*/ return true; } diff --git a/components/streams/src/filestream.cpp b/components/streams/src/filestream.cpp index 0044d014233690dc683e6f5ca18ab7def86895b9..96159a54475f4863a011bb360a2903ed01977c0b 100644 --- a/components/streams/src/filestream.cpp +++ b/components/streams/src/filestream.cpp @@ -94,7 +94,10 @@ bool File::_checkFile() { is_video_ = count < 9; LOG(INFO) << " -- Frame rate = " << (1000 / min_ts_diff); - if (!is_video_) LOG(INFO) << " -- Static image"; + if (!is_video_) { + LOG(INFO) << " -- Static image"; + set("looping", false); + } std::string codec_str = ""; for (auto c : codecs_found) { @@ -327,6 +330,8 @@ bool File::tick(int64_t ts) { spkt.flags = 0; spkt.channel = Channel::EndFrame; + //LOG(INFO) << "Send EndFrame: " << spkt.timestamp << ", " << int(spkt.streamID); + Packet pkt; pkt.bitrate = 255; pkt.codec = ftl::codecs::codec_t::Invalid; @@ -355,8 +360,8 @@ bool File::tick(int64_t ts) { } } - int64_t max_ts = 0; - for (auto &fsd : framesets_) max_ts = std::max(max_ts, (fsd.second.timestamp == 0) ? timestart_ : fsd.second.timestamp); + int64_t max_ts = std::numeric_limits<int64_t>::min(); + for (auto &fsd : framesets_) max_ts = std::max(max_ts, (fsd.second.timestamp <= 0) ? timestart_ : fsd.second.timestamp); int64_t extended_ts = max_ts + 200; // Buffer 200ms ahead while ((active_ && istream_->good()) || buffer_in_.nonparsed_size() > 0u) { @@ -373,7 +378,7 @@ bool File::tick(int64_t ts) { auto &fsdata = framesets_[std::get<0>(data).streamID]; - if (fsdata.first_ts < 0) LOG(WARNING) << "Bad first timestamp"; + if (fsdata.first_ts < 0) LOG(WARNING) << "Bad first timestamp " << fsdata.first_ts << ", " << std::get<0>(data).timestamp; // Adjust timestamp // FIXME: A potential bug where multiple times are merged into one? @@ -386,7 +391,7 @@ bool File::tick(int64_t ts) { // This should only occur for first few frames, generally otherwise // the data buffer is already several frames ahead so is processed // above. Hence, no need to bother parallelising this bit. - /*if (std::get<0>(data).timestamp <= timestamp_) { + /*if (!is_video_ && std::get<0>(data).timestamp <= timestamp_) { std::get<0>(data).timestamp = ts; //if (cb_) { dlk.lock(); @@ -413,6 +418,44 @@ bool File::tick(int64_t ts) { // for (auto &fsd : framesets_) fsd.second.timestamp += interval_; //} + // Force send end frames for static files + if (data_.size() == 0 && !is_video_) { + for (auto &fsix : framesets_) { + auto &fsdata = fsix.second; + if (fsdata.needs_endframe) { + fsdata.needs_endframe = false; + // Send final frame packet. + StreamPacket spkt; + spkt.timestamp = fsdata.timestamp; + spkt.streamID = fsix.first; + spkt.flags = 0; + spkt.channel = Channel::EndFrame; + + //LOG(INFO) << "Send EndFrame: " << spkt.timestamp << ", " << int(spkt.streamID); + + Packet pkt; + pkt.bitrate = 255; + pkt.codec = ftl::codecs::codec_t::Invalid; + pkt.packet_count = 1; + pkt.frame_count = 1; + + for (size_t i=0; i<fsdata.frame_count; ++i) { + spkt.frame_number = i; + pkt.packet_count = fsdata.packet_counts[i]+1; + fsdata.packet_counts[i] = 0; + + try { + cb_.trigger(spkt, pkt); + } catch (const ftl::exception &e) { + LOG(ERROR) << "Exception in packet callback: " << e.what() << e.trace(); + } catch (std::exception &e) { + LOG(ERROR) << "Exception in packet callback: " << e.what(); + } + } + } + } + } + if (data_.size() == 0 && value("looping", true)) { buffer_in_.reset(); buffer_in_.remove_nonparsed_buffer();