Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
Derek Buitenhuis authored on 2016/03/04 02:14:26... | ... |
@@ -15,6 +15,9 @@ libavutil: 2015-08-28 |
15 | 15 |
|
16 | 16 |
API changes, most recent first: |
17 | 17 |
|
18 |
+2016-XX-XX - xxxxxxx - lavf 57.28.100 |
|
19 |
+ Add protocol blacklisting API |
|
20 |
+ |
|
18 | 21 |
2016-02-28 - xxxxxxx - lavc 57.27.101 |
19 | 22 |
Validate AVFrame returned by get_buffer2 to have required |
20 | 23 |
planes not NULL and unused planes set to NULL as crashes |
... | ... |
@@ -251,7 +251,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** |
251 | 251 |
|
252 | 252 |
/* wrap interrupt callback */ |
253 | 253 |
c->interrupt_callback = h->interrupt_callback; |
254 |
- ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist); |
|
254 |
+ ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist, h->protocol_blacklist); |
|
255 | 255 |
if (ret != 0) { |
256 | 256 |
av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg); |
257 | 257 |
goto url_fail; |
... | ... |
@@ -1832,11 +1832,11 @@ typedef struct AVFormatContext { |
1832 | 1832 |
#endif |
1833 | 1833 |
|
1834 | 1834 |
/** |
1835 |
- * ',' separated list of allowed protocols. |
|
1835 |
+ * ',' separated list of disallowed protocols. |
|
1836 | 1836 |
* - encoding: unused |
1837 | 1837 |
* - decoding: set by user through AVOptions (NO direct access) |
1838 | 1838 |
*/ |
1839 |
- char *protocol_whitelist; |
|
1839 |
+ char *protocol_blacklist; |
|
1840 | 1840 |
|
1841 | 1841 |
/* |
1842 | 1842 |
* A callback for opening new IO streams. |
... | ... |
@@ -1865,6 +1865,13 @@ typedef struct AVFormatContext { |
1865 | 1865 |
* A callback for closing the streams opened with AVFormatContext.io_open(). |
1866 | 1866 |
*/ |
1867 | 1867 |
void (*io_close)(struct AVFormatContext *s, AVIOContext *pb); |
1868 |
+ |
|
1869 |
+ /** |
|
1870 |
+ * ',' separated list of disallowed protocols. |
|
1871 |
+ * - encoding: unused |
|
1872 |
+ * - decoding: set by user through AVOptions (NO direct access) |
|
1873 |
+ */ |
|
1874 |
+ char *protocol_blacklist; |
|
1868 | 1875 |
} AVFormatContext; |
1869 | 1876 |
|
1870 | 1877 |
int av_format_get_probe_score(const AVFormatContext *s); |
... | ... |
@@ -1089,7 +1089,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) |
1089 | 1089 |
|
1090 | 1090 |
ast->sub_ctx->pb = pb; |
1091 | 1091 |
|
1092 |
- if (ff_copy_whitelists(ast->sub_ctx, s) < 0) |
|
1092 |
+ if (ff_copy_whiteblacklists(ast->sub_ctx, s) < 0) |
|
1093 | 1093 |
goto error; |
1094 | 1094 |
|
1095 | 1095 |
if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { |
... | ... |
@@ -55,6 +55,7 @@ static void *urlcontext_child_next(void *obj, void *prev) |
55 | 55 |
#define D AV_OPT_FLAG_DECODING_PARAM |
56 | 56 |
static const AVOption options[] = { |
57 | 57 |
{"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
58 |
+ {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
|
58 | 59 |
{ NULL } |
59 | 60 |
}; |
60 | 61 |
|
... | ... |
@@ -173,12 +174,19 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) |
173 | 173 |
// Check that URLContext was initialized correctly and lists are matching if set |
174 | 174 |
av_assert0(!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || |
175 | 175 |
(uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value))); |
176 |
+ av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) || |
|
177 |
+ (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value))); |
|
176 | 178 |
|
177 | 179 |
if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) { |
178 | 180 |
av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist \'%s\'!\n", uc->protocol_whitelist); |
179 | 181 |
return AVERROR(EINVAL); |
180 | 182 |
} |
181 | 183 |
|
184 |
+ if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) { |
|
185 |
+ av_log(uc, AV_LOG_ERROR, "Protocol blacklisted \'%s\'!\n", uc->protocol_blacklist); |
|
186 |
+ return AVERROR(EINVAL); |
|
187 |
+ } |
|
188 |
+ |
|
182 | 189 |
if (!uc->protocol_whitelist && uc->prot->default_whitelist) { |
183 | 190 |
av_log(uc, AV_LOG_DEBUG, "Setting default whitelist '%s'\n", uc->prot->default_whitelist); |
184 | 191 |
uc->protocol_whitelist = av_strdup(uc->prot->default_whitelist); |
... | ... |
@@ -190,6 +198,8 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) |
190 | 190 |
|
191 | 191 |
if ((err = av_dict_set(options, "protocol_whitelist", uc->protocol_whitelist, 0)) < 0) |
192 | 192 |
return err; |
193 |
+ if ((err = av_dict_set(options, "protocol_blacklist", uc->protocol_blacklist, 0)) < 0) |
|
194 |
+ return err; |
|
193 | 195 |
|
194 | 196 |
err = |
195 | 197 |
uc->prot->url_open2 ? uc->prot->url_open2(uc, |
... | ... |
@@ -199,6 +209,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) |
199 | 199 |
uc->prot->url_open(uc, uc->filename, uc->flags); |
200 | 200 |
|
201 | 201 |
av_dict_set(options, "protocol_whitelist", NULL, 0); |
202 |
+ av_dict_set(options, "protocol_blacklist", NULL, 0); |
|
202 | 203 |
|
203 | 204 |
if (err) |
204 | 205 |
return err; |
... | ... |
@@ -290,7 +301,8 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, |
290 | 290 |
} |
291 | 291 |
|
292 | 292 |
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, |
293 |
- const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist) |
|
293 |
+ const AVIOInterruptCB *int_cb, AVDictionary **options, |
|
294 |
+ const char *whitelist, const char* blacklist) |
|
294 | 295 |
{ |
295 | 296 |
AVDictionary *tmp_opts = NULL; |
296 | 297 |
AVDictionaryEntry *e; |
... | ... |
@@ -307,10 +319,16 @@ int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, |
307 | 307 |
av_assert0(!whitelist || |
308 | 308 |
!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || |
309 | 309 |
!strcmp(whitelist, e->value)); |
310 |
+ av_assert0(!blacklist || |
|
311 |
+ !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) || |
|
312 |
+ !strcmp(blacklist, e->value)); |
|
310 | 313 |
|
311 | 314 |
if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0) |
312 | 315 |
goto fail; |
313 | 316 |
|
317 |
+ if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0) |
|
318 |
+ goto fail; |
|
319 |
+ |
|
314 | 320 |
if ((ret = av_opt_set_dict(*puc, options)) < 0) |
315 | 321 |
goto fail; |
316 | 322 |
|
... | ... |
@@ -328,7 +346,7 @@ int ffurl_open(URLContext **puc, const char *filename, int flags, |
328 | 328 |
const AVIOInterruptCB *int_cb, AVDictionary **options) |
329 | 329 |
{ |
330 | 330 |
return ffurl_open_whitelist(puc, filename, flags, |
331 |
- int_cb, options, NULL); |
|
331 |
+ int_cb, options, NULL, NULL); |
|
332 | 332 |
} |
333 | 333 |
|
334 | 334 |
static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, |
... | ... |
@@ -254,6 +254,11 @@ typedef struct AVIOContext { |
254 | 254 |
* ',' separated list of allowed protocols. |
255 | 255 |
*/ |
256 | 256 |
const char *protocol_whitelist; |
257 |
+ |
|
258 |
+ /** |
|
259 |
+ * ',' separated list of disallowed protocols. |
|
260 |
+ */ |
|
261 |
+ const char *protocol_blacklist; |
|
257 | 262 |
} AVIOContext; |
258 | 263 |
|
259 | 264 |
/* unbuffered I/O */ |
... | ... |
@@ -155,7 +155,7 @@ int ffio_open_null_buf(AVIOContext **s); |
155 | 155 |
|
156 | 156 |
int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, |
157 | 157 |
const AVIOInterruptCB *int_cb, AVDictionary **options, |
158 |
- const char *whitelist); |
|
158 |
+ const char *whitelist, const char *blacklist); |
|
159 | 159 |
|
160 | 160 |
/** |
161 | 161 |
* Close a null buffer. |
... | ... |
@@ -848,6 +848,11 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) |
848 | 848 |
avio_closep(s); |
849 | 849 |
goto fail; |
850 | 850 |
} |
851 |
+ (*s)->protocol_blacklist = av_strdup(h->protocol_blacklist); |
|
852 |
+ if (!(*s)->protocol_blacklist && h->protocol_blacklist) { |
|
853 |
+ avio_closep(s); |
|
854 |
+ goto fail; |
|
855 |
+ } |
|
851 | 856 |
(*s)->direct = h->flags & AVIO_FLAG_DIRECT; |
852 | 857 |
|
853 | 858 |
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL; |
... | ... |
@@ -974,13 +979,13 @@ int avio_open(AVIOContext **s, const char *filename, int flags) |
974 | 974 |
|
975 | 975 |
int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, |
976 | 976 |
const AVIOInterruptCB *int_cb, AVDictionary **options, |
977 |
- const char *whitelist |
|
977 |
+ const char *whitelist, const char *blacklist |
|
978 | 978 |
) |
979 | 979 |
{ |
980 | 980 |
URLContext *h; |
981 | 981 |
int err; |
982 | 982 |
|
983 |
- err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist); |
|
983 |
+ err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist); |
|
984 | 984 |
if (err < 0) |
985 | 985 |
return err; |
986 | 986 |
err = ffio_fdopen(s, h); |
... | ... |
@@ -994,13 +999,13 @@ int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, |
994 | 994 |
int avio_open2(AVIOContext **s, const char *filename, int flags, |
995 | 995 |
const AVIOInterruptCB *int_cb, AVDictionary **options) |
996 | 996 |
{ |
997 |
- return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL); |
|
997 |
+ return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL); |
|
998 | 998 |
} |
999 | 999 |
|
1000 | 1000 |
int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, |
1001 | 1001 |
const AVIOInterruptCB *int_cb, AVDictionary **options) |
1002 | 1002 |
{ |
1003 |
- return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist); |
|
1003 |
+ return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist, s->protocol_blacklist); |
|
1004 | 1004 |
} |
1005 | 1005 |
|
1006 | 1006 |
int avio_close(AVIOContext *s) |
... | ... |
@@ -87,7 +87,7 @@ static int cache_open(URLContext *h, const char *arg, int flags, AVDictionary ** |
87 | 87 |
av_freep(&buffername); |
88 | 88 |
|
89 | 89 |
return ffurl_open_whitelist(&c->inner, arg, flags, &h->interrupt_callback, |
90 |
- options, h->protocol_whitelist); |
|
90 |
+ options, h->protocol_whitelist, h->protocol_blacklist); |
|
91 | 91 |
} |
92 | 92 |
|
93 | 93 |
static int add_entry(URLContext *h, const unsigned char *buf, int size) |
... | ... |
@@ -98,7 +98,7 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) |
98 | 98 |
|
99 | 99 |
/* creating URLContext */ |
100 | 100 |
err = ffurl_open_whitelist(&uc, node_uri, flags, |
101 |
- &h->interrupt_callback, NULL, h->protocol_whitelist); |
|
101 |
+ &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist); |
|
102 | 102 |
if (err < 0) |
103 | 103 |
break; |
104 | 104 |
|
... | ... |
@@ -301,7 +301,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) |
301 | 301 |
|
302 | 302 |
cat->avf->interrupt_callback = avf->interrupt_callback; |
303 | 303 |
|
304 |
- if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0) |
|
304 |
+ if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0) |
|
305 | 305 |
return ret; |
306 | 306 |
|
307 | 307 |
if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 || |
... | ... |
@@ -138,7 +138,7 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary |
138 | 138 |
|
139 | 139 |
if ((ret = ffurl_open_whitelist(&c->hd, nested_url, flags, |
140 | 140 |
&h->interrupt_callback, options, |
141 |
- h->protocol_whitelist)) < 0) { |
|
141 |
+ h->protocol_whitelist, h->protocol_blacklist)) < 0) { |
|
142 | 142 |
av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", nested_url); |
143 | 143 |
goto err; |
144 | 144 |
} |
... | ... |
@@ -539,7 +539,7 @@ static int ftp_connect_control_connection(URLContext *h) |
539 | 539 |
} /* if option is not given, don't pass it and let tcp use its own default */ |
540 | 540 |
err = ffurl_open_whitelist(&s->conn_control, buf, AVIO_FLAG_READ_WRITE, |
541 | 541 |
&h->interrupt_callback, &opts, |
542 |
- h->protocol_whitelist); |
|
542 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
543 | 543 |
av_dict_free(&opts); |
544 | 544 |
if (err < 0) { |
545 | 545 |
av_log(h, AV_LOG_ERROR, "Cannot open control connection\n"); |
... | ... |
@@ -593,7 +593,7 @@ static int ftp_connect_data_connection(URLContext *h) |
593 | 593 |
} /* if option is not given, don't pass it and let tcp use its own default */ |
594 | 594 |
err = ffurl_open_whitelist(&s->conn_data, buf, h->flags, |
595 | 595 |
&h->interrupt_callback, &opts, |
596 |
- h->protocol_whitelist); |
|
596 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
597 | 597 |
av_dict_free(&opts); |
598 | 598 |
if (err < 0) |
599 | 599 |
return err; |
... | ... |
@@ -94,7 +94,7 @@ static int gopher_open(URLContext *h, const char *uri, int flags) |
94 | 94 |
|
95 | 95 |
s->hd = NULL; |
96 | 96 |
err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, |
97 |
- &h->interrupt_callback, NULL, h->protocol_whitelist); |
|
97 |
+ &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist); |
|
98 | 98 |
if (err < 0) |
99 | 99 |
goto fail; |
100 | 100 |
|
... | ... |
@@ -1619,7 +1619,7 @@ static int hls_read_header(AVFormatContext *s) |
1619 | 1619 |
pls->ctx->io_open = nested_io_open; |
1620 | 1620 |
pls->stream_offset = stream_offset; |
1621 | 1621 |
|
1622 |
- if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0) |
|
1622 |
+ if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) |
|
1623 | 1623 |
goto fail; |
1624 | 1624 |
|
1625 | 1625 |
ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL); |
... | ... |
@@ -119,7 +119,7 @@ static int parse_playlist(URLContext *h, const char *url) |
119 | 119 |
|
120 | 120 |
if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, |
121 | 121 |
&h->interrupt_callback, NULL, |
122 |
- h->protocol_whitelist)) < 0) |
|
122 |
+ h->protocol_whitelist, h->protocol_blacklist)) < 0) |
|
123 | 123 |
return ret; |
124 | 124 |
|
125 | 125 |
read_chomp_line(in, line, sizeof(line)); |
... | ... |
@@ -307,7 +307,7 @@ retry: |
307 | 307 |
av_log(h, AV_LOG_DEBUG, "opening %s\n", url); |
308 | 308 |
ret = ffurl_open_whitelist(&s->seg_hd, url, AVIO_FLAG_READ, |
309 | 309 |
&h->interrupt_callback, NULL, |
310 |
- h->protocol_whitelist); |
|
310 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
311 | 311 |
if (ret < 0) { |
312 | 312 |
if (ff_check_interrupt(&h->interrupt_callback)) |
313 | 313 |
return AVERROR_EXIT; |
... | ... |
@@ -221,7 +221,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) |
221 | 221 |
if (!s->hd) { |
222 | 222 |
err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, |
223 | 223 |
&h->interrupt_callback, options, |
224 |
- h->protocol_whitelist); |
|
224 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
225 | 225 |
if (err < 0) |
226 | 226 |
return err; |
227 | 227 |
} |
... | ... |
@@ -456,7 +456,7 @@ static int http_listen(URLContext *h, const char *uri, int flags, |
456 | 456 |
goto fail; |
457 | 457 |
if ((ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, |
458 | 458 |
&h->interrupt_callback, options, |
459 |
- h->protocol_whitelist |
|
459 |
+ h->protocol_whitelist, h->protocol_blacklist |
|
460 | 460 |
)) < 0) |
461 | 461 |
goto fail; |
462 | 462 |
s->handshake_step = LOWER_PROTO; |
... | ... |
@@ -1582,7 +1582,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) |
1582 | 1582 |
redo: |
1583 | 1583 |
ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, |
1584 | 1584 |
&h->interrupt_callback, NULL, |
1585 |
- h->protocol_whitelist); |
|
1585 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
1586 | 1586 |
if (ret < 0) |
1587 | 1587 |
return ret; |
1588 | 1588 |
|
... | ... |
@@ -165,7 +165,7 @@ static int icecast_open(URLContext *h, const char *uri, int flags) |
165 | 165 |
ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path); |
166 | 166 |
// Finally open http proto handler |
167 | 167 |
ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, |
168 |
- &opt_dict, h->protocol_whitelist); |
|
168 |
+ &opt_dict, h->protocol_whitelist, h->protocol_blacklist); |
|
169 | 169 |
|
170 | 170 |
cleanup: |
171 | 171 |
av_freep(&user); |
... | ... |
@@ -532,7 +532,7 @@ enum AVWriteUncodedFrameFlags { |
532 | 532 |
/** |
533 | 533 |
* Copies the whilelists from one context to the other |
534 | 534 |
*/ |
535 |
-int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src); |
|
535 |
+int ff_copy_whiteblacklists(AVFormatContext *dst, AVFormatContext *src); |
|
536 | 536 |
|
537 | 537 |
int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, |
538 | 538 |
const AVIOInterruptCB *int_cb, AVDictionary **options); |
... | ... |
@@ -71,7 +71,7 @@ static int md5_close(URLContext *h) |
71 | 71 |
if (*filename) { |
72 | 72 |
err = ffurl_open_whitelist(&out, filename, AVIO_FLAG_WRITE, |
73 | 73 |
&h->interrupt_callback, NULL, |
74 |
- h->protocol_whitelist); |
|
74 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
75 | 75 |
if (err) |
76 | 76 |
return err; |
77 | 77 |
err = ffurl_write(out, buf, i*2+1); |
... | ... |
@@ -530,7 +530,7 @@ static int mms_open(URLContext *h, const char *uri, int flags) |
530 | 530 |
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); |
531 | 531 |
err = ffurl_open_whitelist(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, |
532 | 532 |
&h->interrupt_callback, NULL, |
533 |
- h->protocol_whitelist); |
|
533 |
+ h->protocol_whitelist, h->protocol_blacklist); |
|
534 | 534 |
if (err) |
535 | 535 |
goto fail; |
536 | 536 |
|
... | ... |
@@ -732,7 +732,7 @@ static int vobsub_read_header(AVFormatContext *s) |
732 | 732 |
goto end; |
733 | 733 |
} |
734 | 734 |
|
735 |
- if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0) |
|
735 |
+ if ((ret = ff_copy_whiteblacklists(vobsub->sub_ctx, s)) < 0) |
|
736 | 736 |
goto end; |
737 | 737 |
|
738 | 738 |
ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL); |
... | ... |
@@ -109,7 +109,7 @@ FF_DISABLE_DEPRECATION_WARNINGS |
109 | 109 |
FF_ENABLE_DEPRECATION_WARNINGS |
110 | 110 |
#endif |
111 | 111 |
|
112 |
- return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist); |
|
112 |
+ return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist); |
|
113 | 113 |
} |
114 | 114 |
|
115 | 115 |
static void io_close_default(AVFormatContext *s, AVIOContext *pb) |
... | ... |
@@ -101,6 +101,7 @@ static const AVOption avformat_options[] = { |
101 | 101 |
{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
102 | 102 |
{"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
103 | 103 |
{"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
104 |
+{"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, |
|
104 | 105 |
{NULL}, |
105 | 106 |
}; |
106 | 107 |
|
... | ... |
@@ -531,7 +531,7 @@ static av_cold int rdt_init(AVFormatContext *s, int st_index, PayloadContext *rd |
531 | 531 |
if (!rdt->rmctx) |
532 | 532 |
return AVERROR(ENOMEM); |
533 | 533 |
|
534 |
- if ((ret = ff_copy_whitelists(rdt->rmctx, s)) < 0) |
|
534 |
+ if ((ret = ff_copy_whiteblacklists(rdt->rmctx, s)) < 0) |
|
535 | 535 |
return ret; |
536 | 536 |
|
537 | 537 |
return avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL); |
... | ... |
@@ -266,7 +266,7 @@ static int rtmpe_open(URLContext *h, const char *uri, int flags) |
266 | 266 |
/* open the tcp or ffrtmphttp connection */ |
267 | 267 |
if ((ret = ffurl_open_whitelist(&rt->stream, url, AVIO_FLAG_READ_WRITE, |
268 | 268 |
&h->interrupt_callback, NULL, |
269 |
- h->protocol_whitelist)) < 0) { |
|
269 |
+ h->protocol_whitelist, h->protocol_blacklist)) < 0) { |
|
270 | 270 |
rtmpe_close(h); |
271 | 271 |
return ret; |
272 | 272 |
} |
... | ... |
@@ -1120,7 +1120,7 @@ static int rtmp_calc_swfhash(URLContext *s) |
1120 | 1120 |
/* Get the SWF player file. */ |
1121 | 1121 |
if ((ret = ffurl_open_whitelist(&stream, rt->swfverify, AVIO_FLAG_READ, |
1122 | 1122 |
&s->interrupt_callback, NULL, |
1123 |
- s->protocol_whitelist)) < 0) { |
|
1123 |
+ s->protocol_whitelist, s->protocol_blacklist)) < 0) { |
|
1124 | 1124 |
av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify); |
1125 | 1125 |
goto fail; |
1126 | 1126 |
} |
... | ... |
@@ -2650,7 +2650,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) |
2650 | 2650 |
reconnect: |
2651 | 2651 |
if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE, |
2652 | 2652 |
&s->interrupt_callback, &opts, |
2653 |
- s->protocol_whitelist)) < 0) { |
|
2653 |
+ s->protocol_whitelist, s->protocol_blacklist)) < 0) { |
|
2654 | 2654 |
av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); |
2655 | 2655 |
goto fail; |
2656 | 2656 |
} |
... | ... |
@@ -131,7 +131,7 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) |
131 | 131 |
rt->asf_ctx->pb = &pb; |
132 | 132 |
av_dict_set(&opts, "no_resync_search", "1", 0); |
133 | 133 |
|
134 |
- if ((ret = ff_copy_whitelists(rt->asf_ctx, s)) < 0) { |
|
134 |
+ if ((ret = ff_copy_whiteblacklists(rt->asf_ctx, s)) < 0) { |
|
135 | 135 |
av_dict_free(&opts); |
136 | 136 |
return ret; |
137 | 137 |
} |
... | ... |
@@ -381,7 +381,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) |
381 | 381 |
hostname, rtp_port, s->local_rtpport, |
382 | 382 |
sources, block); |
383 | 383 |
if (ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, |
384 |
- NULL, h->protocol_whitelist) < 0) |
|
384 |
+ NULL, h->protocol_whitelist, h->protocol_blacklist) < 0) |
|
385 | 385 |
goto fail; |
386 | 386 |
s->local_rtpport = ff_udp_get_local_port(s->rtp_hd); |
387 | 387 |
if(s->local_rtpport == 65535) { |
... | ... |
@@ -395,7 +395,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) |
395 | 395 |
sources, block); |
396 | 396 |
if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, |
397 | 397 |
&h->interrupt_callback, NULL, |
398 |
- h->protocol_whitelist) < 0) { |
|
398 |
+ h->protocol_whitelist, h->protocol_blacklist) < 0) { |
|
399 | 399 |
s->local_rtpport = s->local_rtcpport = -1; |
400 | 400 |
continue; |
401 | 401 |
} |
... | ... |
@@ -405,7 +405,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) |
405 | 405 |
hostname, s->rtcp_port, s->local_rtcpport, |
406 | 406 |
sources, block); |
407 | 407 |
if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, &h->interrupt_callback, |
408 |
- NULL, h->protocol_whitelist) < 0) |
|
408 |
+ NULL, h->protocol_whitelist, h->protocol_blacklist) < 0) |
|
409 | 409 |
goto fail; |
410 | 410 |
break; |
411 | 411 |
} |
... | ... |
@@ -1469,7 +1469,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, |
1469 | 1469 |
/* we will use two ports per rtp stream (rtp and rtcp) */ |
1470 | 1470 |
j += 2; |
1471 | 1471 |
err = ffurl_open_whitelist(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE, |
1472 |
- &s->interrupt_callback, &opts, s->protocol_whitelist); |
|
1472 |
+ &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); |
|
1473 | 1473 |
|
1474 | 1474 |
av_dict_free(&opts); |
1475 | 1475 |
|
... | ... |
@@ -1612,7 +1612,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, |
1612 | 1612 |
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, |
1613 | 1613 |
port, "%s", optbuf); |
1614 | 1614 |
if (ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, |
1615 |
- &s->interrupt_callback, NULL, s->protocol_whitelist) < 0) { |
|
1615 |
+ &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist) < 0) { |
|
1616 | 1616 |
err = AVERROR_INVALIDDATA; |
1617 | 1617 |
goto fail; |
1618 | 1618 |
} |
... | ... |
@@ -1801,7 +1801,7 @@ redirect: |
1801 | 1801 |
host, port, |
1802 | 1802 |
"?timeout=%d", rt->stimeout); |
1803 | 1803 |
if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, |
1804 |
- &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { |
|
1804 |
+ &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist)) < 0) { |
|
1805 | 1805 |
err = ret; |
1806 | 1806 |
goto fail; |
1807 | 1807 |
} |
... | ... |
@@ -2317,7 +2317,7 @@ static int sdp_read_header(AVFormatContext *s) |
2317 | 2317 |
rtsp_st->nb_exclude_source_addrs, |
2318 | 2318 |
rtsp_st->exclude_source_addrs); |
2319 | 2319 |
err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, |
2320 |
- &s->interrupt_callback, &opts, s->protocol_whitelist); |
|
2320 |
+ &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); |
|
2321 | 2321 |
|
2322 | 2322 |
av_dict_free(&opts); |
2323 | 2323 |
|
... | ... |
@@ -2387,7 +2387,7 @@ static int rtp_read_header(AVFormatContext *s) |
2387 | 2387 |
return AVERROR(EIO); |
2388 | 2388 |
|
2389 | 2389 |
ret = ffurl_open_whitelist(&in, s->filename, AVIO_FLAG_READ, |
2390 |
- &s->interrupt_callback, NULL, s->protocol_whitelist); |
|
2390 |
+ &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist); |
|
2391 | 2391 |
if (ret) |
2392 | 2392 |
goto fail; |
2393 | 2393 |
|
... | ... |
@@ -296,7 +296,7 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) |
296 | 296 |
av_log(s, AV_LOG_TRACE, "Opening: %s", url); |
297 | 297 |
ret = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, |
298 | 298 |
&s->interrupt_callback, &opts, |
299 |
- s->protocol_whitelist); |
|
299 |
+ s->protocol_whitelist, s->protocol_blacklist); |
|
300 | 300 |
av_dict_free(&opts); |
301 | 301 |
if (ret) |
302 | 302 |
localport += 2; |
... | ... |
@@ -665,7 +665,7 @@ static int rtsp_listen(AVFormatContext *s) |
665 | 665 |
|
666 | 666 |
if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, |
667 | 667 |
&s->interrupt_callback, NULL, |
668 |
- s->protocol_whitelist)) { |
|
668 |
+ s->protocol_whitelist, s->protocol_blacklist)) { |
|
669 | 669 |
av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n"); |
670 | 670 |
return ret; |
671 | 671 |
} |
... | ... |
@@ -87,7 +87,7 @@ static int sap_read_header(AVFormatContext *s) |
87 | 87 |
port); |
88 | 88 |
ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_READ, |
89 | 89 |
&s->interrupt_callback, NULL, |
90 |
- s->protocol_whitelist); |
|
90 |
+ s->protocol_whitelist, s->protocol_blacklist); |
|
91 | 91 |
if (ret) |
92 | 92 |
goto fail; |
93 | 93 |
|
... | ... |
@@ -161,7 +161,7 @@ static int sap_read_header(AVFormatContext *s) |
161 | 161 |
sap->sdp_ctx->pb = &sap->sdp_pb; |
162 | 162 |
sap->sdp_ctx->interrupt_callback = s->interrupt_callback; |
163 | 163 |
|
164 |
- if ((ret = ff_copy_whitelists(sap->sdp_ctx, s)) < 0) |
|
164 |
+ if ((ret = ff_copy_whiteblacklists(sap->sdp_ctx, s)) < 0) |
|
165 | 165 |
goto fail; |
166 | 166 |
|
167 | 167 |
ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL); |
... | ... |
@@ -151,7 +151,7 @@ static int sap_write_header(AVFormatContext *s) |
151 | 151 |
base_port += 2; |
152 | 152 |
ret = ffurl_open_whitelist(&fd, url, AVIO_FLAG_WRITE, |
153 | 153 |
&s->interrupt_callback, NULL, |
154 |
- s->protocol_whitelist); |
|
154 |
+ s->protocol_whitelist, s->protocol_blacklist); |
|
155 | 155 |
if (ret) { |
156 | 156 |
ret = AVERROR(EIO); |
157 | 157 |
goto fail; |
... | ... |
@@ -171,7 +171,7 @@ static int sap_write_header(AVFormatContext *s) |
171 | 171 |
"?ttl=%d&connect=1", ttl); |
172 | 172 |
ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_WRITE, |
173 | 173 |
&s->interrupt_callback, NULL, |
174 |
- s->protocol_whitelist); |
|
174 |
+ s->protocol_whitelist, s->protocol_blacklist); |
|
175 | 175 |
if (ret) { |
176 | 176 |
ret = AVERROR(EIO); |
177 | 177 |
goto fail; |
... | ... |
@@ -123,7 +123,7 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) |
123 | 123 |
os->tail_out = os->out; |
124 | 124 |
av_dict_set(&opts, "truncate", "0", 0); |
125 | 125 |
ret = ffurl_open_whitelist(&os->out, frag->file, AVIO_FLAG_WRITE, |
126 |
- &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); |
|
126 |
+ &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist, os->ctx->protocol_blacklist); |
|
127 | 127 |
av_dict_free(&opts); |
128 | 128 |
if (ret < 0) { |
129 | 129 |
os->out = os->tail_out; |
... | ... |
@@ -132,7 +132,7 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) |
132 | 132 |
} |
133 | 133 |
av_dict_set(&opts, "truncate", "0", 0); |
134 | 134 |
ffurl_open_whitelist(&os->out2, frag->infofile, AVIO_FLAG_WRITE, |
135 |
- &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); |
|
135 |
+ &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist, os->ctx->protocol_blacklist); |
|
136 | 136 |
av_dict_free(&opts); |
137 | 137 |
ffurl_seek(os->out, offset - frag->start_pos, SEEK_SET); |
138 | 138 |
if (os->out2) |
... | ... |
@@ -332,7 +332,7 @@ static int ism_write_header(AVFormatContext *s) |
332 | 332 |
} |
333 | 333 |
|
334 | 334 |
ctx = avformat_alloc_context(); |
335 |
- if (!ctx || ff_copy_whitelists(ctx, s) < 0) { |
|
335 |
+ if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) { |
|
336 | 336 |
ret = AVERROR(ENOMEM); |
337 | 337 |
goto fail; |
338 | 338 |
} |
... | ... |
@@ -526,7 +526,7 @@ static int ism_flush(AVFormatContext *s, int final) |
526 | 526 |
continue; |
527 | 527 |
|
528 | 528 |
snprintf(filename, sizeof(filename), "%s/temp", os->dirname); |
529 |
- ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); |
|
529 |
+ ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist); |
|
530 | 530 |
if (ret < 0) |
531 | 531 |
break; |
532 | 532 |
os->cur_start_pos = os->tail_pos; |
... | ... |
@@ -81,7 +81,7 @@ static int srtp_open(URLContext *h, const char *uri, int flags) |
81 | 81 |
path, sizeof(path), uri); |
82 | 82 |
ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path); |
83 | 83 |
if ((ret = ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, |
84 |
- NULL, h->protocol_whitelist)) < 0) |
|
84 |
+ NULL, h->protocol_whitelist, h->protocol_blacklist)) < 0) |
|
85 | 85 |
goto fail; |
86 | 86 |
|
87 | 87 |
h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size, |
... | ... |
@@ -78,7 +78,7 @@ static int subfile_open(URLContext *h, const char *filename, int flags, |
78 | 78 |
} |
79 | 79 |
av_strstart(filename, "subfile:", &filename); |
80 | 80 |
ret = ffurl_open_whitelist(&c->h, filename, flags, &h->interrupt_callback, |
81 |
- options, h->protocol_whitelist); |
|
81 |
+ options, h->protocol_whitelist, h->protocol_blacklist); |
|
82 | 82 |
if (ret < 0) |
83 | 83 |
return ret; |
84 | 84 |
c->pos = c->start; |
... | ... |
@@ -106,5 +106,5 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV |
106 | 106 |
|
107 | 107 |
return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, |
108 | 108 |
&parent->interrupt_callback, options, |
109 |
- parent->protocol_whitelist); |
|
109 |
+ parent->protocol_whitelist, parent->protocol_blacklist); |
|
110 | 110 |
} |
... | ... |
@@ -83,7 +83,7 @@ static int import_pem(URLContext *h, char *path, CFArrayRef *array) |
83 | 83 |
|
84 | 84 |
if ((ret = ffio_open_whitelist(&s, path, AVIO_FLAG_READ, |
85 | 85 |
&h->interrupt_callback, NULL, |
86 |
- h->protocol_whitelist)) < 0) |
|
86 |
+ h->protocol_whitelist, h->protocol_blacklist)) < 0) |
|
87 | 87 |
goto end; |
88 | 88 |
|
89 | 89 |
if ((ret = avio_size(s)) < 0) |
... | ... |
@@ -47,6 +47,7 @@ typedef struct URLContext { |
47 | 47 |
AVIOInterruptCB interrupt_callback; |
48 | 48 |
int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */ |
49 | 49 |
const char *protocol_whitelist; |
50 |
+ const char *protocol_blacklist; |
|
50 | 51 |
} URLContext; |
51 | 52 |
|
52 | 53 |
typedef struct URLProtocol { |
... | ... |
@@ -140,7 +141,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options); |
140 | 140 |
*/ |
141 | 141 |
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, |
142 | 142 |
const AVIOInterruptCB *int_cb, AVDictionary **options, |
143 |
- const char *whitelist); |
|
143 |
+ const char *whitelist, const char* blacklist); |
|
144 | 144 |
|
145 | 145 |
int ffurl_open(URLContext **puc, const char *filename, int flags, |
146 | 146 |
const AVIOInterruptCB *int_cb, AVDictionary **options); |
... | ... |
@@ -142,18 +142,21 @@ void av_format_inject_global_side_data(AVFormatContext *s) |
142 | 142 |
} |
143 | 143 |
} |
144 | 144 |
|
145 |
-int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src) |
|
145 |
+int ff_copy_whiteblacklists(AVFormatContext *dst, AVFormatContext *src) |
|
146 | 146 |
{ |
147 | 147 |
av_assert0(!dst->codec_whitelist && |
148 | 148 |
!dst->format_whitelist && |
149 |
- !dst->protocol_whitelist); |
|
149 |
+ !dst->protocol_whitelist && |
|
150 |
+ !dst->protocol_blacklist); |
|
150 | 151 |
dst-> codec_whitelist = av_strdup(src->codec_whitelist); |
151 | 152 |
dst->format_whitelist = av_strdup(src->format_whitelist); |
152 | 153 |
dst->protocol_whitelist = av_strdup(src->protocol_whitelist); |
154 |
+ dst->protocol_blacklist = av_strdup(src->protocol_blacklist); |
|
153 | 155 |
if ( (src-> codec_whitelist && !dst-> codec_whitelist) |
154 | 156 |
|| (src-> format_whitelist && !dst-> format_whitelist) |
155 |
- || (src->protocol_whitelist && !dst->protocol_whitelist)) { |
|
156 |
- av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n"); |
|
157 |
+ || (src->protocol_whitelist && !dst->protocol_whitelist) |
|
158 |
+ || (src->protocol_blacklist && !dst->protocol_blacklist)) { |
|
159 |
+ av_log(dst, AV_LOG_ERROR, "Failed to duplicate black/whitelist\n"); |
|
157 | 160 |
return AVERROR(ENOMEM); |
158 | 161 |
} |
159 | 162 |
return 0; |
... | ... |
@@ -460,6 +463,14 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, |
460 | 460 |
} |
461 | 461 |
} |
462 | 462 |
|
463 |
+ if (!s->protocol_blacklist && s->pb && s->pb->protocol_blacklist) { |
|
464 |
+ s->protocol_blacklist = av_strdup(s->pb->protocol_blacklist); |
|
465 |
+ if (!s->protocol_blacklist) { |
|
466 |
+ ret = AVERROR(ENOMEM); |
|
467 |
+ goto fail; |
|
468 |
+ } |
|
469 |
+ } |
|
470 |
+ |
|
463 | 471 |
if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) { |
464 | 472 |
av_log(s, AV_LOG_ERROR, "Format not on whitelist \'%s\'\n", s->format_whitelist); |
465 | 473 |
ret = AVERROR(EINVAL); |
... | ... |
@@ -30,8 +30,8 @@ |
30 | 30 |
#include "libavutil/version.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 57 |
33 |
-#define LIBAVFORMAT_VERSION_MINOR 27 |
|
34 |
-#define LIBAVFORMAT_VERSION_MICRO 102 |
|
33 |
+#define LIBAVFORMAT_VERSION_MINOR 28 |
|
34 |
+#define LIBAVFORMAT_VERSION_MICRO 100 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFORMAT_VERSION_MINOR, \ |