libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
ancframesync.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <promeki/namespace.h>
14#include <promeki/ancpacket.h>
17#include <promeki/ancformat.h>
18#include <promeki/frame.h>
20#include <promeki/list.h>
21#include <promeki/map.h>
22#include <promeki/result.h>
23#include <promeki/set.h>
24
25PROMEKI_NAMESPACE_BEGIN
26
104class AncFrameSync {
105 public:
107 AncFrameSync() = default;
108
110 explicit AncFrameSync(AncTranslateConfig cfg) : _translator(std::move(cfg)) {}
111
113 const AncTranslateConfig &config() const { return _translator.config(); }
114
116 void setConfig(AncTranslateConfig cfg) { _translator.setConfig(std::move(cfg)); }
117
141 Result<::promeki::List<Frame>> apply(Frame in, FrameSyncDisposition disposition);
142
147 size_t stashedPacketCount() const;
148
149 private:
150 // Walks `frame`'s payload list and dispatches every ANC packet
151 // through AncTranslator::applySyncPolicy with the given
152 // disposition + repeatIndex. Mutates the frame in place via
153 // CoW: detaches the Frame::Data, then detaches each
154 // AncPayload::Ptr via .modify(), then replaces the packet
155 // list with the policy's output. Non-ANC payloads are
156 // untouched, so a downstream observer can verify that
157 // VideoPayload / AudioPayload entries are still aliased
158 // across repeats.
159 Error applyToFrame(Frame &frame, FrameSyncDisposition disposition, uint8_t repeatIndex);
160
161 // Logs a once-per-format warning the first time we see an ANC
162 // packet whose format has no registered SyncPolicy. The
163 // dedupe set is per-instance, matching the spec.
164 void warnFallbackOnce(AncFormat::ID id, const String &name);
165
166 // Walks every ANC packet on the (read-only) input frame and
167 // dispatches each through applySyncPolicy with disposition
168 // = Drop. Any packets the per-format policy returns
169 // (SCTE-104 cues, etc.) are stuffed into the stash.
170 Error applyDropAndStash(const Frame &frame);
171
172 // Latest-wins insert into the stash, keyed on the input
173 // packet's format. When a Drop policy returns multiple
174 // packets they all stash atomically under that format
175 // (next Play emits all of them). A second Drop hitting the
176 // same format replaces the previously-stashed list and
177 // warns once.
178 void stashPackets(AncFormat::ID id, const AncPacket::List &pkts);
179
180 // Appends every stashed packet to @p frame's first AncPayload
181 // (creating an empty AncPayload on the frame if none exists).
182 // Clears the stash on completion. No-op when the stash is
183 // empty.
184 void drainStashInto(Frame &frame);
185
186 AncTranslator _translator;
187 Set<AncFormat::ID> _fallbackWarned;
188 Map<AncFormat::ID, AncPacket::List> _stash;
189};
190
191PROMEKI_NAMESPACE_END
192
193#endif // PROMEKI_ENABLE_PROAV