MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / buildThread

Method buildThread

pj_scene2D/core/src/entry_thumbnail_cache.cpp:70–119  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

68}
69
70void EntryThumbnailCache::buildThread(Timestamp start_ns, Timestamp end_ns) {
71 // Own decoder + own extractor (the build runs concurrently with playback).
72 StreamingVideoDecoder decoder;
73 decoder.attach(store_, topic_, extractor_);
74
75 auto range = store_->timeRange(topic_);
76 const Timestamp lo = (end_ns >= start_ns) ? start_ns : range.first;
77 const Timestamp hi = (end_ns >= start_ns) ? end_ns : range.second;
78 const int64_t span = std::max<int64_t>(1, hi - lo);
79 // ~1 thumbnail per second, but never more than max_tiles over the whole span
80 // (a long clip just gets a coarser interval instead of more tiles).
81 const int64_t interval =
82 std::max<int64_t>(kOneSecondNs, span / static_cast<int64_t>(std::max<std::size_t>(1, cfg_.max_tiles)));
83
84 // Single forward decode pass; the decoder surfaces ~1 frame per interval in
85 // ascending PTS order. We encode each and stop at the tile / byte budget.
86 bool resolution_checked = false;
87 decoder.decodeSampled(interval, [&](const DecodedFrame& f) -> bool {
88 if (!running_.load()) {
89 return false;
90 }
91 if (!resolution_checked) {
92 resolution_checked = true;
93 // Resolution gate: if the source is already <= our cap, the downscale is a
94 // no-op and on-scrub decode is cheap, so a thumbnail track buys nothing.
95 if (f.width <= cfg_.max_width) {
96 return false;
97 }
98 }
99 JpegThumbnail thumb = encodeThumbnailJpeg(f, cfg_.max_width, cfg_.quality);
100 if (thumb.jpeg.empty()) {
101 return true;
102 }
103 std::lock_guard<std::mutex> lock(mutex_);
104 if (bytes_ + thumb.jpeg.size() > cfg_.max_bytes) {
105 return false; // hard ceiling
106 }
107 bytes_ += thumb.jpeg.size();
108 tiles_.push_back({f.pts, std::move(thumb.jpeg), thumb.width, thumb.height});
109 return tiles_.size() < cfg_.max_tiles;
110 });
111
112 // decodeSampled emits ascending PTS, but sort defensively for lookup()'s
113 // binary search (drain order is not guaranteed).
114 {
115 std::lock_guard<std::mutex> lock(mutex_);
116 std::sort(tiles_.begin(), tiles_.end(), [](const Tile& a, const Tile& b) { return a.ts < b.ts; });
117 }
118 running_.store(false);
119}
120
121} // namespace PJ

Callers

nothing calls this directly

Calls 10

encodeThumbnailJpegFunction · 0.85
decodeSampledMethod · 0.80
storeMethod · 0.80
attachMethod · 0.45
timeRangeMethod · 0.45
loadMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected