FFmpeg  4.4.6
librist.c
Go to the documentation of this file.
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 
24 #include "libavutil/avassert.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/parseutils.h"
27 #include "libavutil/time.h"
28 
29 #include "avformat.h"
30 #include "internal.h"
31 #include "network.h"
32 #include "os_support.h"
33 #include "url.h"
34 
35 #include <librist/librist.h>
36 
37 // RIST_MAX_PACKET_SIZE - 28 minimum protocol overhead
38 #define MAX_PAYLOAD_SIZE (10000-28)
39 
40 typedef struct RISTContext {
41  const AVClass *class;
42 
43  int profile;
46  int log_level;
48  char *secret;
49 
50  struct rist_logging_settings logging_settings;
51  struct rist_peer_config peer_config;
52 
53  struct rist_peer *peer;
54  struct rist_ctx *ctx;
55 } RISTContext;
56 
57 #define D AV_OPT_FLAG_DECODING_PARAM
58 #define E AV_OPT_FLAG_ENCODING_PARAM
59 #define OFFSET(x) offsetof(RISTContext, x)
60 static const AVOption librist_options[] = {
61  { "rist_profile","set profile", OFFSET(profile), AV_OPT_TYPE_INT, {.i64=RIST_PROFILE_MAIN}, 0, 2, .flags = D|E, "profile" },
62  { "simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_SIMPLE}, 0, 0, .flags = D|E, "profile" },
63  { "main", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_MAIN}, 0, 0, .flags = D|E, "profile" },
64  { "advanced", NULL, 0, AV_OPT_TYPE_CONST, {.i64=RIST_PROFILE_ADVANCED}, 0, 0, .flags = D|E, "profile" },
65  { "buffer_size", "set buffer_size in ms", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64=0}, 0, 30000, .flags = D|E },
66  { "pkt_size", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64=1316}, 1, MAX_PAYLOAD_SIZE, .flags = D|E },
67  { "log_level", "set loglevel", OFFSET(log_level), AV_OPT_TYPE_INT, {.i64=RIST_LOG_INFO}, -1, INT_MAX, .flags = D|E },
68  { "secret", "set encryption secret",OFFSET(secret), AV_OPT_TYPE_STRING,{.str=NULL}, 0, 0, .flags = D|E },
69  { "encryption","set encryption type",OFFSET(encryption), AV_OPT_TYPE_INT ,{.i64=0}, 0, INT_MAX, .flags = D|E },
70  { NULL }
71 };
72 
73 static int risterr2ret(int err)
74 {
75  switch (err) {
76  case RIST_ERR_MALLOC:
77  return AVERROR(ENOMEM);
78  default:
79  return AVERROR_EXTERNAL;
80  }
81 }
82 
83 static int log_cb(void *arg, enum rist_log_level log_level, const char *msg)
84 {
85  int level;
86 
87  switch (log_level) {
88  case RIST_LOG_ERROR: level = AV_LOG_ERROR; break;
89  case RIST_LOG_WARN: level = AV_LOG_WARNING; break;
90  case RIST_LOG_NOTICE: level = AV_LOG_INFO; break;
91  case RIST_LOG_INFO: level = AV_LOG_VERBOSE; break;
92  case RIST_LOG_DEBUG: level = AV_LOG_DEBUG; break;
93  case RIST_LOG_DISABLE: level = AV_LOG_QUIET; break;
94  default: level = AV_LOG_WARNING;
95  }
96 
97  av_log(arg, level, "%s", msg);
98 
99  return 0;
100 }
101 
103 {
104  RISTContext *s = h->priv_data;
105  int ret = 0;
106 
107  s->peer = NULL;
108 
109  if (s->ctx)
110  ret = rist_destroy(s->ctx);
111  s->ctx = NULL;
112 
113  return risterr2ret(ret);
114 }
115 
116 static int librist_open(URLContext *h, const char *uri, int flags)
117 {
118  RISTContext *s = h->priv_data;
119  struct rist_logging_settings *logging_settings = &s->logging_settings;
120  struct rist_peer_config *peer_config = &s->peer_config;
121  int ret;
122 
124  return AVERROR(EINVAL);
125 
126  ret = rist_logging_set(&logging_settings, s->log_level, log_cb, h, NULL, NULL);
127  if (ret < 0)
128  return risterr2ret(ret);
129 
130  if (flags & AVIO_FLAG_WRITE) {
131  h->max_packet_size = s->packet_size;
132  ret = rist_sender_create(&s->ctx, s->profile, 0, logging_settings);
133  }
134  if (ret < 0)
135  goto err;
136 
137  if (flags & AVIO_FLAG_READ) {
138  h->max_packet_size = MAX_PAYLOAD_SIZE;
139  ret = rist_receiver_create(&s->ctx, s->profile, logging_settings);
140  }
141  if (ret < 0)
142  goto err;
143 
144  ret = rist_peer_config_defaults_set(peer_config);
145  if (ret < 0)
146  goto err;
147 
148  ret = rist_parse_address(uri, (const struct rist_peer_config **)&peer_config);
149  if (ret < 0)
150  goto err;
151 
152  if (((s->encryption == 128 || s->encryption == 256) && !s->secret) ||
153  ((peer_config->key_size == 128 || peer_config->key_size == 256) && !peer_config->secret[0])) {
154  av_log(h, AV_LOG_ERROR, "secret is mandatory if encryption is enabled\n");
155  librist_close(h);
156  return AVERROR(EINVAL);
157  }
158 
159  if (s->secret && peer_config->secret[0] == 0)
160  av_strlcpy(peer_config->secret, s->secret, RIST_MAX_STRING_SHORT);
161 
162  if (s->secret && (s->encryption == 128 || s->encryption == 256))
163  peer_config->key_size = s->encryption;
164 
165  if (s->buffer_size) {
166  peer_config->recovery_length_min = s->buffer_size;
167  peer_config->recovery_length_max = s->buffer_size;
168  }
169 
170  ret = rist_peer_create(s->ctx, &s->peer, &s->peer_config);
171  if (ret < 0)
172  goto err;
173 
174  ret = rist_start(s->ctx);
175  if (ret < 0)
176  goto err;
177 
178  return 0;
179 
180 err:
181  librist_close(h);
182 
183  return risterr2ret(ret);
184 }
185 
186 static int librist_read(URLContext *h, uint8_t *buf, int size)
187 {
188  RISTContext *s = h->priv_data;
189  const struct rist_data_block *data_block;
190  int ret;
191 
192  ret = rist_receiver_data_read(s->ctx, &data_block, POLLING_TIME);
193  if (ret < 0)
194  return risterr2ret(ret);
195 
196  if (ret == 0)
197  return AVERROR(EAGAIN);
198 
199  if (data_block->payload_len > MAX_PAYLOAD_SIZE) {
200  rist_receiver_data_block_free((struct rist_data_block**)&data_block);
201  return AVERROR_EXTERNAL;
202  }
203 
204  size = data_block->payload_len;
205  memcpy(buf, data_block->payload, size);
206  rist_receiver_data_block_free((struct rist_data_block**)&data_block);
207 
208  return size;
209 }
210 
211 static int librist_write(URLContext *h, const uint8_t *buf, int size)
212 {
213  RISTContext *s = h->priv_data;
214  struct rist_data_block data_block = { 0 };
215  int ret;
216 
217  data_block.ts_ntp = 0;
218  data_block.payload = buf;
219  data_block.payload_len = size;
220 
221  ret = rist_sender_data_write(s->ctx, &data_block);
222  if (ret < 0)
223  return risterr2ret(ret);
224 
225  return ret;
226 }
227 
228 static const AVClass librist_class = {
229  .class_name = "librist",
230  .item_name = av_default_item_name,
231  .option = librist_options,
232  .version = LIBAVUTIL_VERSION_INT,
233 };
234 
236  .name = "rist",
237  .url_open = librist_open,
238  .url_read = librist_read,
239  .url_write = librist_write,
240  .url_close = librist_close,
241  .priv_data_size = sizeof(RISTContext),
243  .priv_data_class = &librist_class,
244 };
uint8_t
simple assert() macros that are a bit more flexible than ISO C assert().
Main libavformat public API header.
#define AVIO_FLAG_READ
read-only
Definition: avio.h:674
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:675
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:676
#define flags(name, subs,...)
Definition: cbs_av1.c:572
#define s(width, name)
Definition: cbs_vp9.c:257
#define NULL
Definition: coverity.c:32
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_QUIET
Print no output.
Definition: log.h:176
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const char * arg
Definition: jacosubdec.c:66
common internal API header
#define E
Definition: librist.c:58
static int librist_open(URLContext *h, const char *uri, int flags)
Definition: librist.c:116
static const AVOption librist_options[]
Definition: librist.c:60
const URLProtocol ff_librist_protocol
Definition: librist.c:235
#define MAX_PAYLOAD_SIZE
Definition: librist.c:38
static int risterr2ret(int err)
Definition: librist.c:73
static int librist_read(URLContext *h, uint8_t *buf, int size)
Definition: librist.c:186
static int librist_write(URLContext *h, const uint8_t *buf, int size)
Definition: librist.c:211
static const AVClass librist_class
Definition: librist.c:228
#define OFFSET(x)
Definition: librist.c:59
static int log_cb(void *arg, enum rist_log_level log_level, const char *msg)
Definition: librist.c:83
#define D
Definition: librist.c:57
static int librist_close(URLContext *h)
Definition: librist.c:102
#define POLLING_TIME
Definition: network.h:249
AVOptions.
miscellaneous OS support macros and functions.
misc parsing utilities
mfxU16 profile
Definition: qsvenc.c:45
Describe the class of an AVClass context structure.
Definition: log.h:67
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
AVOption.
Definition: opt.h:248
int profile
Definition: librist.c:43
int encryption
Definition: librist.c:47
int log_level
Definition: librist.c:46
char * secret
Definition: librist.c:48
struct rist_peer_config peer_config
Definition: librist.c:51
struct rist_peer * peer
Definition: librist.c:53
struct rist_logging_settings logging_settings
Definition: librist.c:50
int buffer_size
Definition: librist.c:44
int packet_size
Definition: librist.c:45
struct rist_ctx * ctx
Definition: librist.c:54
Definition: url.h:38
const char * name
Definition: url.h:55
uint8_t level
Definition: svq3.c:206
#define av_log(a,...)
int size
unbuffered private I/O API
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34