FFmpeg
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 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
level
uint8_t level
Definition: svq3.c:206
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
log_cb
static int log_cb(void *arg, enum rist_log_level log_level, const char *msg)
Definition: librist.c:83
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34
AV_LOG_QUIET
#define AV_LOG_QUIET
Print no output.
Definition: log.h:176
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:676
profile
mfxU16 profile
Definition: qsvenc.c:45
AVOption
AVOption.
Definition: opt.h:248
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
URLProtocol
Definition: url.h:54
os_support.h
librist_class
static const AVClass librist_class
Definition: librist.c:228
RISTContext::peer_config
struct rist_peer_config peer_config
Definition: librist.c:51
risterr2ret
static int risterr2ret(int err)
Definition: librist.c:73
E
#define E
Definition: librist.c:58
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
s
#define s(width, name)
Definition: cbs_vp9.c:257
RISTContext::packet_size
int packet_size
Definition: librist.c:45
RISTContext::profile
int profile
Definition: librist.c:43
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:675
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
OFFSET
#define OFFSET(x)
Definition: librist.c:59
RISTContext::encryption
int encryption
Definition: librist.c:47
arg
const char * arg
Definition: jacosubdec.c:66
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
librist_read
static int librist_read(URLContext *h, uint8_t *buf, int size)
Definition: librist.c:186
librist_options
static const AVOption librist_options[]
Definition: librist.c:60
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
parseutils.h
time.h
RISTContext::peer
struct rist_peer * peer
Definition: librist.c:53
MAX_PAYLOAD_SIZE
#define MAX_PAYLOAD_SIZE
Definition: librist.c:38
size
int size
Definition: twinvq_data.h:10344
URLProtocol::name
const char * name
Definition: url.h:55
D
#define D
Definition: librist.c:57
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
URLContext
Definition: url.h:38
RISTContext::log_level
int log_level
Definition: librist.c:46
url.h
uint8_t
uint8_t
Definition: audio_convert.c:194
RISTContext
Definition: librist.c:40
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
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
avformat.h
network.h
librist_close
static int librist_close(URLContext *h)
Definition: librist.c:102
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
RISTContext::buffer_size
int buffer_size
Definition: librist.c:44
librist_write
static int librist_write(URLContext *h, const uint8_t *buf, int size)
Definition: librist.c:211
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:674
RISTContext::logging_settings
struct rist_logging_settings logging_settings
Definition: librist.c:50
ff_librist_protocol
const URLProtocol ff_librist_protocol
Definition: librist.c:235
RISTContext::secret
char * secret
Definition: librist.c:48
POLLING_TIME
#define POLLING_TIME
Definition: network.h:249
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_strlcpy
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
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
librist_open
static int librist_open(URLContext *h, const char *uri, int flags)
Definition: librist.c:116
h
h
Definition: vp9dsp_template.c:2038
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
RISTContext::ctx
struct rist_ctx * ctx
Definition: librist.c:54
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234