API changes, most recent first:
+2016-xx-xx - xxxxxxx - lavf 57.4.0 - avformat.h
+ Add AVFormatContext.protocol_whitelist and protocol_blacklist.
+ Add 'protocol_whitelist' and 'protocol_blacklist' private options for
+ avio_open2().
+
2016-xx-xx - lavc 57.13.0 - avcodec.h
Add AVCodecContext.hw_frames_ctx.
* A callback for closing the streams opened with AVFormatContext.io_open().
*/
void (*io_close)(struct AVFormatContext *s, AVIOContext *pb);
+
+ /**
+ * A comma-separated list of protocol names that will not be used internally
+ * by libavformat. If this field is a non-empty string, then protocols
+ * listed here will be forbidden.
+ *
+ * This field should be set using AVOptions.
+ */
+ char *protocol_blacklist;
+
+ /**
+ * A comma-separated list of protocol names that can be used internally by
+ * libavformat. If this field is a non-empty string, all protocols not
+ * listed here will be forbidden.
+ *
+ * This field should be set using AVOptions.
+ */
+ char *protocol_whitelist;
} AVFormatContext;
typedef struct AVPacketList {
#define SHORT_SEEK_THRESHOLD 4096
typedef struct AVIOInternal {
+ const AVClass *class;
+
+ char *protocol_whitelist;
+ char *protocol_blacklist;
+
URLContext *h;
const URLProtocol **protocols;
} AVIOInternal;
+static void *io_priv_child_next(void *obj, void *prev)
+{
+ AVIOInternal *internal = obj;
+ return prev ? NULL : internal->h;
+}
+
+static const AVClass *io_priv_child_class_next(const AVClass *prev)
+{
+ return prev ? NULL : &ffurl_context_class;
+}
+
+#define OFFSET(x) offsetof(AVIOInternal, x)
+static const AVOption io_priv_options[] = {
+ { "protocol_whitelist", "A comma-separated list of allowed protocols",
+ OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING },
+ { "protocol_blacklist", "A comma-separated list of forbidden protocols",
+ OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING },
+ { NULL },
+};
+
+static const AVClass io_priv_class = {
+ .class_name = "AVIOContext",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = io_priv_options,
+ .child_next = io_priv_child_next,
+ .child_class_next = io_priv_child_class_next,
+};
+
static void *ff_avio_child_next(void *obj, void *prev)
{
AVIOContext *s = obj;
- AVIOInternal *internal = s->opaque;
- return prev ? NULL : internal->h;
+ return prev ? NULL : s->opaque;
}
static const AVClass *ff_avio_child_class_next(const AVClass *prev)
{
- return prev ? NULL : &ffurl_context_class;
+ return prev ? NULL : &io_priv_class;
}
static const AVOption ff_avio_options[] = {
if (!internal)
goto fail;
+ internal->class = &io_priv_class;
internal->h = h;
+ av_opt_set_defaults(internal);
+
*s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE,
internal, io_read_packet, io_write_packet, io_seek);
if (!*s)
(*s)->av_class = &ff_avio_class;
return 0;
fail:
+ if (internal)
+ av_opt_free(internal);
av_freep(&internal);
av_freep(&buffer);
return AVERROR(ENOMEM);
{
AVIOInternal *internal;
const URLProtocol **protocols;
+ char *proto_whitelist = NULL, *proto_blacklist = NULL;
+ AVDictionaryEntry *e;
URLContext *h;
int err;
- protocols = ffurl_get_protocols(NULL, NULL);
+ if (options) {
+ e = av_dict_get(*options, "protocol_whitelist", NULL, 0);
+ if (e)
+ proto_whitelist = e->value;
+ e = av_dict_get(*options, "protocol_blacklist", NULL, 0);
+ if (e)
+ proto_blacklist = e->value;
+ }
+
+ protocols = ffurl_get_protocols(proto_whitelist, proto_blacklist);
if (!protocols)
return AVERROR(ENOMEM);
internal = (*s)->opaque;
internal->protocols = protocols;
+ if (options) {
+ err = av_opt_set_dict(internal, options);
+ if (err < 0) {
+ avio_closep(s);
+ return err;
+ }
+ }
+
return 0;
}
internal = s->opaque;
h = internal->h;
+ av_opt_free(internal);
+
av_freep(&internal->protocols);
av_freep(&s->opaque);
av_freep(&s->buffer);
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+#include "url.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
static int io_open_default(AVFormatContext *s, AVIOContext **pb,
const char *url, int flags, AVDictionary **options)
{
- return avio_open2(pb, url, flags, &s->interrupt_callback, options);
+ AVDictionary *opts_local = NULL;
+ int ret;
+
+ if (!options)
+ options = &opts_local;
+
+ if (s->protocol_whitelist) {
+ ret = av_dict_set(options, "protocol_whitelist", s->protocol_whitelist, 0);
+ if (ret < 0)
+ goto finish;
+ }
+ if (s->protocol_blacklist) {
+ ret = av_dict_set(options, "protocol_blacklist", s->protocol_blacklist, 0);
+ if (ret < 0)
+ goto finish;
+ }
+ ret = avio_open2(pb, url, flags, &s->interrupt_callback, options);
+finish:
+ av_dict_free(&opts_local);
+ return ret;
}
static void io_close_default(AVFormatContext *s, AVIOContext *pb)
{"auto", "enabled when required by target format", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_AUTO }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
{"make_non_negative", "shift timestamps so they are non negative", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
{"make_zero", "shift timestamps so they start at 0", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_ZERO }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
+{"protocol_blacklist", "A comma-separated list of blacklisted protocols used for opening files internally by lavf",
+ OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = "concat" }, .flags = E | D },
+{"protocol_whitelist", "A comma-separated list of whitelisted protocols used for opening files internally by lavf",
+ OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = E | D },
{NULL},
};
return AVERROR(EIO);
if (!rt->protocols) {
- rt->protocols = ffurl_get_protocols(NULL, NULL);
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!rt->protocols)
return AVERROR(ENOMEM);
}
return AVERROR(EIO);
if (!rt->protocols) {
- rt->protocols = ffurl_get_protocols(NULL, NULL);
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!rt->protocols)
return AVERROR(ENOMEM);
}
return AVERROR(EIO);
if (!rt->protocols) {
- rt->protocols = ffurl_get_protocols(NULL, NULL);
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!rt->protocols)
return AVERROR(ENOMEM);
}
enum RTSPMethod methodcode;
if (!rt->protocols) {
- rt->protocols = ffurl_get_protocols(NULL, NULL);
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!rt->protocols)
return AVERROR(ENOMEM);
}
av_strlcpy(host, "224.2.127.254", sizeof(host));
}
- sap->protocols = ffurl_get_protocols(NULL, NULL);
+ sap->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!sap->protocols) {
ret = AVERROR(ENOMEM);
goto fail;
freeaddrinfo(ai);
}
- sap->protocols = ffurl_get_protocols(NULL, NULL);
+ sap->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
if (!sap->protocols) {
ret = AVERROR(ENOMEM);
goto fail;
goto fail;
}
- c->protocols = ffurl_get_protocols(NULL, NULL);
+ c->protocols = ffurl_get_protocols(s->protocol_whitelist, s->protocol_blacklist);
if (!c->protocols) {
ret = AVERROR(ENOMEM);
goto fail;
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 57
-#define LIBAVFORMAT_VERSION_MINOR 3
+#define LIBAVFORMAT_VERSION_MINOR 4
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \