[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