Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Loading...
Searching...
No Matches
composer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Roc Streaming authors
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8
9//! @file roc_fec/composer.h
10//! @brief FECFRAME packet composer.
11
12#ifndef ROC_FEC_COMPOSER_H_
13#define ROC_FEC_COMPOSER_H_
14
15#include "roc_core/align_ops.h"
16#include "roc_core/log.h"
18#include "roc_fec/headers.h"
20
21namespace roc {
22namespace fec {
23
24//! FECFRAME packet composer.
25template <class PayloadID, PayloadID_Type Type, PayloadID_Pos Pos>
27public:
28 //! Initialization.
29 //! @remarks
30 //! Composes FECFRAME header or footer and passes the rest to
31 //! @p inner_composer if it's not null.
32 Composer(packet::IComposer* inner_composer)
33 : inner_composer_(inner_composer) {
34 }
35
36 //! Adjust buffer to align payload.
37 virtual bool
38 align(core::Slice<uint8_t>& buffer, size_t header_size, size_t payload_alignment) {
39 if ((unsigned long)buffer.data() % payload_alignment != 0) {
40 roc_panic("fec composer: unexpected non-aligned buffer");
41 }
42
43 if (Pos == Header) {
44 header_size += sizeof(PayloadID);
45 }
46
47 if (inner_composer_ == NULL) {
48 const size_t padding = core::AlignOps::pad_as(header_size, payload_alignment);
49
50 if (buffer.capacity() < padding) {
51 roc_log(
53 "fec composer: not enough space for alignment: padding=%lu cap=%lu",
54 (unsigned long)padding, (unsigned long)buffer.capacity());
55 return false;
56 }
57
58 buffer.reslice(padding, padding);
59 return true;
60 } else {
61 return inner_composer_->align(buffer, header_size, payload_alignment);
62 }
63 }
64
65 //! Prepare buffer for composing a packet.
66 virtual bool
67 prepare(packet::Packet& packet, core::Slice<uint8_t>& buffer, size_t payload_size) {
68 core::Slice<uint8_t> payload_id = buffer.subslice(0, 0);
69
70 if (Pos == Header) {
71 if (payload_id.capacity() < sizeof(PayloadID)) {
73 "fec composer: not enough space for fec header: size=%lu cap=%lu",
74 (unsigned long)sizeof(PayloadID),
75 (unsigned long)payload_id.capacity());
76 return false;
77 }
78 payload_id.reslice(0, sizeof(PayloadID));
79 }
80
81 core::Slice<uint8_t> payload =
82 payload_id.subslice(payload_id.size(), payload_id.size());
83
84 if (inner_composer_) {
85 if (!inner_composer_->prepare(packet, payload, payload_size)) {
86 return false;
87 }
88 } else {
89 payload.reslice(0, payload_size);
90 }
91
92 if (Pos == Footer) {
93 payload_id = payload.subslice(payload.size(), payload.size());
94
95 if (payload_id.capacity() < sizeof(PayloadID)) {
97 "fec composer: not enough space for fec header: size=%lu cap=%lu",
98 (unsigned long)sizeof(PayloadID),
99 (unsigned long)payload_id.capacity());
100 return false;
101 }
102 payload_id.reslice(0, sizeof(PayloadID));
103 }
104
105 if (Type == Repair) {
107 }
108
110
111 packet::FEC& fec = *packet.fec();
112
113 fec.fec_scheme = PayloadID::fec_scheme();
114 fec.payload_id = payload_id;
115 fec.payload = payload;
116
117 buffer.reslice(0, payload_id.size() + payload.size());
118
119 return true;
120 }
121
122 //! Pad packet.
123 virtual bool pad(packet::Packet& packet, size_t padding_size) {
124 if (inner_composer_) {
125 return inner_composer_->pad(packet, padding_size);
126 }
127
128 // padding not supported
129 return false;
130 }
131
132 //! Compose packet to buffer.
133 virtual bool compose(packet::Packet& packet) {
134 if (!packet.fec()) {
135 roc_panic("fec composer: unexpected non-fec packet");
136 }
137
138 if (packet.fec()->payload_id.size() != sizeof(PayloadID)) {
139 roc_panic("fec composer: unexpected payload id size");
140 }
141
142 packet::FEC& fec = *packet.fec();
143
144 PayloadID& payload_id = *(PayloadID*)fec.payload_id.data();
145
146 payload_id.clear();
147
148 roc_panic_if((fec.encoding_symbol_id >> 16) != 0);
149 payload_id.set_esi((uint16_t)fec.encoding_symbol_id);
150
151 payload_id.set_sbn(fec.source_block_number);
152
153 roc_panic_if((fec.source_block_length >> 16) != 0);
154 payload_id.set_k((uint16_t)fec.source_block_length);
155
156 roc_panic_if((fec.block_length >> 16) != 0);
157 payload_id.set_n((uint16_t)fec.block_length);
158
159 if (inner_composer_) {
160 return inner_composer_->compose(packet);
161 }
162
163 return true;
164 }
165
166private:
167 packet::IComposer* inner_composer_;
168};
169
170} // namespace fec
171} // namespace roc
172
173#endif // ROC_FEC_COMPOSER_H_
Alignment operations.
static size_t pad_as(size_t size, size_t alignment)
Return padding needed for given alignment.
Base class for non-copyable objects.
Definition noncopyable.h:23
Shared ownership intrusive pointer.
Definition shared_ptr.h:32
T * data() const
Get slice data.
Definition slice.h:93
size_t size() const
Get number of elements in slice.
Definition slice.h:109
FECFRAME packet composer.
Definition composer.h:26
virtual bool pad(packet::Packet &packet, size_t padding_size)
Pad packet.
Definition composer.h:123
virtual bool compose(packet::Packet &packet)
Compose packet to buffer.
Definition composer.h:133
Composer(packet::IComposer *inner_composer)
Initialization.
Definition composer.h:32
virtual bool prepare(packet::Packet &packet, core::Slice< uint8_t > &buffer, size_t payload_size)
Prepare buffer for composing a packet.
Definition composer.h:67
virtual bool align(core::Slice< uint8_t > &buffer, size_t header_size, size_t payload_alignment)
Adjust buffer to align payload.
Definition composer.h:38
Packet composer interface.
Definition icomposer.h:22
virtual bool align(core::Slice< uint8_t > &buffer, size_t header_size, size_t payload_alignment)=0
Adjust buffer to align payload.
virtual bool pad(Packet &packet, size_t padding_size)=0
Pad packet.
virtual bool prepare(Packet &packet, core::Slice< uint8_t > &buffer, size_t payload_size)=0
Prepare buffer for composing a packet.
virtual bool compose(Packet &packet)=0
Compose packet to buffer.
const FEC * fec() const
FEC packet.
@ FlagRepair
Packet contains repair FEC symbols.
Definition packet.h:51
@ FlagFEC
Packet contains FEC header.
Definition packet.h:48
void add_flags(unsigned flags)
Add flags.
Packet composer interface.
Logging.
#define roc_log(level,...)
Print message to log.
Definition log.h:31
@ Header
PayloadID comes before payload.
Definition headers.h:32
@ Footer
PayloadID comes after payload.
Definition headers.h:33
@ Repair
Source packet header of footer.
Definition headers.h:27
Root namespace.
@ LogDebug
Regular debug message.
Definition log.h:48
Non-copyable object.
#define roc_panic_if(x)
Panic if condition is true.
Definition panic.h:26
#define roc_panic(...)
Print error message and terminate program gracefully.
Definition panic.h:50
FECFRAME headers.
FECFRAME packet.
Definition fec.h:35
core::Slice< uint8_t > payload
FECFRAME payload.
Definition fec.h:74
size_t encoding_symbol_id
The index number of packet in a block ("esi").
Definition fec.h:47
size_t source_block_length
Number of source packets in block to which this packet belongs ("sblen").
Definition fec.h:59
FecScheme fec_scheme
The FEC scheme to which the packet belongs to.
Definition fec.h:39
size_t block_length
Number of source + repair packets in block to which this packet belongs ("blen").
Definition fec.h:66
blknum_t source_block_number
Number of a source block in a packet stream ("sbn").
Definition fec.h:54
core::Slice< uint8_t > payload_id
FECFRAME header or footer.
Definition fec.h:69