libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
mediaiocommand.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 <cassert>
14#include <functional>
15#include <promeki/function.h>
16#include <promeki/namespace.h>
17#include <promeki/error.h>
18#include <promeki/list.h>
19#include <promeki/sharedptr.h>
20#include <promeki/string.h>
21#include <promeki/atomic.h>
22#include <promeki/mutex.h>
24#include <promeki/frame.h>
25#include <promeki/framecount.h>
26#include <promeki/framenumber.h>
27#include <promeki/framerate.h>
28#include <promeki/mediadesc.h>
29#include <promeki/audiodesc.h>
30#include <promeki/metadata.h>
31#include <promeki/mediaconfig.h>
34#include <promeki/clock.h>
35
36PROMEKI_NAMESPACE_BEGIN
37
38class EventLoop;
39class MediaIOPortGroup;
40class MediaIOSink;
41
42// ============================================================================
43// Command hierarchy — all I/O operations are submitted as commands to the
44// MediaIO submit() virtual. Each command carries inputs (set by the public
45// API method that builds it) and outputs (set by the backend's
46// executeCmd()), so all data flow is lock-free.
47// ============================================================================
48
60#define PROMEKI_MEDIAIO_COMMAND(NAME, KIND_TAG) \
61public: \
62 Kind kind() const override { \
63 return KIND_TAG; \
64 } \
65 NAME *_promeki_clone() const { \
66 assert(false && #NAME " should not be cloned"); \
67 return nullptr; \
68 }
69
98class MediaIOCommand {
99 public:
101 enum Kind {
102 Open,
103 Close,
104 Read,
105 Write,
106 Seek,
107 Params,
108 Stats,
109 SetClock
110 };
111
113 using Ptr = SharedPtr<MediaIOCommand, false>;
114
123 RefCount _promeki_refct;
124
131 MediaIOCommand *_promeki_clone() const {
132 assert(false && "MediaIOCommand should never be cloned");
133 return nullptr;
134 }
135
137 MediaIOCommand() = default;
138
140 virtual ~MediaIOCommand() = default;
141
146 virtual Kind kind() const = 0;
147
157 static const char *kindName(Kind k) {
158 switch (k) {
159 case Open: return "Open";
160 case Close: return "Close";
161 case Read: return "Read";
162 case Write: return "Write";
163 case Seek: return "Seek";
164 case Params: return "Params";
165 case Stats: return "Stats";
166 case SetClock: return "SetClock";
167 }
168 return "Unknown";
169 }
170
172 const char *kindName() const { return kindName(kind()); }
173
174 // ---- Cancellation ----
175
189 Atomic<bool> cancelled{false};
190
191 // ---- Strategy hints ----
192
206 bool urgent = false;
207
208 // ---- Output (filled by the framework after dispatch) ----
209
222 Error result = Error::Ok;
223
253 MediaIOStats stats;
254
255 // ---- Completion synchronization ----
256 //
257 // Every command carries its own completion latch + a
258 // wait condition for blocking waiters and a one-shot
259 // continuation callback for asynchronous consumers.
260 // @ref MediaIORequest is a thin facade over these
261 // primitives — it adds no completion state of its own
262 // beyond a shared pointer to this command.
263
280 void markCompleted();
281
299 Error waitForCompletion(unsigned int timeoutMs = 0) const;
300
306 bool isCompleted() const { return _completed.value(); }
307
320 void setCompletionCallback(Function<void(Error)> cb, EventLoop *loop);
321
322 private:
323 Atomic<bool> _completed{false};
324 mutable Mutex _completionMutex;
325 mutable WaitCondition _completionCv;
326 Mutex _callbackMutex;
327 Function<void(Error)> _callback;
328 EventLoop *_callbackLoop = nullptr;
329};
330
335class MediaIOCommandOpen : public MediaIOCommand {
336 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandOpen, Open)
337 public:
338 // ---- Inputs ----
339
341 MediaConfig config;
343 MediaDesc pendingMediaDesc;
345 Metadata pendingMetadata;
347 AudioDesc pendingAudioDesc;
349 List<int> videoTracks;
351 List<int> audioTracks;
352
353 // ---- Outputs ----
354
356 MediaDesc mediaDesc;
358 AudioDesc audioDesc;
360 Metadata metadata;
362 FrameRate frameRate;
364 bool canSeek = false;
366 FrameCount frameCount = FrameCount::unknown();
368 int defaultStep = 1;
370 int defaultPrefetchDepth = 1;
372 int defaultWriteDepth = 4;
374 MediaIOSeekMode defaultSeekMode = MediaIO_SeekExact;
375};
376
384class MediaIOCommandClose : public MediaIOCommand {
385 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandClose, Close)
386};
387
392class MediaIOCommandRead : public MediaIOCommand {
393 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandRead, Read)
394 public:
395 // ---- Inputs ----
406 MediaIOPortGroup *group = nullptr;
420 double rate = 1.0;
421
422 // ---- Outputs ----
423
425 Frame frame;
427 FrameNumber currentFrame;
428
429 // ---- Optional outputs (mid-stream descriptor change) ----
440 bool mediaDescChanged = false;
442 MediaDesc updatedMediaDesc;
443};
444
449class MediaIOCommandWrite : public MediaIOCommand {
450 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandWrite, Write)
451 public:
452 // ---- Inputs ----
462 MediaIOPortGroup *group = nullptr;
463
474 MediaIOSink *sink = nullptr;
476 Frame frame;
477
478 // ---- Outputs ----
479
481 FrameNumber currentFrame;
483 FrameCount frameCount;
484};
485
490class MediaIOCommandSeek : public MediaIOCommand {
491 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandSeek, Seek)
492 public:
493 // ---- Inputs ----
502 MediaIOPortGroup *group = nullptr;
504 FrameNumber frameNumber;
513 MediaIOSeekMode mode = MediaIO_SeekDefault;
514
515 // ---- Output ----
516
518 FrameNumber currentFrame;
519};
520
536class MediaIOCommandParams : public MediaIOCommand {
537 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandParams, Params)
538 public:
539 // ---- Inputs ----
540 String name;
541 MediaIOParams params;
542
543 // ---- Output ----
544 MediaIOParams output;
545};
546
564class MediaIOCommandStats : public MediaIOCommand {
565 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandStats, Stats)
566};
567
589class MediaIOCommandSetClock : public MediaIOCommand {
590 PROMEKI_MEDIAIO_COMMAND(MediaIOCommandSetClock, SetClock)
591 public:
592 // ---- Inputs ----
600 MediaIOPortGroup *group = nullptr;
601
610 Clock::Ptr clock;
611};
612
613PROMEKI_NAMESPACE_END
614
615#endif // PROMEKI_ENABLE_PROAV