VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
mcap_reader.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file mcap_reader.h
26 * @brief Concrete BagReader implementation for the MCAP bag file format.
27 *
28 * @details
29 * @c McapReader reads bag files in the MCAP format (@c .vcap / @c .vcapx extension) and inherits all
30 * playback, seeking, and integrity-check capabilities from @c BagReader.
31 *
32 * MCAP (Message Capture Archive Protocol) is a modular, indexed binary format designed
33 * for efficient random-access playback. It supports channel-level schemas, checksums,
34 * and multiple compression codecs.
35 *
36 * @par Usage
37 * @code
38 * auto reader = vlink::BagReader::create("/data/recording.vcap");
39 * // or explicitly:
40 * auto reader = std::make_shared<vlink::McapReader>("/data/recording.vcap");
41 * reader->register_output_callback([](int64_t ts, const std::string& url,
42 * vlink::ActionType action, const vlink::Bytes& data) {
43 * // process message
44 * });
45 * reader->async_run();
46 * reader->play({});
47 * @endcode
48 *
49 * @see BagReader, DatabaseReader
50 */
51
52#pragma once
53
54#include <future>
55#include <memory>
56#include <string>
57#include <vector>
58
59#include "./bag_reader.h"
60
61namespace vlink {
62
63/**
64 * @class McapReader
65 * @brief Concrete MCAP-format bag file player.
66 *
67 * @details
68 * All virtual methods from @c BagReader are implemented. Prefer using
69 * @c BagReader::create() for format-agnostic construction.
70 */
71class VLINK_EXPORT McapReader final : public BagReader {
72 public:
73 /**
74 * @brief Constructs an @c McapReader for the given @p path.
75 *
76 * @param path Path to the @c .vcap / @c .vcapx file.
77 * @param read_only Open in read-only mode.
78 * @param try_to_fix Attempt repair if the file is corrupt.
79 */
80 explicit McapReader(const std::string& path, bool read_only = true, bool try_to_fix = false);
81
82 /**
83 * @brief Destructor -- stops playback and releases the MCAP file handle.
84 */
85 ~McapReader() override;
86
87 /**
88 * @brief Attaches a @c BagReaderPluginInterface for custom URL/type conversion.
89 *
90 * @param plugin_interface Plugin to bind. May be @c nullptr to detach.
91 */
92 void bind_plugin_interface(const std::shared_ptr<BagReaderPluginInterface>& plugin_interface) override;
93
94 /**
95 * @brief Registers a callback fired whenever the playback status changes.
96 *
97 * @param status_callback Callback receiving the new @c Status value.
98 */
99 void register_status_callback(StatusCallback&& status_callback) override;
100
101 /**
102 * @brief Registers a callback fired when the reader is ready to start playing.
103 *
104 * @param ready_callback Callback invoked once the file is open and parsed.
105 */
106 void register_ready_callback(ReadyCallback&& ready_callback) override;
107
108 /**
109 * @brief Registers a callback fired when playback ends or is interrupted.
110 *
111 * @param finish_callback Callback receiving the @c is_interrupted flag.
112 */
113 void register_finish_callback(FinishCallback&& finish_callback) override;
114
115 /**
116 * @brief Registers the callback that receives replayed messages.
117 *
118 * @param output_callback Called for each message during playback.
119 */
120 void register_output_callback(OutputCallback&& output_callback) override;
121
122 /**
123 * @brief Starts playback with the given configuration.
124 *
125 * @param config Playback configuration (rate, times, filters, etc.).
126 */
127 void play(const Config& config) override;
128
129 /**
130 * @brief Stops playback and resets the reader to the beginning.
131 */
132 void stop() override;
133
134 /**
135 * @brief Pauses playback at the current position.
136 */
137 void pause() override;
138
139 /**
140 * @brief Resumes a paused playback from the current position.
141 */
142 void resume() override;
143
144 /**
145 * @brief Advances one message while paused, then pauses again.
146 */
147 void pause_to_next() override;
148
149 /**
150 * @brief Seeks to @p begin_time and resumes playback.
151 *
152 * @param begin_time Seek target timestamp in milliseconds (relative to recording start).
153 * @param rate New playback rate multiplier.
154 * @param times Number of loops after the jump.
155 * @param force_to_play If @c true, forces play state even if currently paused.
156 */
157 void jump(int64_t begin_time, double rate, int times, bool force_to_play = false) override;
158
159 /**
160 * @brief Verifies the integrity of the MCAP file asynchronously.
161 *
162 * @return @c std::future<bool> that resolves to @c true if the file is intact.
163 */
164 std::future<bool> check() override;
165
166 /**
167 * @brief Rebuilds the index tables asynchronously.
168 *
169 * @return @c std::future<bool> that resolves to @c true on success.
170 */
171 std::future<bool> reindex() override;
172
173 /**
174 * @brief Repairs a corrupt MCAP file asynchronously.
175 *
176 * @param rebuild If @c true, rebuilds the entire index from scratch.
177 * @return @c std::future<bool> that resolves to @c true if repair succeeded.
178 */
179 std::future<bool> fix(bool rebuild = false) override;
180
181 /**
182 * @brief Updates the tag name stored in the bag metadata.
183 *
184 * @param tag_name New tag name string.
185 */
186 void tag(const std::string& tag_name) override;
187
188 /**
189 * @brief Returns the current playback position as a recording-relative timestamp.
190 *
191 * @return Current position in milliseconds relative to the recording start.
192 */
193 [[nodiscard]] int64_t get_timestamp() const override;
194
195 /**
196 * @brief Returns the real elapsed wall-clock time since playback started.
197 *
198 * @return Elapsed wall-clock time in milliseconds.
199 */
200 [[nodiscard]] int64_t get_real_timestamp() const override;
201
202 /**
203 * @brief Returns the current playback status.
204 *
205 * @return One of @c kStopped, @c kPaused, or @c kPlaying.
206 */
207 [[nodiscard]] Status get_status() const override;
208
209 /**
210 * @brief Returns the bag file metadata and per-URL statistics.
211 *
212 * @return Const reference to the @c Info struct populated at open time.
213 */
214 [[nodiscard]] const Info& get_info() const override;
215
216 /**
217 * @brief Scans the MCAP file and returns all embedded schemas.
218 *
219 * @return Vector of @c SchemaData descriptors found in the file.
220 */
221 [[nodiscard]] std::vector<SchemaData> detect_schema() override;
222
223 /**
224 * @brief Returns the serialisation type string for a given URL.
225 *
226 * @param url Topic URL to look up.
227 * @return Serialisation type (e.g., @c "demo.proto.PointCloud"), or empty if unknown.
228 */
229 [[nodiscard]] std::string get_ser_type(const std::string& url) const override;
230
231 /**
232 * @brief Returns the coarse schema family for a given URL.
233 *
234 * @param url Topic URL to look up.
235 * @return Schema family, or @c SchemaType::kUnknown if unavailable.
236 */
237 [[nodiscard]] SchemaType get_schema_type(const std::string& url) const override;
238
239 /**
240 * @brief Returns @c true if the bag spans multiple split files.
241 */
242 [[nodiscard]] bool is_split_mode() const override;
243
244 /**
245 * @brief Returns the zero-based index of the current split file being read.
246 */
247 [[nodiscard]] int get_split_index() const override;
248
249 /**
250 * @brief Returns @c true if a jump-to-timestamp seek is currently in progress.
251 */
252 [[nodiscard]] bool is_jumping() const override;
253
254 protected:
255 size_t get_max_task_count() const override;
256
257 void on_begin() override;
258
259 void on_end() override;
260
261 private:
262 void update_status(Status status);
263
264 void do_stop();
265
266 void do_pause();
267
268 void prepare_file(void* file);
269
270 void open(const std::string& path);
271
272 void close();
273
274 int get_reset_index(const Config& config);
275
276 void read(const Config& config);
277
278 std::unique_ptr<struct McapReaderImpl> impl_;
279
281};
282
283} // namespace vlink
Abstract base class for VLink bag file playback with time-based seeking and rate control.
#define VLINK_EXPORT
Definition macros.h:85
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
Definition macros.h:184