[FFmpeg-devel] [PATCH] avformat: Add multi protocol
Nicolas George
george at nsup.org
Mon Jul 18 17:08:59 EEST 2016
Le primidi 1er thermidor, an CCXXIV, Michael Niedermayer a écrit :
> TODO: docs, version bump,
> TODO: option passing support (as seperate commit/patch)
>
> Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> ---
> libavformat/Makefile | 1 +
> libavformat/multi.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++
> libavformat/protocols.c | 1 +
> 3 files changed, 136 insertions(+)
> create mode 100644 libavformat/multi.c
Is it similar to the tee muxer for protocols? If so, maybe use a similar
name.
>
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 6451c1c..b4dd6df 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -553,6 +553,7 @@ OBJS-$(CONFIG_ICECAST_PROTOCOL) += icecast.o
> OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
> OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
> OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
> +OBJS-$(CONFIG_MULTI_PROTOCOL) += multi.o
> OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
> OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
> OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o
> diff --git a/libavformat/multi.c b/libavformat/multi.c
> new file mode 100644
> index 0000000..f2e4243
> --- /dev/null
> +++ b/libavformat/multi.c
> @@ -0,0 +1,134 @@
> +/*
> + * Multi output protocol
> + * Copyright (c) 2016 Michael Niedermayer
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "libavutil/avstring.h"
> +#include "libavutil/opt.h"
> +#include "avformat.h"
> +#include "avio_internal.h"
> +
> +typedef struct ChildContext {
> + URLContext *url_context;
> +} ChildContext;
> +
> +typedef struct MultiContext {
> + const AVClass *class;
> + int child_count;
> + ChildContext *child;
> +} MultiContext;
> +
> +static const AVOption multi_options[] = {
> + { NULL }
> +};
> +
> +static const AVClass multi_class = {
> + .class_name = "multi",
> + .item_name = av_default_item_name,
> + .option = multi_options,
> + .version = LIBAVUTIL_VERSION_INT,
> +};
> +
> +static const char *const child_delim = "|";
> +
> +static int multi_write(URLContext *h, const unsigned char *buf, int size)
> +{
> + MultiContext *c = h->priv_data;
> + int i;
> + int main_ret = size;
> +
> + for (i=0; i<c->child_count; i++) {
> + int ret = ffurl_write(c->child[i].url_context, buf, size);
> + if (ret < 0)
> + main_ret = ret;
> + }
> + return main_ret;
> +}
> +
> +static int multi_close(URLContext *h)
> +{
> + MultiContext *c = h->priv_data;
> + int i;
> +
> + for (i=0; i<c->child_count; i++) {
> + ffurl_closep(&c->child[i].url_context);
Return value ignored.
> + }
> +
> + av_freep(&c->child);
> + c->child_count = 0;
> + return 0;
> +}
> +
> +static int multi_open(URLContext *h, const char *filename, int flags)
> +{
> + MultiContext *c = h->priv_data;
> + int ret, i;
> +
> + av_strstart(filename, "multi:", &filename);
> +
> + if (flags & AVIO_FLAG_READ)
> + return AVERROR(ENOSYS);
> +
> + while (*filename) {
> + char *child_name = av_get_token(&filename, child_delim);
> + void *tmp;
> + if (!child_name) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> +
> + tmp = av_realloc_array(c->child, c->child_count + 1, sizeof(*c->child));
> + if (!tmp) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + c->child = tmp;
> + memset(&c->child[c->child_count], 0, sizeof(&c->child[c->child_count]));
> +
> + ret = ffurl_open_whitelist(&c->child[c->child_count].url_context, child_name, flags,
> + &h->interrupt_callback, /*AVDictionary **options*/NULL,
> + h->protocol_whitelist, h->protocol_blacklist,
> + h);
> + av_free(child_name);
> + if (ret < 0)
> + goto fail;
> + c->child_count++;
> +
> + if (strspn(filename, child_delim))
> + filename++;
> + }
> +
> + h->is_streamed = 0;
> + for (i=0; i<c->child_count; i++) {
> + h->is_streamed |= c->child[i].url_context->is_streamed;
> + }
> +
> + return 0;
> +fail:
> + multi_close(h);
> + return ret;
> +}
> +const URLProtocol ff_multi_protocol = {
> + .name = "multi",
> + .url_open = multi_open,
> + .url_write = multi_write,
> + .priv_data_size = sizeof(MultiContext),
> + .priv_data_class = &multi_class,
> + .default_whitelist = "crypto,file,http,https,httpproxy,tcp,tls"
> +};
> \ No newline at end of file
> diff --git a/libavformat/protocols.c b/libavformat/protocols.c
> index 124010c..13d6621 100644
> --- a/libavformat/protocols.c
> +++ b/libavformat/protocols.c
> @@ -42,6 +42,7 @@ extern const URLProtocol ff_icecast_protocol;
> extern const URLProtocol ff_mmsh_protocol;
> extern const URLProtocol ff_mmst_protocol;
> extern const URLProtocol ff_md5_protocol;
> +extern const URLProtocol ff_multi_protocol;
> extern const URLProtocol ff_pipe_protocol;
> extern const URLProtocol ff_rtmp_protocol;
> extern const URLProtocol ff_rtmpe_protocol;
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160718/af34040d/attachment.sig>
More information about the ffmpeg-devel
mailing list