From 9985710a5a927d52c345c4bdcc88f5c014ee2fe7 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Fri, 29 Nov 2013 08:41:24 +0100 Subject: [PATCH] ffserver: add stream Metadata option Also deprecate Author, Comment, Copyright, and Title options, and update docs to use the new Metadata option. --- doc/ffserver.conf | 10 ++++---- doc/ffserver.texi | 16 ++++++++----- ffserver.c | 60 ++++++++++++++++++++++++++++------------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/doc/ffserver.conf b/doc/ffserver.conf index 0f5922cc3e..094c093af2 100644 --- a/doc/ffserver.conf +++ b/doc/ffserver.conf @@ -235,7 +235,7 @@ StartSendOnKey # #Feed feed1.ffm -#Title "Stream title" +#Metadata title "Stream title" #AudioBitRate 64 #AudioChannels 2 #AudioSampleRate 44100 @@ -280,10 +280,10 @@ StartSendOnKey # #File "/usr/local/httpd/htdocs/test.asf" #NoAudio -#Author "Me" -#Copyright "Super MegaCorp" -#Title "Test stream from disk" -#Comment "Test comment" +#Metadata author "Me" +#Metadata copyright "Super MegaCorp" +#Metadata title "Test stream from disk" +#Metadata comment "Test comment" # diff --git a/doc/ffserver.texi b/doc/ffserver.texi index 3f7a98dbe5..ed538c1af0 100644 --- a/doc/ffserver.texi +++ b/doc/ffserver.texi @@ -550,7 +550,11 @@ for regular streams. @item Comment @var{value} @item Copyright @var{value} @item Title @var{value} -Set metadata corresponding to the option. +Set metadata corresponding to the option. All these options are +deprecated in favor of @option{Metadata}. + +@item Metadata @var{key} @var{value} +Set metadata value on the output stream. @item NoAudio @item NoVideo @@ -757,7 +761,7 @@ Ogg Vorbis audio @example Feed feed1.ffm -Title "Stream title" +Metadata title "Stream title" AudioBitRate 64 AudioChannels 2 AudioSampleRate 44100 @@ -804,10 +808,10 @@ NoAudio File "/usr/local/httpd/htdocs/test.asf" NoAudio -Author "Me" -Copyright "Super MegaCorp" -Title "Test stream from disk" -Comment "Test comment" +Metadata author "Me" +Metadata copyright "Super MegaCorp" +Metadata title "Test stream from disk" +Metadata comment "Test comment" @end example @end itemize diff --git a/ffserver.c b/ffserver.c index f06df2715a..11a4a160dc 100644 --- a/ffserver.c +++ b/ffserver.c @@ -216,6 +216,7 @@ typedef struct FFStream { struct FFStream *feed; /* feed we are using (can be null if coming from file) */ AVDictionary *in_opts; /* input parameters */ + AVDictionary *metadata; /* metadata to set on the stream */ AVInputFormat *ifmt; /* if non NULL, force input format */ AVOutputFormat *fmt; IPAddressACL *acl; @@ -228,10 +229,6 @@ typedef struct FFStream { int feed_streams[MAX_STREAMS]; /* index of streams in the feed */ char feed_filename[1024]; /* file name of the feed storage, or input file name for a stream */ - char author[512]; - char title[512]; - char copyright[512]; - char comment[512]; pid_t pid; /* Of ffmpeg process */ time_t pid_start; /* Of ffmpeg process */ char **child_argv; @@ -2279,11 +2276,7 @@ static int http_prepare_data(HTTPContext *c) switch(c->state) { case HTTPSTATE_SEND_DATA_HEADER: memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx)); - av_dict_set(&c->fmt_ctx.metadata, "author" , c->stream->author , 0); - av_dict_set(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0); - av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0); - av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0); - + av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0); c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams); for(i=0;istream->nb_streams;i++) { @@ -2993,6 +2986,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, AVFormatContext *avc; AVStream *avs = NULL; AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); + AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0); int i; avc = avformat_alloc_context(); @@ -3001,7 +2995,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, } avc->oformat = rtp_format; av_dict_set(&avc->metadata, "title", - stream->title[0] ? stream->title : "No Title", 0); + entry ? entry->value : "No Title", 0); avc->nb_streams = stream->nb_streams; if (stream->is_multicast) { snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d", @@ -4067,7 +4061,7 @@ static int parse_ffconfig(const char *filename) FILE *f; char line[1024]; char cmd[64]; - char arg[1024]; + char arg[1024], arg2[1024]; const char *p; int val, errors, line_num; FFStream **last_stream, *stream, *redirect; @@ -4367,18 +4361,37 @@ static int parse_ffconfig(const char *filename) } else { ERROR("FaviconURL only permitted for status streams\n"); } - } else if (!av_strcasecmp(cmd, "Author")) { - if (stream) - get_arg(stream->author, sizeof(stream->author), &p); - } else if (!av_strcasecmp(cmd, "Comment")) { - if (stream) - get_arg(stream->comment, sizeof(stream->comment), &p); - } else if (!av_strcasecmp(cmd, "Copyright")) { - if (stream) - get_arg(stream->copyright, sizeof(stream->copyright), &p); - } else if (!av_strcasecmp(cmd, "Title")) { - if (stream) - get_arg(stream->title, sizeof(stream->title), &p); + } else if (!av_strcasecmp(cmd, "Author") || + !av_strcasecmp(cmd, "Comment") || + !av_strcasecmp(cmd, "Copyright") || + !av_strcasecmp(cmd, "Title")) { + get_arg(arg, sizeof(arg), &p); + + if (stream) { + char key[32]; + int i, ret; + + for (i = 0; i < strlen(cmd); i++) + key[i] = av_tolower(cmd[i]); + key[i] = 0; + av_log(NULL, AV_LOG_WARNING, + "'%s' option in configuration file is deprecated, " + "use 'Metadata %s VALUE' instead\n", cmd, key); + if ((ret = av_dict_set(&stream->metadata, key, arg, 0)) < 0) { + ERROR("Could not set metadata '%s' to value '%s': %s\n", + key, arg, av_err2str(ret)); + } + } + } else if (!av_strcasecmp(cmd, "Metadata")) { + get_arg(arg, sizeof(arg), &p); + get_arg(arg2, sizeof(arg2), &p); + if (stream) { + int ret; + if ((ret = av_dict_set(&stream->metadata, arg, arg2, 0)) < 0) { + ERROR("Could not set metadata '%s' to value '%s': %s\n", + arg, arg2, av_err2str(ret)); + } + } } else if (!av_strcasecmp(cmd, "Preroll")) { get_arg(arg, sizeof(arg), &p); if (stream) @@ -4501,7 +4514,6 @@ static int parse_ffconfig(const char *filename) } } else if (!av_strcasecmp(cmd, "AVOptionVideo") || !av_strcasecmp(cmd, "AVOptionAudio")) { - char arg2[1024]; AVCodecContext *avctx; int type; get_arg(arg, sizeof(arg), &p);