1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /**
20 * @file
21 * Reliable Internet Streaming Transport protocol
22 */
23
29
35
36 #include <librist/librist.h>
37 #include <librist/version.h>
38
39 // RIST_MAX_PACKET_SIZE - 28 minimum protocol overhead
40 #define MAX_PAYLOAD_SIZE (10000-28)
41
42 #define FF_LIBRIST_MAKE_VERSION(major, minor, patch) \
43 ((patch) + ((minor)* 0x100) + ((major) *0x10000))
44 #define FF_LIBRIST_VERSION FF_LIBRIST_MAKE_VERSION(LIBRIST_API_VERSION_MAJOR, LIBRIST_API_VERSION_MINOR, LIBRIST_API_VERSION_PATCH)
45 #define FF_LIBRIST_VERSION_41 FF_LIBRIST_MAKE_VERSION(4, 1, 0)
46
49
56
59
63
64 #define D AV_OPT_FLAG_DECODING_PARAM
65 #define E AV_OPT_FLAG_ENCODING_PARAM
66 #define OFFSET(x) offsetof(RISTContext, x)
72 {
"buffer_size",
"set buffer_size in ms",
OFFSET(buffer_size),
AV_OPT_TYPE_INT, {.i64=0}, 0, 30000, .flags =
D|
E },
74 {
"log_level",
"set loglevel",
OFFSET(log_level),
AV_OPT_TYPE_INT, {.i64=RIST_LOG_INFO}, -1, INT_MAX, .flags =
D|
E },
78 };
79
81 {
82 switch (err) {
83 case RIST_ERR_MALLOC:
85 default:
87 }
88 }
89
90 static int log_cb(
void *
arg,
enum rist_log_level log_level,
const char *msg)
91 {
93
94 switch (log_level) {
102 }
103
105
106 return 0;
107 }
108
110 {
113
115
117 ret = rist_destroy(
s->ctx);
119
121 }
122
124 {
126 struct rist_logging_settings *logging_settings = &
s->logging_settings;
127 struct rist_peer_config *peer_config = &
s->peer_config;
129
132
133 s->logging_settings = (
struct rist_logging_settings)LOGGING_SETTINGS_INITIALIZER;
137
139 h->max_packet_size =
s->packet_size;
140 ret = rist_sender_create(&
s->ctx,
s->profile, 0, logging_settings);
141 }
143 goto err;
144
147 ret = rist_receiver_create(&
s->ctx,
s->profile, logging_settings);
148 }
150 goto err;
151
152 ret = rist_peer_config_defaults_set(peer_config);
154 goto err;
155
156 #if FF_LIBRIST_VERSION < FF_LIBRIST_VERSION_41
157 ret = rist_parse_address(uri, (
const struct rist_peer_config **)&peer_config);
158 #else
159 ret = rist_parse_address2(uri, &peer_config);
160 #endif
162 goto err;
163
164 if (((
s->encryption == 128 ||
s->encryption == 256) && !
s->secret) ||
165 ((peer_config->key_size == 128 || peer_config->key_size == 256) && !peer_config->secret[0])) {
169 }
170
171 if (
s->secret && peer_config->secret[0] == 0)
172 av_strlcpy(peer_config->secret,
s->secret, RIST_MAX_STRING_SHORT);
173
174 if (
s->secret && (
s->encryption == 128 ||
s->encryption == 256))
175 peer_config->key_size =
s->encryption;
176
177 if (
s->buffer_size) {
178 peer_config->recovery_length_min =
s->buffer_size;
179 peer_config->recovery_length_max =
s->buffer_size;
180 }
181
182 ret = rist_peer_create(
s->ctx, &
s->peer, &
s->peer_config);
184 goto err;
185
186 ret = rist_start(
s->ctx);
188 goto err;
189
190 return 0;
191
192 err:
194
196 }
197
199 {
202
203 #if FF_LIBRIST_VERSION < FF_LIBRIST_VERSION_41
204 const struct rist_data_block *data_block;
206 #else
207 struct rist_data_block *data_block;
209 #endif
210
213
216
218 #if FF_LIBRIST_VERSION < FF_LIBRIST_VERSION_41
219 rist_receiver_data_block_free((struct rist_data_block**)&data_block);
220 #else
221 rist_receiver_data_block_free2(&data_block);
222 #endif
224 }
225
226 size = data_block->payload_len;
227 memcpy(buf, data_block->payload,
size);
228 #if FF_LIBRIST_VERSION < FF_LIBRIST_VERSION_41
229 rist_receiver_data_block_free((struct rist_data_block**)&data_block);
230 #else
231 rist_receiver_data_block_free2(&data_block);
232 #endif
234 }
235
237 {
239 struct rist_data_block data_block = { 0 };
241
242 data_block.ts_ntp = 0;
243 data_block.payload = buf;
244 data_block.payload_len =
size;
245
246 ret = rist_sender_data_write(
s->ctx, &data_block);
249
251 }
252
258 };
259
269 };