diff --git a/doc/muxers.texi b/doc/muxers.texi index 5f98bc5bdc..05bf483ba5 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1215,6 +1215,11 @@ overwritten with new images. Default value is 0. @item strftime If set to 1, expand the filename with date and time information from @code{strftime()}. Default value is 0. + +@item protocol_opts @var{options_list} +Set protocol options as a :-separated list of key=value parameters. Values +containing the @code{:} special character must be escaped. + @end table @subsection Examples @@ -1257,6 +1262,12 @@ You can set the file name with current frame's PTS: ffmpeg -f v4l2 -r 1 -i /dev/video0 -copyts -f image2 -frame_pts true %d.jpg" @end example +A more complex example is to publish contents of your desktop directly to a +WebDAV server every second: +@example +ffmpeg -f x11grab -framerate 1 -i :0.0 -q:v 6 -update 1 -protocol_opts method=PUT http://example.com/desktop.jpg +@end example + @section matroska Matroska container muxer. diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 5ee99890ce..a2786ec6f8 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -23,6 +23,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/dict.h" #include "libavutil/log.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -44,6 +45,7 @@ typedef struct VideoMuxData { int frame_pts; const char *muxer; int use_rename; + AVDictionary *protocol_opts; } VideoMuxData; static int write_header(AVFormatContext *s) @@ -132,6 +134,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(par->format); int ret, i; int nb_renames = 0; + AVDictionary *options = NULL; if (img->update) { av_strlcpy(filename, img->path, sizeof(filename)); @@ -160,13 +163,19 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); } for (i = 0; i < 4; i++) { + av_dict_copy(&options, img->protocol_opts, 0); snprintf(img->tmp[i], sizeof(img->tmp[i]), "%s.tmp", filename); av_strlcpy(img->target[i], filename, sizeof(img->target[i])); - if (s->io_open(s, &pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, NULL) < 0) { + if (s->io_open(s, &pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, &options) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", img->use_rename ? img->tmp[i] : filename); ret = AVERROR(EIO); goto fail; } + if (options) { + av_log(s, AV_LOG_ERROR, "Could not recognize some protocol options\n"); + ret = AVERROR(EINVAL); + goto fail; + } if (!img->split_planes || i+1 >= desc->nb_components) break; @@ -210,6 +219,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return 0; fail: + av_dict_free(&options); for (i = 0; i < FF_ARRAY_ELEMS(pb); i++) if (pb[i]) ff_format_io_close(s, &pb[i]); @@ -235,6 +245,7 @@ static const AVOption muxoptions[] = { { "strftime", "use strftime for filename", OFFSET(use_strftime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC }, { "frame_pts", "use current frame pts for filename", OFFSET(frame_pts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC }, { "atomic_writing", "write files atomically (using temporary files and renames)", OFFSET(use_rename), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC }, + { "protocol_opts", "specify protocol options for the opened files", OFFSET(protocol_opts), AV_OPT_TYPE_DICT, {0}, 0, 0, ENC }, { NULL }, }; diff --git a/libavformat/version.h b/libavformat/version.h index 0a79868663..8be0c41411 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 #define LIBAVFORMAT_VERSION_MINOR 35 -#define LIBAVFORMAT_VERSION_MICRO 103 +#define LIBAVFORMAT_VERSION_MICRO 104 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \