Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* @file streams.hpp
* @copyright Copyright (c) 2022 University of Turku, MIT License
* @author Nicolas Pope
*/
#pragma once
#include <ftl/handle.hpp>
#include <ftl/threads.hpp>
#include <ftl/protocol/channels.hpp>
#include <ftl/protocol/channelSet.hpp>
#include <ftl/protocol/packet.hpp>
#include <string>
#include <vector>
#include <unordered_set>
namespace ftl {
namespace protocol {
/* Represents a request for data through a stream */
struct Request {
uint32_t frameset;
uint32_t frame;
ftl::protocol::Channel channel;
int bitrate;
int count;
ftl::protocol::Codec codec;
};
using RequestCallback = std::function<bool(const ftl::protocol::Request&)>;
using StreamCallback = std::function<bool(const ftl::protocol::StreamPacket &, const ftl::protocol::Packet &)>;
enum struct StreamOption {
kInvalid = 0,
kLooping,
kSpeed,
kBitrate,
kAdaptiveBitrate
};
enum struct StreamType {
kMixed,
kUnknown,
kLive,
kRecorded
};
/**
* Base stream class to be implemented. Provides encode and decode functionality
* around a generic packet read and write mechanism. Some specialisations will
* provide and automatically handle control signals.
*
* Streams are bidirectional, frames can be both received and written.
*/
class Stream {
public:
virtual ~Stream() {};
/**
* Obtain all packets for next frame. The provided callback function is
* called once for every packet. This function might continue to call the
* callback even after the read function returns, for example with a
* NetStream.
*/
ftl::Handle onPacket(const StreamCallback &cb) { return cb_.on(cb); };
virtual bool post(const ftl::protocol::StreamPacket &, const ftl::protocol::Packet &)=0;
// TODO: Add methods for: pause, paused, statistics, stream type, options
/**
* Start the stream. Calls to the onPacket callback will only occur after
* a call to this function (and before a call to end()).
*/
virtual bool begin()=0;
virtual bool end()=0;
/**
* Is the stream active? Generally true if begin() has been called, false
* initially and after end(). However, it may go false for other reasons.
* If false, no calls to onPacket will occur and posts will be ignored.
*/
virtual bool active()=0;
/**
* Perform a forced reset of the stream. This means something different
* depending on stream type, for example with a network stream it involves
* resending all stream requests as if a reconnection had occured.
*/
virtual void reset();
/**
* Query available video channels for a frameset.
*/
const ftl::protocol::ChannelSet &available(int fs) const;
/**
* Query selected channels for a frameset. Channels not selected may not
* be transmitted, received or decoded.
*/
ftl::protocol::ChannelSet selected(int fs) const;
ftl::protocol::ChannelSet selectedNoExcept(int fs) const;
/**
* Change the video channel selection for a frameset.
*/
void select(int fs, const ftl::protocol::ChannelSet &, bool make=false);
/**
* Number of framesets in stream.
*/
inline size_t size() const { return state_.size(); }
virtual bool enable(uint8_t fs, uint8_t f) { return true; }
protected:
ftl::Handler<const ftl::protocol::StreamPacket&, const ftl::protocol::Packet&> cb_;
/**
* Allow modification of available channels. Calling this with an invalid
* fs number will create that frameset and increase the size.
*/
ftl::protocol::ChannelSet &available(int fs);
private:
struct FSState {
ftl::protocol::ChannelSet selected;
ftl::protocol::ChannelSet available;
};
std::vector<FSState> state_;
mutable SHARED_MUTEX mtx_;
};
}
}