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