feat(engine): HDF5-native galleries with embedded calibration; TensorRT backends; scene detection
Gallery format switches from JSON to HDF5 exclusively (JSON read-only kept for back-compat): save_gallery always writes HDF5, and the fitted Platt-sigmoid calibration (a, b, valid, hash) is now embedded directly in the gallery file instead of a sidecar .calib_cache.json — identity_matcher reads it from the loaded gallery and writes back only when the embeddings actually changed (hash mismatch), skipping the O(n^2) refit otherwise. Also includes: TensorRT inference backend support (ort_backend.cpp, trt_backend.cpp), gemm_backend improvements, TransNetV2-based scene-boundary detection wired through frame_source/face_tracker/main, and CMake build target updates for the new sources. Bumps the KPN submodule to feature/persistent-pipeline-reuse (push_blocking backpressure, node_ptr/node_stats introspection, ObjectVariantNodeWrapper for stateful functors) — needed by the optimizer's sae_kpn Python bindings.
This commit is contained in:
+21
-3
@@ -13,6 +13,7 @@ extern "C" {
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@@ -35,7 +36,15 @@ extern "C" {
|
||||
// Non-copyable; wrap in unique_ptr if you need to move it.
|
||||
|
||||
struct FFmpegDecoder {
|
||||
explicit FFmpegDecoder(const std::string& path, bool use_hw = true) {
|
||||
// out_scale in (0,1] downscales decoded frames (applied in the sws_scale
|
||||
// colour conversion, so it's nearly free). 1.0 = native resolution.
|
||||
explicit FFmpegDecoder(const std::string& path, bool use_hw = true,
|
||||
float out_scale = 1.0f)
|
||||
: out_scale_(out_scale > 0.f && out_scale <= 1.f ? out_scale : 1.0f)
|
||||
{
|
||||
// Quiet FFmpeg's own logging (e.g. the harmless "Could not dynamically
|
||||
// load CUDA" emitted while probing hwaccels before VAAPI succeeds).
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
if (avformat_open_input(&fmt_ctx_, path.c_str(), nullptr, nullptr) < 0)
|
||||
throw std::runtime_error("[FFmpegDecoder] cannot open: " + path);
|
||||
if (avformat_find_stream_info(fmt_ctx_, nullptr) < 0)
|
||||
@@ -179,6 +188,7 @@ private:
|
||||
AVPixelFormat hw_pix_fmt_ = AV_PIX_FMT_NONE;
|
||||
int64_t last_pts_ = AV_NOPTS_VALUE;
|
||||
int64_t max_forward_pts_ = AV_NOPTS_VALUE; // set after codec opens
|
||||
float out_scale_ = 1.0f; // decoded-frame downscale (0,1]
|
||||
|
||||
int64_t to_stream_pts(double sec) const {
|
||||
AVStream* s = fmt_ctx_->streams[stream_idx_];
|
||||
@@ -289,13 +299,21 @@ private:
|
||||
const int w = sw->width;
|
||||
const int h = sw->height;
|
||||
|
||||
// Optional downscale, folded into the colour conversion (near-free).
|
||||
// Round to even dimensions for swscale/codec friendliness.
|
||||
int out_w = w, out_h = h;
|
||||
if (out_scale_ < 1.0f) {
|
||||
out_w = std::max(2, (static_cast<int>(w * out_scale_) / 2) * 2);
|
||||
out_h = std::max(2, (static_cast<int>(h * out_scale_) / 2) * 2);
|
||||
}
|
||||
|
||||
sws_ctx_ = sws_getCachedContext(sws_ctx_,
|
||||
w, h, static_cast<AVPixelFormat>(sw->format),
|
||||
w, h, AV_PIX_FMT_BGR24,
|
||||
out_w, out_h, AV_PIX_FMT_BGR24,
|
||||
SWS_BILINEAR, nullptr, nullptr, nullptr);
|
||||
if (!sws_ctx_) return {};
|
||||
|
||||
cv::Mat out(h, w, CV_8UC3);
|
||||
cv::Mat out(out_h, out_w, CV_8UC3);
|
||||
uint8_t* dst_data[1] = { out.data };
|
||||
int dst_linesize[1] = { static_cast<int>(out.step) };
|
||||
sws_scale(sws_ctx_,
|
||||
|
||||
Reference in New Issue
Block a user